CSS :focus-within, :has(), pointer-events

Stylujemy rodzica w CSS :focus-within, :has(), pointer-events

Często podczas stylowania mamy do czynienia z sytuacją, kiedy rodzic musi zareagować na zmiany w dziecku. Proste – coś dzieje się na danym elemencie, a my chcemy, aby na tę akcję odpowiedział element nadrzędny. Łatwo się mówi.

Generalnie – w CSS nie ma możliwości odwołania się do rodzica danego elementu. CSS nie został stworzony do podróżowania w górę drzewa. Ugh. Czemu? Ponoć z powodów wydajnościowych. Nadchodzą jednak czasy, kiedy stylowanie rodzica nie będzie powodem bezsennych nocy, zimnych potów oraz nagłych duszności…

:focus-within

To świeży, długo wyczekiwana pseudoklasa w świecie CSS. Jej działanie jest banalnie proste.

:focus-within aktywuje się, kiedy element, na którym działa jest w stanie :focus lub jakikolwiek jego potomek jest w stanie :focus.

Wsparcie – słabiutkie. Na dzień dzisiejszy Firefox (od 52), Safari (od 10.1), w Chrome pojawi się od wersji 60. Aktualne wsparcie sprawdzisz TUTAJ.

Przykład: najprostszy z możliwych, wprost z dokumentacji. Klikamy na jakikolwiek input nadając mu stan :focus, natomiast kto reaguje? Kontener, element nadrzędny, rodzic właśnie dzięki zastosowaniu na nim :focus-within.
Uwaga, jeśli przykład Wam nie działa, sprawdźcie, czy Wasza przeglądarka wspiera :focus-within

Ciekawe zastosowanie :focus-within opisuje w swoim artykule Scott: podświetlanie rzędu tabeli po zaznaczeniu komórki należącej do niego czy kombinacje w menu rozwijanym. Polecam artykuł zainteresowanym tematem.

:has()

Kolejna super pseudoklasa. Niestety, jej specyfikacja nie jest jeszcze skończona. Wsparcie wśród przeglądarek? Póki co żadne. Aktualne dane sprawdzisz TUTAJ. Uwaga – nie mylcie tej pseudoklasy z selektorem jQuery. Niby ich działanie jest takie samo, jednak sposób użycia inny

Ale do czego ona będzie służyć?

:has(selector_list) jest aktywne dla tych elementów, które zawierają w sobie przynajmniej jeden selektor z podanych jako parametry lub w których zakresie są selektory podane jako parametry.


Przykład: wybieramy wszystkie elementy <section>, które zawierają w sobie nagłówek <h1> lub element o klasie .header.

section:has(h1, .header)

Wybieramy wszystkie elementy <a>, których bezpośrednim dzieckiem jest element <img>.

a:has(> img)

Wybieramy wszystkie elementy <p>, dla których bezpośrednim następującym rodzeństwem jest inny element <span>. Tutaj paragraf <p> nie zawiera w sobie elementu <span>, jednak <span> jest w jego zakresie.

p:has(+ span)

Wybieramy wszystkie elementy <p>, dla których następującym (niekoniecznie bezpośrednim) rodzeństwem jest inny element <span>. Tutaj też paragraf <p> nie zawiera w sobie elementu <span>, jednak <span> jest w jego zakresie.

p:has(~ span)

Więcej dla zainteresowanych w drafcie W3C TUTAJ lub w artykule Chrisa TUTAJ.

pointer-events

Znacie tą własność CSSa? Ja przyznaję się bez bicia, że bardzo późno ją odkryłam. A pointer-events to własność stara jak świat, która ma świetne wsparcie (klik). Za jej pomocą określamy, czy dany element ma reagować na zdarzenia wywołane kursorem myszy lub dotknięciem na ekranie dotykowym. Możemy przypisać jej aż 11 wartości, jednak 8 z nich jest zarezerwowanych dla elementów SVG. Pozostałe 3 to auto, none, inherit.

Ok. I jak to się ma ze stylowaniem rodzica? Tylko spójrzcie na poniższy przykład.

See the Pen pointer-events by sourire09 (@sourire09) on CodePen.dark

Po kolei. Mamy kontener (rodzic), a w nim przycisk (dziecko). Naszym celem jest to, aby po najechaniu na przycisk, zmienił się kolor ramki rodzica. Jakim cudem? Do rodzica dopisujemy regułę zmiany koloru podczas każdego najechania myszką nad rodzicem. Ale hola hola! Przecież kolor ma się zmieniać podczas hovera nad przyciskiem! Dlatego też dopisujemy do rodzica regułę  pointer-events: none.

.container {
  pointer-events: none;
  border: 10px solid grey;
  transition: border-color 0.3s ease-in-out;
  
  &:hover {
    border-color: green;
  }
}

Teraz hover nigdzie nie działa! Aby przywrócić go nad przyciskiem, dopisujemy:

.button {
  pointer-events: auto;
}

Ot, cała filozofia.

Szukacie innych przykładów użycia pointer-events? Ależ proszę:

See the Pen Stuff you can do with CSS pointer events by Martijn Cuppens (@MartijnCuppens) on CodePen.dark


Znacie jakieś inne magiczne sztuczki do stylowania rodzica w CSS? Dajcie znać w komentarzach!

Artykuły, które mogą Ci się spodobać...

Wpisz hasło, którego szukasz i naciśnij ENTER, aby je wyszukać. Naciśnij ESC, aby anulować.

Dawaj na górę