Cómo podemos aplicar CSS a los slots de los Custom Elements. Aplicable a Web Components en general y por supuesto a la librería Lit. Entender el pseudo-elemento ::slotted().
Como hemos dicho ya anteriormente en el Manual de Lit, el contenido que contiene la etiqueta host (la etiqueta del componente) se puede usar dentro del componente vía slot. De hecho, en un artículo anterior ya estuvimos aprendiendo mucho acerca del trabajo con slots.
En este artículo vamos a abordar la aplicación de estilos a los elementos hijo, es decir cómo podemos modificar el aspecto de aquellos elementos que se encuentran dentro de la etiqueta del componente. Para ello aplicaremos CSS de varias formas.
Los estilos CSS a los elementos hijos se colocan desde fuera
Como primera regla, debemos saber que el CSS que aplica al contenido de la etiqueta padre no es generalmente una responsabilidad de la implementación de ese componente, sino de quien está usando el componente.
Para que nos entendamos, veamos este código:
<dw-card>
<p>
Esto es un contenido que viene vía slot
</p>
</dw-card>
El párrafo que hay dentro del dw-card
no pertenece directamente al componente, sino que es un contenido de fuera del componente. Por tanto, si por ejemplo el componente está colocado en el cuerpo de un documento HTML, tendrás que aplicar estilos mediante el CSS global de la página.
Solo para que sirva de referencia, dado que un código vale más que mil palabras, puedes ver la siguiente página web:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Documento de estilos en slots</title>
<style>
p {
color: red;
}
dw-card {
font-size: 0.8em;
}
</style>
</head>
<body>
<h1>Poner estilos en slots</h1>
<dw-card>
<p>
Esto es un contenido que viene <b>vía slot</b>
</p>
<ul>
<li>Elemento de lista</li>
<li>Otro elemento</li>
</ul>
<div>
<p>otro párrafo que no es hijo directo</p>
</div>
</dw-card>
<script src="index.js" type="module"></script>
</body>
</html>
Se ha definido un estilo global sobre la etiqueta P, por lo que afecta a todos los párrafos y por tanto también al párrafo que está dentro del dw-card.
Por supuesto, es posible aplicar estilo al contenido del elemento dw-card
con el selector de etiqueta dw-card
. Ni necesitamos decir que podríamos poner también una clase particular a los párrafos o al propio componente de tarjeta para aplicarles estilos de manera específica a ellos.
Este estilo afectará al componente dw-card
en sí, tanto a él mismo como a su contenido, ya que el tamaño de la fuente sí que penetra dentro del componente, a no ser que en el CSS del componente se haya definido un estilo que lo sobreescriba.
Cómo aplicar estilos desde dentro del componente con ::slotted()
Ahora bien, en ocasiones es posible que necesitemos definir unos estilos a los elementos hijos que usamos como slots y CSS nos ofrece algunas soluciones que podemos aplicar cuando usamos el estándar Web Components.
Qué es ::slotted()
En CSS existe un pseudo-elemento llamado ::slotted()
que sirve para seleccionar elementos que se han colocado dentro de un slot en un template HTML. Es una vía adecuada para usar en nuestros componentes aunque tiene algunas limitaciones:
- Ese pseudo-elemento solamente afectará a los slots que se han volcado dentro del shadow DOM de los componentes.
-
::slotted() no podrá seleccionar nodos de texto. Es decir, si usamos texto sin etiquetas dentro del componente (como en
<dw-button>Púlsame</dw-button>
) no servirá de nada. - Con
::slotted()
podremos llegar a seleccionar etiquetas hijas directas del componente, pero no otros descendientes más profundos.
Algunos ejemplos de uso de ::slotted()
podrían ser los siguientes. Vamos a pensar que estuvieran en el componente dw-card y tendrían efectos que vamos a comentar.
::slotted(*) {
color: #35e;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
Esto afectará a todas las etiquetas hijas directas del componente. Atendiendo al HTML que hemos puesto antes, afectaría al párrafo y la etiqueta <ul>
.
Pero fíjate que en HTML habíamos dicho que los párrafos tienen un color rojo. Ese selector de párrafo ganaría al selector ::slotted()
por lo que el párrafo al final tendría color rojo.
::slotted(p) {
text-decoration: underline;
}
Esto afecta a los párrafos que están en el slot y son hijos directos. Por tanto solamente afectaría al primer <p>
, el segundo que está dentro de un <div>
no se verá afectado..
::slotted(ul) {
text-transform: uppercase;
}
Esto afectará a la lista desordenada completa.
::slotted(li) {
font-weight: bold;
}
Esto no afectaría a nada, ya que los <li>
no son hijos directos del componente.
Estos estilos realmente solo los hemos aplicado por probar los efectos de ::slotted()
, en verdad no son muy prácticos para nuestro componente de tarjeta. Los puedes ver aplicados en este commit del repositorio de ejemplos del manual.
Conclusión sobre CSS con ::slotted
Hemos conocido el pseudo-elemento de CSS ::slotted()
que nos permite aplicar algo de estilo a los hijos del componente. Es un recurso que conviene conocer y tener a mano para cuando puedas llegar a necesitar. No obstante, dicho sea de paso, no lo he utilizado demasiadas veces en la práctica, incluso en ocasiones debo reconocer que me he sentido un poco frustrado por sus limitaciones a la hora de aplicar estilos, principalmente porque solamente afecta a los hijos directos.
Por eso es importante haber mencionado que generalmente se acaba aplicando estilos a los slots, mediante el CSS global de la página, o el CSS del componente padre.
En el siguiente artículo veremos cómo acceder a los hijos del componente por medio de programación Javascript. Y además en el ejemplo que desarrollaremos verás una aplicación de ::slotted()
adicional para seguir practicando.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...