Os nomes CSS definidos por autoria e o shadow DOM devem funcionar juntos. No entanto, os navegadores são inconsistentes com a especificação, às vezes com problemas e cada nome CSS é inconsistente de uma maneira um pouco diferente.
Este artigo documenta o status atual de como os nomes CSS definidos pelo autor se comportam nos escopos de sombra, na esperança de que possa servir de guia para melhorar e interoperabilidade em um futuro próximo.
O que são nomes CSS definidos pelo autor?
Os nomes CSS definidos pelo autor são um mecanismo de sintaxe CSS relativamente antigo,
introduzido para a regra @keyframes
, que define um <keyframe-name>
como
uma ident personalizada ou uma string. O objetivo desse conceito é declarar
algo em uma parte de uma folha de estilo e referenciá-lo em outra 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;
}
Outros recursos CSS que usam nomes CSS são fontes, declarações de propriedade, consultas de contêiner e, mais recentemente, transições de visualização, posicionamento de âncoras e animações de rolagem. A tabela não abrangente a seguir inclui nomes em que o Chrome verifica o estado.
Recurso | Declaração de nome | Referência de nome |
---|---|---|
Frames-chave | @keyframes |
animation-name |
Fontes | @font-face { }
@font-palette-values |
font-family
font-palette |
Declarações de propriedade | @property |
Qualquer propriedade personalizada |
Ver transição | view-transition-name
view-transition-class |
::view-transition-group() |
Posicionamento da âncora | anchor-name |
position-anchor |
Animação de rolagem | animation-timeline |
view-timeline-name
scroll-timeline-name |
Estilo do contador | @counter-style
Counter-reset
counter-set
counter-increment |
list-style |
Consultas em contêiner | container-name |
@container |
Variável CSS | --something |
var(--something) |
Página | @page |
Como você pode ver na tabela, um name de CSS geralmente tem um CSS correspondente
referência. Por exemplo, animation-name
é uma referência ao objeto @keyframes
nome. Os nomes CSS são diferentes dos definidos no DOM, como atributos
e nomes de tag, já que são declarados e depois referenciados dentro do contexto do
as folhas de estilo.
Como os nomes se relacionam com o shadow DOM
Enquanto os nomes CSS são construídos para criar relações entre diferentes partes de uma documento ou folha de estilo, o Shadow DOM é criado para fazer o oposto. Ela encapsula as relações para que não vazem entre os componentes da Web que devem ter o próprio namespace.
Ao juntar os nomes CSS e o shadow DOM, a experiência de compor os componentes da Web devem parecer expressivos o suficiente para serem flexíveis, mas restritos o suficiente para se manter estável.
Na teoria, isso é bom. Na prática, os navegadores são inconsistentes na forma como o CSS interoperam com o shadow DOM entre recursos no mesmo navegador, entre navegadores e entre os recursos e a especificação.
Como os nomes e o shadow DOM devem funcionar juntos
Para entender o problema, é importante entender como essas partes do CSS devem funcionar juntos na teoria.
A regra geral
A regra geral de como os nomes CSS se comportam entre árvores paralelas é definida no arquivo Especificação de escopo do CSS nível 1. Para resumir: um nome CSS é global dentro do escopo em que é definido, ou seja, ele pode ser acessado por árvores paralelas descendentes, mas não por árvores-sombra ancestrais. Observe que são diferentes de nomes na plataforma da Web, como IDs de elementos, que são encapsulados no mesmo escopo de árvore.
Exceção à regra: @property
Ao contrário de outros nomes CSS, as propriedades CSS não são encapsuladas pelo shadow DOM.
Em vez disso, são os meios comuns de transmitir parâmetros em diferentes
árvores.
Isso faz
Descritor @property
especial: deve se comportar como uma declaração de tipo "document-global"
define como uma propriedade nomeada específica age. Como as propriedades precisam ser
entre árvores paralelas, a incompatibilidade de declarações de propriedade criaria
resultados, portanto, as declarações @property
são especificadas para serem niveladas e resolvidas.
de acordo com a ordem do documento.
Como a regra vai funcionar com ::part
Partes de sombra
expor um elemento dentro de uma árvore paralela à árvore pai. Ao fazer isso, o
árvore mãe pode acessar esse elemento e também estilizá-lo usando a ::part
.
.
Como ::part
permite que dois escopos de árvore estilizem o mesmo elemento, o seguinte
a ordem em cascata é especificada:
- Primeiro, verifique o estilo dentro do contexto da sombra. Essa é a configuração "padrão" o estilo da peça.
- Em seguida, aplique o estilo externo conforme definido em
::part
. Esta é a "personalizado" o estilo da peça. - Em seguida, aplique qualquer estilo interno definido com
!important
. Isso permite que um elemento personalizado declare que determinada propriedade de um determinado não é personalizável por::part
.
Isso significa que os nomes dentro do shadow DOM não podem ser referenciados em um
::part
, já que ::part
é um estilo com escopo de host em vez de com escopo de sombra.
estilo. Exemplo:
// 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;
}
Como a regra deve funcionar com estilos in-line
Diferente de ::part
, estilos in-line com o atributo style
ou aqueles
definindo programaticamente o estilo usando script, têm o escopo do elemento
tem o escopo definido. Isso porque, para aplicar um estilo a um elemento ao qual você precisa de acesso,
na alça do elemento e, portanto, na própria raiz paralela.
Como os nomes CSS e o shadow DOM funcionam juntos na realidade
Embora as regras anteriores sejam bem definidas e consistentes, a abordagem
nem sempre refletem isso.
Na prática, @property
funciona de maneira diferente da especificação de maneira consistente.
em vários navegadores, e a maioria dos outros recursos apresenta bugs abertos (alguns deles estão
que ainda não foram lançados, então há tempo para corrigi-los).
Para testar e demonstrar como esses recursos funcionam na prática, criamos o seguinte página: https://css-names-in-the-shadow.glitch.me/. Esta página tem vários iframes, cada um focado em um dos recursos e testando seis cenários:
- Referência externa a um nome externo: nenhum shadow DOM envolvido, deve funcionam.
- Referência externa a um nome interno: não funciona, porque significa que o nome definido no contexto sombra vazou.
- Referência interna ao nome externo: funciona, como nomes com escopo de árvore. são herdados por raízes sombra.
- Referência interna ao nome interno: deve funcionar como o nome do bloco estão no mesmo escopo.
- Referência de
::part
ao nome externo: precisa funcionar, já que o::part
e o nome sejam declarados no mesmo escopo. - Referência de
::part
ao nome interno: não vai funcionar, como o escopo externo não devem adquirir conhecimento sobre nomes declarados dentro do shadow DOM.
@keyframes
Conforme definido na especificação, será possível fazer referência a nomes de frames-chave
de uma raiz paralela, desde que a @keyframes
esteja em um ancestral.
do projeto. Na prática, nenhum navegador implementa esse comportamento, e o frame-chave
as definições só podem ser referenciadas no escopo em que são definidas. Consulte
problema 10540 (link em inglês).
@property
Conforme definido na especificação, qualquer declaração de @property
será
simplificada para o escopo do documento. Atualmente, no entanto, em todos os navegadores, só é possível
declarar @property
no escopo do documento e @property
declarações no
as raízes paralelas serão ignoradas.
Consulte o problema 10541.
Bugs específicos do navegador
Os outros recursos não apresentam um comportamento consistente nos navegadores:
@font-face
é simplificado para o escopo raiz no Safari.- O Chromium não permite herdar regras
@anchor-name
em uma raiz paralela - O escopo de
@scroll-timeline-name
e@view-timeline-name
não está definido corretamente no::part
(também no Chromium). - Nenhum navegador permite declarar
@font-palette-values
em raízes paralelas. view-transition-class
pode ser definido dentro de uma raiz paralela (a transição está fora da raiz paralela).- O Firefox permite que o
::part
acesse nomes de sombras internos (consultas de contêiner, frames-chave). - O Firefox e o Safari não respeitam a
@counter-style
em uma raiz paralela.
counter-reset
, counter-set
e counter-increment
têm um pouco de
regras diferentes porque são nomes implícitos e declaram propriedades CSS
ter um conjunto de regras estabelecido e bem testado.
Conclusão
A má notícia é que, ao examinar o instantâneo do estado de interoperabilidade atual, em relação aos nomes CSS e ao shadow DOM, a experiência é inconsistente e de bugs. Nenhum dos recursos que examinamos se comporta de forma consistente navegadores e de acordo com as especificações. A boa notícia é que o delta para tornar a experiência consistente é finito lista de bugs e problemas de especificação. Vamos corrigir isso. Enquanto isso, esta visão geral pode ajudar se você estiver com dificuldades e inconsistências descritas neste artigo.