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, co jest nowością, animacje sterowane przewijaniem, 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 Dowolna deklaracja niezarejestrowanej właściwości niestandardowej |
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 kontenera | container-name |
@container |
Strona | page |
@page |
Jak widać w tabeli, nazwa usługi porównywania cen zwykle odpowiada jej odwołaniu. 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 zapewnić elastyczność, ale też na tyle ograniczone, aby zapewnić stabilność.
Teoretycznie jest to dobre. W praktyce przeglądarki nie są spójne pod względem sposobu, w jaki nazwy CSS współdziałają z modelem shadow DOM, 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 model shadow DOM powinny 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 CSS jest globalna w zakresie, w którym jest zdefiniowana. Oznacza to, że można uzyskać do niej dostęp z drzew potomnych cieni, ale nie z drzew potomnych lub nadrzędnych. Pamiętaj, że w odróżnieniu od nazw na platformie internetowej, takich jak identyfikatory elementów, które są zapieczętowane w tym samym zakresie drzewa.
Wyjątek od reguły: @property
W przeciwieństwie do innych nazw CSS właściwości CSS nie są otoczone przez DOM cieniowany.
Są to raczej wspólne środki przekazywania parametrów między różnymi drzewami cieni.
To sprawia, że deskryptor @property
jest wyjątkowy: ma on 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 powodowałaby nieoczekiwane wyniki. Dlatego deklaracje @property
są sformatowane i rozwiązywane zgodnie z kolejnością w dokumencie.
Jak reguła powinna działać w przypadku funkcji ::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 zgodnie z definicją 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 nie można odwoływać się do nazw z modelu shadow DOM za pomocą interfejsu ::part
, ponieważ ::part
to styl ograniczony do hosta, a nie ograniczony do cienia. 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 odróżnieniu od ::part
style wbudowane z atrybutem style
lub te, które automatycznie ustawiają styl za pomocą skryptu, mają zakres ograniczony do zakresu elementu. Wynika to z faktu, że zastosowanie stylu do elementu wymaga dostępu
do uchwytu elementu, a tym samym do samego poziomu głównego.
Jak nazwy CSS i shadow DOM współdziałają w rzeczywistości
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ć działanie tych funkcji w praktyce, utworzyliśmy 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 jest wymagane shadow DOM, więc powinno 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 odniesienie do nazwy zewnętrznej: powinno to zadziałać, ponieważ nazwy ograniczone do drzewa są dziedziczone przez rdzenie podrzędne.
- Wewnętrzne odwołanie do wewnętrznej nazwy: powinno to działać, ponieważ nazwa odwołania znajduje się w tym samym zakresie.
- Odwołanie
::part
do nazwy zewnętrznej: powinno to zadział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 z definicją w specyfikacji każda deklaracja wartości @property
zostanie spłaszczona 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.
Przeczytaj 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 głównym - Atrybuty
scroll-timeline-name
iview-timeline-name
mają nieprawidłowy zakres w witrynie::part
(również w Chromium). - Żadna przeglądarka nie zezwala na zadeklarowanie wartości
@font-palette-values
w rdzeniach cieni. view-transition-class
można zdefiniować w korzeniach zduplikowanych (sama zmiana jest 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ą problemy z niespójnością i błędami. Żadna z badanych przez nas funkcji nie działa w spójny sposób we wszystkich 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.