Nombres de CSS definidos por el autor y shadow DOM: En especificación y en la práctica

Se supone que los nombres de CSS definidos por la autoría y el shadow DOM deben funcionar juntos. Sin embargo, los navegadores no coinciden con la especificación y, a veces, con cada y todos los nombres de CSS son incoherentes de una forma ligeramente diferente.

En este artículo, se documenta el estado actual de cómo se comportan los nombres de CSS definidos por el autor a través de los alcances de las sombras, con la esperanza de que pueda servir como guía para mejorar la interoperabilidad en un futuro cercano.

¿Qué son los nombres de CSS definidos por el autor?

Los nombres de CSS definidos por el autor son un mecanismo de sintaxis de CSS relativamente antiguo, originalmente. Se introdujo para la regla @keyframes, que define un <keyframe-name> como una identidad personalizada o una cadena. El propósito de este concepto es declarar algo en una parte de una hoja de estilo y hacer referencia a él en otra parte.

/* "fade-in" is a CSS name, representing a set of keyframes */
@keyframes fade-in {
  from { opacity: 0 };
  to { opacity: 1 }
}

.card {
  /* "fade-in" is a reference to the above keyframes */
  animation-name: fade-in;
}

Otras funciones de CSS que usan nombres CSS son las fuentes, las declaraciones de propiedad, consultas de contenedores y, más recientemente, las transiciones de vistas, el posicionamiento de los anclajes y animaciones basadas en desplazamientos. La siguiente tabla no completa incluye nombres que Chrome verifica el estado.

Función Declaración de nombre Referencia de nombre
Fotogramas clave @keyframes animation-name
Fuentes @font-face { }
@font-palette-values
font-family
font-palette
Declaraciones de propiedad @property Cualquier propiedad personalizada
Ver transición view-transition-name
view-transition-class
::view-transition-group()
Posicionamiento del anuncio fijo anchor-name position-anchor
Animación basada en desplazamientos animation-timeline view-timeline-name
scroll-timeline-name
Estilo del contador @counter-style
Counter-reset
counter-set
counter-increment
list-style
Consultas de contenedores container-name @container
Variable de CSS --something var(--something)
Página @page

Como puedes ver en la tabla, los nombres de CSS suelen tener sus respectivos valores referencia. Por ejemplo, animation-name es una referencia a @keyframes. de la fuente de datos. Los nombres de CSS son diferentes de los nombres definidos en el DOM, como los atributos y nombres de etiquetas, ya que se declaran y, luego, se hace referencia a ellos en el contexto de las hojas de estilo.

Cómo se relacionan los nombres con el shadow DOM

Si bien los nombres de CSS se crean para crear relaciones entre las diferentes partes de una documento o la hoja de estilo, Shadow DOM es para hacer lo contrario. Encapsula relaciones para que no se filtren en componentes web que deberían tener su propio espacio de nombres.

Al juntar los nombres de CSS y el shadow DOM, la experiencia de composición los componentes web deben parecer lo suficientemente expresivos como para ser flexibles, pero limitados lo suficientemente estables.

Esto es bueno en teoría. En la práctica, los navegadores no coinciden en la forma en que CSS interoperan con el shadow DOM; ambos entre funciones de la misma navegador, en todos los navegadores y entre las funciones y la especificación.

Cómo deben funcionar en conjunto los nombres y el shadow DOM

Para entender el problema, vale la pena entender cómo estas partes del CSS debería funcionar juntos en teoría.

La regla general

La regla general de cómo se comportan los nombres de CSS en los árboles sombreados se define en el Especificación de nivel 1 de permisos de CSS. En resumen: un nombre de CSS es global dentro del alcance en el que está definido. se puede acceder a él desde árboles sombreados descendientes, pero no desde hermanos o árboles de sombra principales. Ten en cuenta que esto no se parece a los nombres en la plataforma web, como IDs de elementos, que se encapsulan dentro del mismo alcance del árbol.

Excepción a la regla: @property

A diferencia de otros nombres de CSS, las propiedades de CSS no están encapsuladas por shadow DOM. Más bien, son el medio común para pasar parámetros a través de diferentes sombras árboles. Esto hace que el Descriptor @property especial: se supone que debe comportarse como una declaración de tipo document-global que define cómo actúa una propiedad con nombre en particular. Porque las propiedades deben coincidir en los árboles paralelos, la falta de coincidencia entre las declaraciones de propiedad generaría resultados inesperados resultados, por lo que se especifican las declaraciones de @property para que se acoplen y se resuelvan según el orden de los documentos.

Cómo debería funcionar la regla con ::part

Partes de sombras exponer un elemento dentro de un shadow tree a su árbol superior. Al hacerlo, la El árbol superior puede acceder a ese elemento y diseñar el diseño con ::part .

Como ::part permite que dos alcances de árbol diseñen el diseño del mismo elemento, lo siguiente se especifica el orden de cascada:

  1. Primero, verifica el estilo dentro del contexto de la sombra. Esta es la configuración “predeterminada” estilo de la pieza.
  2. Luego, aplica el estilo externo como se define en ::part. Este es el "personalizado" estilo de la pieza.
  3. Luego, aplica cualquier estilo interno que se defina junto con !important. Esto permite que un elemento personalizado declare que cierta propiedad de un determinado no se puede personalizar por ::part.

Esto significa que no se puede hacer referencia a nombres dentro del shadow DOM desde un ::part, ya que ::part es un estilo con alcance de host en lugar de un alcance de sombra estilo. Por ejemplo:

// inside the shadow DOM:
@keyframes fade-in {
  from { opacity: 0}
}

// This shouldn't work!
// The host style shouldn't know the name "fade-in"
::part(slider) {
  animation-name: fade-in;  
}

Cómo debe funcionar la regla con los estilos intercalados

A diferencia de ::part, los estilos intercalados con el atributo style o aquellos que configuran el estilo de manera programática con secuencias de comandos, se definen el alcance. Esto se debe a que, para aplicar un estilo a un elemento al que necesitas acceder, el controlador del elemento y, por lo tanto, a la raíz de las shadow.

Cómo los nombres de CSS y el shadow DOM funcionan juntos en la realidad

Aunque las reglas anteriores están bien definidas y coherentes, implementaciones no siempre reflejan eso. En la práctica, @property funciona de manera diferente a la especificación de manera coherente. en distintos navegadores y la mayoría de las funciones tienen errores abiertos (algunas son que todavía no se lanzaron, así que hay tiempo de corregirlos).

Para probar y demostrar cómo funcionan estas funciones en la práctica, creamos la siguiente página: https://css-names-in-the-shadow.glitch.me/. Esta página tiene varios iframes, cada uno enfocado en una de las funciones y probando seis diferentes:

  • Referencia externa a un nombre externo: No incluye shadow DOM; esto debería el trabajo.
  • Referencia externa a un nombre interno: no debería funcionar, como lo haría. significa que se filtró el nombre definido en el contexto de la sombra.
  • Referencia interna al nombre externo: Debería funcionar, como nombres con alcance de árbol. y las shadow roots heredan.
  • Referencia interna al nombre interno: debería funcionar, ya que tanto el nombre del referencia están dentro del mismo alcance.
  • Referencia de ::part al nombre externo: esto debería funcionar, ya que ::part y el nombre se declaran en el mismo alcance.
  • Referencia de ::part al nombre interno: esto no debería funcionar, ya que el alcance externo. no debería obtener conocimiento sobre los nombres declarados dentro del shadow DOM.

@keyframes

Según se define en la especificación, debes poder hacer referencia a los nombres de los fotogramas clave desde una shadow root, siempre que la regla at @keyframes esté en un principal del proyecto. En la práctica, ningún navegador implementa este comportamiento, y el fotograma clave solo se puede hacer referencia a las definiciones en el alcance en el que se definen. Consulta error 10540.

@property

Como se define en la especificación, cualquier declaración de @property será en el alcance del documento. Sin embargo, actualmente, en todos los navegadores solo puedes declarar @property en el alcance del documento y las declaraciones @property dentro se ignoran las shadow roots.
Consulta el error 10541.

Errores específicos del navegador

Las otras funciones no muestran un comportamiento coherente en todos los navegadores:

  • @font-face se acopla al permiso raíz en Safari.
  • Chromium no permite heredar reglas de @anchor-name en una shadow root
  • @scroll-timeline-name y @view-timeline-name no tienen un alcance correcto en ::part (también en Chromium).
  • Ningún navegador permite declarar @font-palette-values en shadow roots.
  • view-transition-class se puede definir dentro de una shadow root (la transición está fuera de la sombra-raíz).
  • Firefox permite que ::part acceda a nombres de sombras internas (consultas de contenedores, fotogramas clave).
  • Firefox y Safari no respetan @counter-style en una shadow root.

Ten en cuenta que counter-reset, counter-set y counter-increment tienen una leve disminución reglas diferentes porque son nombres implícitos y declarar propiedades de CSS deben tener un conjunto de reglas establecidos y probados.

Conclusión

La mala noticia es que, al examinar el resumen del estado de interoperabilidad actual, Con respecto a los nombres de las CSS y al shadow DOM, la experiencia es inconsistente y tiene muchos errores. Ninguna de las funciones que examinamos aquí se comporta de manera coherente en todas y de acuerdo con las especificaciones. La buena noticia es que el delta, para hacer que la experiencia sea coherente, es un una lista de errores y problemas de especificaciones. Solucionemos esto. Mientras tanto, esperamos que esta descripción general te ayude si tienes dificultades con el las inconsistencias descritas en este artículo.