Nazwy CSS zdefiniowane przez autora i DOM cieni mają ze sobą współpracować. Jednak przeglądarki nie są zgodne ze specyfikacją, czasem ze sobą nawzajem, a każda nazwa w CSS jest niespójna w trochę inny sposób.
Z tego artykułu dowiesz się, jak obecnie zachowują się nazwy CSS zdefiniowane przez autora w różnych zakresach cieniowych. Mamy nadzieję, że pomoże Ci to w niedalekiej przyszłości poprawić interoperacyjność.
Czym są nazwy CSS zdefiniowane przez autora?
Nazwy CSS zdefiniowane przez autora to stosunkowo stary mechanizm składni CSS, który został pierwotnie wprowadzony w ramach reguły @keyframes
, która definiuje <keyframe-name>
jako identyfikator niestandardowy lub ciąg znaków. Celem tego założenia jest zadeklarowanie czegoś w jednej części arkusza stylów i odwoływanie się do niego w innej części.
/* "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;
}
Inne funkcje CSS, które używają nazw CSS, to czcionki, deklaracje właściwości, zapytania o kontenery oraz, w ostatnim czasie, animacje sterowane przez przewijanie, pozycjonowanie kotwic i przechodzenie między widokami. W tej niepełnej tabeli znajdują się nazwy, których stan jest sprawdzany przez Chrome.
Funkcja | Oświadczenie o nazwie | Nazwa |
---|---|---|
Klatki kluczowe | @keyframes |
animation-name |
Czcionki | @font-face { }
@font-palette-values |
font-family
font-palette |
Deklaracje dotyczące usługi | @property Wszelkie niezarejestrowane deklaracje właściwości niestandardowych |
var() |
Wyświetlanie przejść | view-transition-name
view-transition-class |
::view-transition-* elementy pseudo |
Umieszczenie kotwicy | anchor-name |
position-anchor |
Animacja wywoływana przez przewijanie | view-timeline-name
scroll-timeline-name |
animation-timeline |
Style list | @counter-style |
list-style |
Liczniki | counter-reset
counter-set
counter-increment |
|
Zapytania dotyczące kontenerów | container-name |
@container |
Strona | page |
@page |
Jak widać w tabeli, nazwa usługi porównywania cen zwykle ma odpowiadającą jej referencję. Na przykład animation-name
to odwołanie do nazwy @keyframes
. Nazwy CSS różnią się od nazw zdefiniowanych w DOM, takich jak atrybuty i nazwy tagów, ponieważ są deklarowane, a następnie odwołują się do nich w kontekście skryptów.
Jak nazwy są powiązane z shadow DOM
Nazwy CSS służą do tworzenia relacji między różnymi częściami dokumentu lub arkusza stylów, a Shadow DOM działa na odwrót. Zawiera ona relacje, aby nie były one widoczne w komponentach internetowych, które mają mieć własną przestrzeń nazw.
Połączenie nazw CSS i domu kratowego cienia powinno sprawić, że tworzenie komponentów internetowych będzie na tyle elastyczne, aby można było je dowolnie modyfikować, a jednocześnie na tyle ograniczone, aby były stabilne.
To dobrze w teorii. W praktyce przeglądarki nie są spójne w sposobie, w jaki nazwy CSS współdziałają z modelem DOM cieni, zarówno w przypadku funkcji w tej samej przeglądarce, w różnych przeglądarkach, jak i między funkcjami a specyfikacją.
Jak nazwy i DOM cieniowany powinny ze sobą współpracować
Aby zrozumieć problem, warto wiedzieć, jak te części CSS powinny teoretycznie ze sobą współpracować.
Zasada ogólna
Ogólna reguła dotycząca zachowania nazw CSS w drzewach cieni jest zdefiniowana w specyfikacji CSS Scoping Level 1. Podsumowując: nazwa usługi porównywania cen jest globalna w zakresie, w którym jest zdefiniowana, co oznacza, że można uzyskać do niej dostęp z potomnych drzew cieni, ale nie z siostrzanych ani przodkowych drzew cieni. Pamiętaj, że w odróżnieniu od nazw na platformie internetowej, takich jak identyfikatory elementów, które są ujęte w ramach tego samego zakresu drzewa.
Wyjątek od reguły: @property
W przeciwieństwie do innych nazw CSS właściwości CSS nie są opakowane przez DOM cieniowany.
Są to raczej wspólne środki przekazywania parametrów między różnymi drzewami cieni.
Dzięki temu deskryptor @property
jest wyjątkowy: ma działać jak deklaracja typu globalnego dokumentu, która określa działanie określonej nazwanej właściwości. Właściwości muszą być zgodne w drzewach cieni, a niezgodność deklaracji właściwości może powodować nieoczekiwane wyniki. Dlatego deklaracje @property
są sformatowane i rozwiązywane zgodnie z kolejnością w dokumencie.
Jak reguła powinna działać w przypadku ::part
Części cienia
pozwalają na wyświetlanie elementu w drzewie cienia w drzewie nadrzędnym. Dzięki temu drzewo nadrzędne ma dostęp do tego elementu i może go stylizować za pomocą elementu ::part
.
Ponieważ ::part
pozwala dwóm zakresom drzewa na nadanie stylu temu samemu elementowi, określono następującą kolejność kaskadową:
- Najpierw sprawdź styl w kontekście cienia. Jest to „domyślny” styl części.
- Następnie zastosuj styl zewnętrzny zdefiniowany w sekcji
::part
. Jest to „spersonalizowany” styl części. - Następnie zastosuj dowolny styl wewnętrzny zdefiniowany razem z elementem
!important
. Dzięki temu element niestandardowy może zadeklarować, że dana właściwość danego elementu nie może być dostosowywana przez::part
.
Oznacza to, że nazwy w modelu DOM ocienionego nie mogą być używane w elementach ::part
, ponieważ ::part
jest stylem ograniczonym do hosta, a nie do modelu ocienionego. Na przykład:
// 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;
}
Jak reguła powinna działać w przypadku stylów wbudowanych
W przeciwieństwie do atrybutu ::part
atrybuty stylów wbudowanych z atrybutem style
lub te, które są ustawiane programowo za pomocą skryptu, są ograniczone do zakresu elementu. Dzieje się tak, ponieważ aby zastosować styl do elementu, musisz mieć dostęp do uchwytu elementu, a tym samym do samego korzenia cienia.
Jak nazwy w CSS i DOM cieni współpracują ze sobą w praktyce
Chociaż powyższe reguły są dobrze zdefiniowane i spójne, ich obecne wdrożenia nie zawsze to odzwierciedlają.
W praktyce @property
działa w sposób spójny w różnych przeglądarkach, ale większość innych funkcji ma otwarte błędy (niektóre z nich nie zostały jeszcze wydane, więc jest czas na ich naprawę).
Aby przetestować i zademonstrować, jak te funkcje działają w praktyce, utworzyliśmy tę stronę: https://css-names-in-the-shadow.glitch.me/. Ta strona zawiera kilka ramek iframe, z których każda koncentruje się na jednej z funkcji i testuje 6 scenariuszy:
- Odniesienie zewnętrzne do nazwy zewnętrznej: nie ma potrzeby korzystania z DOM cieniowanego, więc powinno to działać.
- Odwołania zewnętrzne do nazw wewnętrznych: nie powinny działać, ponieważ oznaczałoby to, że nazwa zdefiniowana w kontekście skrótu została ujawniona.
- Wewnętrzne odwołanie do nazwy zewnętrznej: powinno to działać, ponieważ nazwy ograniczone do drzewa są dziedziczone przez korzenie cienia.
- Wewnętrzne odwołanie do wewnętrznej nazwy: powinno to działać, ponieważ nazwa odwołania znajduje się w tym samym zakresie.
::part
odwołanie do nazwy zewnętrznej: powinno to działać, ponieważ zarówno::part
, jak i nazwa są zadeklarowane w tym samym zakresie.::part
odwołanie do nazwy wewnętrznej: nie powinno działać, ponieważ zakres zewnętrzny nie może uzyskać informacji o nazwach zadeklarowanych w cieniach DOM.
@keyframes
Zgodnie ze specyfikacją nazwy klatek kluczowych powinny być dostępne w rdzeniu schatten, o ile reguła at-rule @keyframes
znajduje się w zakresie przodka. W praktyce żaden przeglądarka nie wdraża tego zachowania, a definicje klatek kluczowych mogą być używane tylko w zakresie, w którym zostały zdefiniowane. Zobacz problem 10540.
@property
Zgodnie ze specyfikacją wszystkie deklaracje @property
zostaną spłaszczone do zakresu dokumentu. Obecnie we wszystkich przeglądarkach można deklarować tylko atrybuty @property
w zakresie dokumentu, a deklaracje atrybutów @property
w korzeniach cienia są ignorowane.
Zobacz problem 10541.
Błędy związane z przeglądarką
Pozostałe funkcje nie działają w taki sam sposób w różnych przeglądarkach:
@font-face
jest spłaszczone do zakresu katalogu źródeł w Safari.- Chromium nie zezwala na dziedziczenie reguł
anchor-name
w katalogu cieni. scroll-timeline-name
iview-timeline-name
nie są prawidłowo ograniczone do::part
(także w Chromium).- Żadna przeglądarka nie zezwala na deklarowanie
@font-palette-values
w katalogu głównym cienia. view-transition-class
można zdefiniować w korzeniach zduplikowanych (sama przejście znajduje się poza korzeniami zduplikowanymi).- Firefox umożliwia
::part
dostęp do nazw cieni wewnętrznych (zapytania dotyczące kontenera, klatki kluczowe). - Firefox i Safari nie uwzględniają
@counter-style
w katalogu cieni.
Pamiętaj, że counter-reset
, counter-set
i counter-increment
mają nieco inne reguły, ponieważ są to nazwy domyślne, a deklarowanie właściwości CSS podlega ustalonemu i dobrze przetestowanemu zestawowi reguł.
Podsumowanie
Złe wieści są takie, że przy obecnym stanie interoperacyjności w przypadku nazw CSS i domu kratowego cienia występują niespójności i błędy. Żadna z badanych przez nas funkcji nie działa w sposób spójny w różnych przeglądarkach i zgodnie ze specyfikacją. Dobra wiadomość jest taka, że różnica, która powoduje niespójności, to ograniczona lista błędów i problemów ze specyfikacją. Naprawmy to. Mamy nadzieję, że ten artykuł pomoże Ci rozwiązać problemy z niespójnościami opisanymi w tym artykule.