Zmiany dziedziczenia stylów zaznaczenia CSS

Data publikacji: 8 października 2024 r.

Od wersji Chrome 131 dziedziczenie wyróżnienia CSS zmienia się w przypadku pseudoklas ::selection i ::target-text. Ma to na celu utworzenie bardziej intuicyjnego modelu dziedziczenia i dostosowanie go do niedawno dodanych pseudoklas ::highlight, ::spelling-error i ::grammar-error. W tym poście wyjaśniamy, jak ta zmiana, która nie powinna mieć widocznego wpływu na większość witryn.

Stylizacja zaznaczenia

Stylizacja wyglądu wybranego tekstu może przekazywać użytkownikom znaczenie, np. przeznaczenie wybranych treści lub brak możliwości ich wybrania. Na przykład GitHub oznacza wybrany kod inaczej niż wybraną strukturę katalogu.

CSS obsługuje stylowanie zaznaczenia za pomocą pseudoelementu ::selection, który należy do zbioru pseudoelementów zwanych pseudoelementami podświetlenia. Te pseudoelementy kontrolują sposób wyświetlania tekstu w ramach różnych działań użytkownika, przeglądarki lub skryptu. Oprócz zaznaczania możesz stylizować błędy ortograficzne (::spelling-error), błędy gramatyczne (::grammar-error), tekstowe cele z osadzonym adresem URL (::target-text) oraz wyróżnienia wygenerowane przez skrypt (::highlight).

Podobnie jak w przypadku dowolnej kolekcji właściwości CSS, podczas projektowania witryny należy wziąć pod uwagę dziedziczenie. Ogólnie deweloperzy oczekują, że właściwości CSS będą dziedziczone w drzewie elementów DOM (np. font) lub wcale nie będą dziedziczone (np. background).

Zmiany w zachowaniu wyboru w Chrome 131

Weź pod uwagę ten fragment dokumentu:

p {
  color: red;
}

.blue::selection {
  color: blue;
}
<p class="blue">Some <em>emphasized</em> text that one would expect to be blue</p>

Deklaracje stylu fragmentu zmieniają kolor wybranego tekstu, przy czym jedna reguła pasuje do wszystkich elementów, a druga do elementów z klasą "blue". Wybranie tej opcji w Chrome 130 lub starszej spowoduje ten efekt:

Tekst, który powinien być niebieski, jest czerwony.

Po wybraniu w Chrome 131 wynik zmienia się na:

Tekst jest teraz podświetlony na niebiesko.

Co się zmieniło? Zachowanie dziedziczenia właściwości selekcji było wcześniej implementowane za pomocą dziedziczenia elementu źródłowego, w którym do wyboru używane są właściwości elementu ::selection dopasowanego do wybranego elementu. Wersje Chrome 130 i starsze korzystają z tego modelu, w którym wyróżniony tekst nie ma pasującego elementu ::selection, ponieważ element .blue::selection pasuje tylko do elementów z klasą "blue", a element <em> takiej klasy nie ma.

Chrome 131 wprowadza nowe działanie, w którym elementy dziedziczą zachowanie zaznaczenia od swojego elementu nadrzędnego. W poprzednim przykładzie element <em> nie ma elementów ::selection odpowiadających mu, więc dziedziczy kolory elementów <p>. Nazywamy to dziedziczeniem wyróżnień CSS. Możesz wypróbować tę funkcję w starszych wersjach Chrome, włączając eksperymentalne funkcje platformy internetowejchrome://flags.

W przypadku witryn, które korzystają z właściwości wyboru, które nie są dziedziczone, mogą wystąpić zmiany w wyglądzie wybranego tekstu, ale raporty o błędach wskazują, że jest to rzadkie.

Właściwości niestandardowe w arkuszu CSS nadal działają

Wiele witryn symuluje dziedziczenie wyróżnień CSS za pomocą właściwości niestandardowych w CSS. Właściwości niestandardowe są dziedziczone w drzewie elementów, co daje efekt „odziedziczone z rodzica” za pomocą takiego fragmentu kodu:

:root {
   --selection-color: lightgreen;
}

::selection {
  color: var(--selection-color);
}

.blue {
  --selection-color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text that is blue</p>

Oto wynik wybrany w Chrome 130 i 131:

Pierwszy wiersz jest zielony, a drugi niebieski.

W tym przypadku każdy element dziedziczy pewną wartość właściwości --selection-color z drzewa elementów, a ten kolor jest używany po wybraniu tekstu. Elementy z klasą .blue i ich potomkowie są zaznaczone na niebiesko, a inne elementy na jasnozielono. Wiele witryn korzysta z tej techniki, a ta metoda jest zalecana na Stack Overflow.

Aby zachować zgodność, model dziedziczenia wyróżnień CSS określa, że ::selection (i inne pseudoelementy wyróżnień CSS) dziedziczą wartości właściwości niestandardowych od swojego elementu źródłowego (elementu, do którego są stosowane). Zmiany w Chrome 131 nie powinny mieć wpływu na witryny korzystające z tej metody.

Właściwości niestandardowe zdefiniowane w samym pseudoelemencie ::selection są ignorowane, aby uniknąć sprzecznych zachowań dziedziczenia. Należy zdefiniować właściwości w samym elemencie, a następnie odwoływać się do nich w pseudoelemencie.

Selektory uniwersalne dla ::selection wyłączają dziedziczenie wyróżnienia

Witryny, które nie używają właściwości niestandardowych w CSS, mogły używać selektora uniwersalnego do ustawiania koloru wybranego tekstu. Na przykład:

::selection /* = *::selection (universal) */ {
  color: lightgreen;
}

.blue::selection {
  color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text</p>

Oto wynik, gdy opcja jest wybrana w Chrome 130 (i starszych) oraz w Chrome 131 (i nowszych):

Pierwszy wiersz tekstu jest zielony. Drugi jest niebieski, ale słowo jest podkreślone na zielono.

Dziedziczenie wyróżnienia CSS nie powoduje, że drugi wyróżniony tekst dziedziczy kolor niebieski od swojego nadrzędnego elementu, ponieważ uniwersalny selektor pasuje do elementu <em> i stosuje uniwersalny kolor wyróżnienia, czyli jasnozielony.

Aby korzystać z zalet dziedziczenia wyróżnienia w usłudze porównywania cen, zmień selektor uniwersalny, aby pasował tylko do elementu wyższego poziomu, który będzie dziedziczony przez elementy podrzędne:

:root::selection {
  color: lightgreen;
}

.blue::selection {
  color: blue;
}
<p>Some <em>emphasized</em> text</p>
<p class="blue">Some <em>emphasized</em> text</p>

Wynik w Chrome 131 wygląda tak:

Pierwszy wiersz tekstu jest zielony. Drugi wiersz jest niebieski.

Jeśli Twoja witryna modyfikuje kolory elementów, ale nie używa właściwości niestandardowych, prawdopodobnie masz selektor uniwersalny dla pseudoelementu ::selection. Dobrą wiadomością jest to, że ta zmiana w Chrome nie spowoduje problemów z Twoją witryną, ale nie będziesz mieć dostępu do żadnych korzyści ergonomicznych wynikających z dziedziczenia wyróżnień.

Zmienia się też styl ::target-text

Wszystkie opisane tutaj zachowania i zmiany dotyczą pseudoelementu ::target-text, tak jak w przypadku elementu ::selection. Przypadki użycia stylizacji tekstu docelowego w pojedynczej witrynie są ograniczone, a ta funkcja jest dość nowa, więc jest mało prawdopodobne, aby w Twojej witrynie zmieniło się zachowanie ::target-text.

Skąd ta zmiana?

Podczas opracowywania innych pseudoelementów wyróżnienia zespół roboczy CSS zdecydował się wdrożyć dziedziczenie z modelem dziedziczenia wyróżnienia. Ta metoda była już określona w specyfikacji pseudoelementu ::selection, ale przeglądarki jej nie wdrożyły. Pseudoelementy niebędące elementami wyboru korzystają z dziedziczenia podświetlenia, w którym pseudoelement jest dziedziczony tak, jakby był właściwością. Oznacza to, że elementy dziedziczą pseudoelementy wyróżnienia z dokumentu nadrzędnego.

W trosce o spójność wszystkich pseudoklas highlight grupa robocza CSS ponownie potwierdziła obsługę dziedziczenia highlight dla ::selection, a przeglądarki pracują nad wprowadzeniem nowego zachowania, starając się jednocześnie nie zepsuć dotychczasowych witryn.

Wypróbuj

Zmiany te ilustruje poniższy przykładowy kod w usłudze CodePen. Wypróbuj w Chrome 131.