La teoría
Una de las características nuevas que trajo Blazor en con NET 6.0 es la posibilidad de trabajar con el CSS isolated. Esto es una característica que nos permite hacer que cada componente tenga su propio CSS y así "independizr" un poco cada componente. Pero esto enfrenta otro reto. ¿Qué CSS lleva prferencia? ¿El que se carga con el HTML y está muy bien atribuido? o por el contrario ¿gana siempre el CSS del componente isolated?
Bueno la respues a esto es fácil. Siempre gana el del componente con el CSS isolated, ya que trabaja casi, casi, como si fuera CSS in line. Lo que han hecho los programadores es asignar una especia de ID al componente, y este ID se pone en el CSS, por lo que si un componente tiene una clase, que está en el CSS público, y además tiene la misma clase isolated, ésta lleva prefencia gracias al ID. La cosa queda un pomo asíÑ
< componente class="mi-clase" / >
CSS Principal
.mi-clase {font-size: 12px}
CSS isolated
.mi-clase {font-size: 24px}
El CSS isolated se convierte en un archivo CSS que se importa desde el CSS principal de la aplicación, mejor dicho, desde el CSS de la aplicación que se genera automáticamente cuando compilamos la aplicación. Ese fichero se va a ver algo como así
abc123 .mi-clase {font-size: 24px}
Luego cuando el componente es invocado se ha rendetizado como
< div class="mi-clase" abc123>Mi componente< /div >
En el CSS de la aplicación auto generado incluirá todos los archivos de los componente isolated como
/* /[carpeta]/[nombre_componente].rz.scp.css */
.mi-clase[abc123] {
font-size: 24px;
}
Ahora algunas aclaraciones
Pero esto ahora lleva un problema añadido. Ti tenemos algún JAVASCRIPT que agregue contenido dinámicamente a nuestro componente, éste no va a tener ese ID que el sistema le ha otorgado a la hora de compilación, y por consiguiente, no tomara en cuenta la sobreescritura de la case y los nuevos elementos con la clase mi-clase no van a tener un tamaño de letra de 24px.
Además si nuestro componente tiene a su vez dentro otro componente, éste segundo tendrá un ID diferente, por lo que sus elementos tampoco se van a ver afectados por la sobreescritura del CSS isolated, y cada elemento que tenga la clase mi-clase van a tener un tamaño de letra de 12px, ya que en el CSS general lo hemos así lo hemos definido. Y aquí es donde la cosa se complica y el porqué de este blog.
Soluciones sencillas para problemas complicados
En primer lugar aclarar que en un principio Microsoft, o la comunidad que desarrolló este mecanismo de isoleted, nos da un elemento para poner en el archivo CSS. Este elemento, o instrucción, no es un tag válido para CSS, pero si lo va a reconocer el compilador. Este tág es ::deep, sí con lo dos puntos verticas dos veces, como si de un atributo de CSS se tratara, de hecho imagino que así lo tratan, como un atributo de CSS, o como se llame, el CSS no es mi fuerte precisamente, pero como siempre en mis blogs doy soluciones explicadas desde la expetiencia, sin ser un experto, y por eso siempre estoy abierto a que me corrijan y me ayuden a mejorar.
Este atributo ::deep va a ser reemplazado en compilación por el ID generado para el componente. Ahora bien, ¿cómo trabaja este atributo ::deep? Si queremos que nuestro CSS se arrastre hacia dentro de mi componente, y afecte a nuestro componente hijo deberemos de ponerlo justo detrás del nombre de la clase.
.mi-clase ::deep .clase-hija {opacity: 0.5}
Ya puede ser una clase o un elemento HTML.
Pero si donde estamos es en el componente hijo y necesitamos sobreescribir una clase del padre pondremos el ::deep antes del nombre de la case
::deep mi-clase {display: inline-table}
Poniendo un ejemplo sencillo en HTML tendríamos renderizado algo como esto
< div class="mi-clase">
Esto tiene un tamaño de letra de 12px
< div class="mi-clase" abc123>
Esto tiene un tamaño de letra de 24px
< div class"clase-hija" abc789>
Esto tiene una opacidad de 0.5, se ve la mitad que el de arriba. Y ademas el texto esta centrado por su CSS isolated en el componente hijo.
< />
< />
< />
Si estuviéramos en los arhivos CSS tendríamos algo como esto
app.css
.mi-clase {font-size: 12px}
MiAplicacion.css
/* /[carpeta]/[nombre_componente1].rz.scp.css */
.mi-clase[abc123] {font-size:24px}
.mi-clase[abc123] .clase-hija {opacity:0.5}
/* /[carpeta]/[nombre_componente2].rz.scp.css */
.clase-hija[abc789] {text-align: center}
Puedes ver un ejemplo en este GitHub