- Notifications
You must be signed in to change notification settings - Fork230
Shadow DOM styling#426
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
0936bd5
a46c986
82e9d90
e376857
b83a67a
8e2c408
39f0fbf
40597d2
e86a421
7d4fb40
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,21 @@ | ||
#EstiloShadow DOM | ||
Shadow DOMpuede incluir las etiquetas`<style>`y `<link rel="stylesheet" href="…">`. En este último caso, las hojas de estilo se almacenan en la cachéHTTP, por lo que no se vuelven a descargar para varios de los componentes que usan la misma plantilla. | ||
Como regla general, los estilos locales solo funcionan dentro delshadow tree,y los estilos de documentos funcionan fuera de él. Pero hay pocas excepciones. | ||
## :host | ||
El selector`:host`permite seleccionar elshadow host (el elemento que contiene el shadow tree). | ||
Por ejemplo, estamos creando un elemento`<custom-dialog>`que debería estar centrado. Para eso necesitamos diseñar el elemento`<custom-dialog>`. | ||
Eso es exactamente lo que`:host`hace: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<template id="tmpl"> | ||
<style> | ||
/*el estilo se aplicará desde el interior al elemento de diálogo personalizado */ | ||
:host { | ||
position: fixed; | ||
left: 50%; | ||
@@ -42,32 +42,32 @@ customElements.define('custom-dialog', class extends HTMLElement { | ||
</custom-dialog> | ||
``` | ||
##Cascada | ||
El shadow host (`<custom-dialog>`en sí) reside en el light DOM,por lo que se ve afectado por las reglas deCSSdel documento. | ||
Si hay una propiedad con estilo tanto en el`:host`localmente, y en el documento, entonces el estilo del documento tiene prioridad. | ||
Por ejemplo, si en el documento tenemos: | ||
```html | ||
<style> | ||
custom-dialog { | ||
padding: 0; | ||
} | ||
</style> | ||
``` | ||
...Entonces el `<custom-dialog>`estaría sin padding. | ||
Es muy conveniente, ya que podemos configurar estilos de componentes "predeterminados" en su regla`:host`, y luego sobreescribirlos fácilmente en el documento. | ||
La excepción es cuando una propiedadlocalestá etiquetada como `!important`. Para tales propiedades, los estilos locales tienen prioridad. | ||
## :host(selector) | ||
Igual que `:host`,pero se aplica solo si elshadow hostcoincide con el `selector`. | ||
Por ejemplo, nos gustaría centrar el`<custom-dialog>`solo si tiene el atributo`centered`: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<template id="tmpl"> | ||
@@ -101,40 +101,40 @@ customElements.define('custom-dialog', class extends HTMLElement { | ||
<custom-dialog centered> | ||
¡Centrado! | ||
</custom-dialog> | ||
<custom-dialog> | ||
No centrado. | ||
</custom-dialog> | ||
``` | ||
Ahora los estilos de centrado adicionales solo se aplican al primer diálogo: `<custom-dialog centered>`. | ||
## :host-context(selector) | ||
Igual que `:host`,pero se aplica solo si elshadow hosto cualquiera de sus ancestros en el documento exterior coinciden con el `selector`. | ||
p. ej. `:host-context(.dark-theme)`coincide solo si hay una clase`dark-theme`en`<custom-dialog>`en cualquier lugar por encima de el: | ||
MoisesTR marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
```html | ||
<body class="dark-theme"> | ||
<!-- | ||
:host-context(.dark-theme)se aplica a loscustom-dialogsdentro de .dark-theme | ||
--> | ||
<custom-dialog>...</custom-dialog> | ||
</body> | ||
``` | ||
Para resumir, podemos usar`:host`-familia de selectores para aplicar estilos al elemento principal del componente, según el contexto. Estos estilos (a menos que sea`!important`)pueden ser sobreescritos por el documento. | ||
##Estilo de contenido eslotado(cuando un elemento ha sido insertado en un slot, se dice que fue eslotado por su término en inglés slotted) | ||
Ahora consideremos la situación con los slots. | ||
Los elementos eslotados vienen dellight DOM,por lo que usan estilos del documento. Los estilos locales no afectan al contenido de los elementos eslotados. | ||
En el siguiente ejemplo, el elemento eslotado`<span>`está enbold,según el estilo del documento, pero no toma el `background`del estilo local: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<style> | ||
*!* | ||
@@ -163,11 +163,11 @@ customElements.define('user-card', class extends HTMLElement { | ||
</script> | ||
``` | ||
El resultado es bold,pero no red. | ||
Si queremos aplicar estilos a elementos eslotados en nuestro componente, hay dos opciones. | ||
Primero, podemos aplicarle el estilo al elemento`<slot>`en sí mismo y confiar en la herencia CSS: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<user-card> | ||
@@ -191,14 +191,14 @@ customElements.define('user-card', class extends HTMLElement { | ||
</script> | ||
``` | ||
Aquí `<p>John Smith</p>`se vuelvebold,porque la herencia CSS está en efecto entre el`<slot>`y su contenido. Pero en el propioCSSno todas las propiedades se heredan. | ||
Otra opción es usar la pseudoclase`::slotted(selector)`. Coincide con elementos en función de 2 condiciones. | ||
1.Eso es un elemento eslotado, que viene dellight DOM.El nombre del slot no importa. Cualquier elemento eslotado, pero solo el elemento en si, no sus hijos. | ||
2.El elemento coincide con el `selector`. | ||
En nuestro ejemplo, `::slotted(div)`selecciona exactamente `<div slot="username">`,pero no sus hijos: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<user-card> | ||
@@ -224,54 +224,54 @@ customElements.define('user-card', class extends HTMLElement { | ||
</script> | ||
``` | ||
Tenga en cuenta, que el selector`::slotted`no puede descender más en elslot.Estos selectores no son válidos: | ||
MoisesTR marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
```css | ||
::slotted(div span) { | ||
/*nuestro slotted <div>no coincide con esto */ | ||
} | ||
::slotted(div) p { | ||
/*No puede entrar en light DOM */ | ||
} | ||
``` | ||
También, `::slotted`solo se puede utilizar en CSS.No podemos usarlo en `querySelector`. | ||
MoisesTR marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
## CSS hookscon propiedades personalizadas | ||
¿Cómo diseñamos los elementos internos de un componente del documento principal? | ||
Selectores como `:host`aplican reglas al elemento`<custom-dialog>`o`<user-card>`,¿pero cómo aplicar estilos a elementos delshadow DOMdentro de ellos? | ||
No hay ningúnselectorque pueda afectar directamente a los estilos del shadow DOM del documento. Pero así como exponemos métodos para interactuar con nuestro componente, podemos exponer variables CSS(propiedades CSSpersonalizadas) para darle estilo. | ||
**Existen propiedadesCSSpersonalizadas en todos los niveles, tanto en lightcomo shadow.** | ||
Por ejemplo, en elshadow DOMpodemos usar la variable CSS`--user-card-field-color`para dar estilo a los campos, y en el documento exterior establecer su valor: | ||
```html | ||
<style> | ||
.field { | ||
color: var(--user-card-field-color, black); | ||
/*si --user-card-field-colorno esta definido, usarcolor negro */ | ||
} | ||
</style> | ||
<div class="field">Name: <slot name="username"></slot></div> | ||
<div class="field">Birthday: <slot name="birthday"></slot></div> | ||
``` | ||
Entonces, podemos declarar esta propiedad en el documento exterior para `<user-card>`: | ||
```css | ||
user-card { | ||
--user-card-field-color: green; | ||
} | ||
``` | ||
Las propiedades personalizadas CSS atraviesan elshadow DOM,son visibles en todas partes, por lo que la regla interna`.field`hará uso de ella. | ||
Aquí está el ejemplo completo: | ||
```html run autorun="no-epub" untrusted height=80 | ||
<style> | ||
@@ -311,24 +311,24 @@ customElements.define('user-card', class extends HTMLElement { | ||
##Resumen | ||
Shadow DOMpuede incluir estilos, como`<style>`o `<link rel="stylesheet">`. | ||
Los estilos locales pueden afectar: | ||
- shadow tree, | ||
- shadow hostcon `:host`-familia de pseudoclases, | ||
-elementos eslotados (provenientes de light DOM), `::slotted(selector)`permite seleccionar elementos eslotados, pero no a sus hijos. | ||
Los estilos de documentos pueden afectar: | ||
- shadow host (ya que vive en el documento exterior) | ||
MoisesTR marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
-elementos eslotados y su contenido (ya que eso también está en el documento exterior) | ||
Cuando las propiedadesCSSentran en conflicto, normalmente los estilos del documento tienen prioridad, a menos que la propiedad esté etiquetada como`!important`.Entonces, los estilos locales tienen prioridad. | ||
Las propiedades CSS personalizadas atraviesan elshadow DOM.Se utilizan como"hooks"para aplicar estilos al componente: | ||
MoisesTR marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
1.El componente utiliza una propiedad CSSpersonalizada para aplicar estilos a elementos clave, como `var(--component-name-title, <default value>)`. | ||
2.El autor del componente publica estas propiedades para los desarrolladores, son tan importantes como otros métodos de componentes públicos. | ||
3.Cuando un desarrollador desea aplicar un estilo a un título, asigna la propiedad CSS`--component-name-title`para elshadow hosto superior. | ||
4.¡Beneficio! |