Tworzenie animowanych, klikalnych kart za pomocą :has() relacyjnej pseudoklasy PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. Aj.

Tworzenie animowanych, klikalnych kart za pomocą relacyjnej pseudoklasy :has()

CSS :has() pseudoklasa jest wprowadzana w wielu przeglądarkach z Chrom i Safari już go w pełni popiera. Często nazywa się go „selektorem rodzica” — tak jak w przypadku, możemy wybrać styl elementu rodzica z selektora dziecka — ale jest o wiele więcej :has() może nam pomóc rozwiązać. Jedną z tych rzeczy jest ponowne wymyślenie klikalnego wzoru kart, którego wielu z nas lubi używać od czasu do czasu.

Przyjrzymy się, jak :has() może nam pomóc w obsłudze kart powiązanych, ale najpierw…

Co to jest :has() pseudo klasa?

Jest już wiązka of wspaniały ilość postów unosić się dookoła które wykonują świetną robotę wyjaśniając co :has() jest i do czego służy, ale wciąż jest na tyle nowy, że i tutaj powinniśmy o nim powiedzieć kilka słów.

:has() jest relacyjną pseudoklasą, która jest częścią Wersja robocza selektorów W3C poziomu 4. O to właśnie chodzi w nawiasach: dopasowywanie elementów, które są powiązane z — lub, dokładniej, zawierają — pewne elementy podrzędne.

/* Matches an article element that contains an image element */
article:has(img) { }

/* Matches an article element with an image contained immediately within it */
article:has(> img) { }

Możesz więc zobaczyć, dlaczego możemy nazwać go selektorem „rodzica”. Ale możemy również połączyć go z innymi pseudoklasami funkcjonalnymi, aby uzyskać bardziej szczegółowe. Załóżmy, że chcemy stylizować artykuły, które nie nie zawierać żadnych obrazów. Możemy połączyć relacyjne moce :has() z mocą negacji :not() aby to zrobić:

/* Matches an article without images  */
article:not(:has(img)) { }

Ale to dopiero początek tego, jak możemy połączyć moce, aby zrobić więcej :has(). Zanim przejdziemy konkretnie do rozwiązania zagadki z klikalnymi kartami, przyjrzyjmy się kilku sposobom, w jakie obecnie podchodzimy do nich bez użycia :has().

Jak obecnie obsługujemy karty klikalne

W dzisiejszych czasach istnieją trzy główne podejścia do tego, jak ludzie tworzą w pełni klikalną kartę i aby w pełni zrozumieć moc tej pseudoklasy, dobrze jest zrobić małe podsumowanie.

Takie podejście jest stosowane dość często. Nigdy nie stosuję tego podejścia, ale stworzyłem szybkie demo, aby to zademonstrować:

Jest tu wiele obaw, zwłaszcza jeśli chodzi o dostępność. Gdy użytkownicy poruszają się po Twojej witrynie za pomocą funkcja wirnika;, usłyszą cały tekst w środku element — nagłówek, tekst i łącze. Ktoś może nie chcieć przez to wszystko siedzieć. Możemy zrobić lepiej. Od HTML5 możemy zagnieżdżać elementy blokowe wewnątrz element. Ale nigdy nie wydaje mi się to właściwe, zwłaszcza z tego powodu.

Plusy:

  • Szybki do wdrożenia
  • Semantycznie poprawny

Wady:

  • Obawy dotyczące dostępności
  • Nie można wybrać tekstu
  • Dużo kłopotów z nadpisywaniem stylów użytych w domyślnych linkach

Metoda JavaScript

Używając JavaScript, możemy dołączyć link do naszej karty zamiast wpisywać go w znaczniku. Znalazłem to świetne demo CodePen przez odchylenie kosztów kto również umożliwił wybór tekstu karty w tym procesie:

Takie podejście ma wiele zalet. Nasze linki są dostępne po fokusie i możemy nawet zaznaczyć tekst. Ale są pewne wady, jeśli chodzi o stylizację. Jeśli chcemy na przykład animować te karty, musielibyśmy dodać :hover style na naszym głównym .card wrapper zamiast samego linku. Nie skorzystalibyśmy również z animacji, gdy linki są w centrum uwagi po naciśnięciu klawisza tabulacji.

Plusy:

  • Może być doskonale dostępny
  • Możliwość zaznaczenia tekstu

Wady:

  • Wymaga JavaScript
  • Kliknięcie prawym przyciskiem nie jest możliwe (chociaż można to naprawić za pomocą dodatkowych skryptów)
  • Będzie wymagało dużo stylizacji na samej karcie, co nie działałoby podczas skupiania linku

Połączenia ::after podejście selektora

Ta metoda wymaga od nas ustawienia karty z pozycjonowaniem względnym, a następnie ustawienia pozycjonowania bezwzględnego na linku ::after pseudo selektor linku. To nie wymaga JavaScriptu i jest dość łatwe do zaimplementowania:

Jest tutaj kilka wad, zwłaszcza jeśli chodzi o zaznaczanie tekstu. Jeśli nie podasz wyższego indeksu Z na treści karty, nie będziesz w stanie zaznaczyć tekstu, ale jeśli to zrobisz, pamiętaj, że kliknięcie tekstu nie aktywuje Twojego linku. To, czy chcesz wybrać tekst, zależy od Ciebie. Myślę, że może to być problem UX, ale zależy to od przypadku użycia. Tekst jest nadal dostępny dla czytników ekranu, ale moim głównym problemem z tą metodą jest brak możliwości animacji.

Plusy:

  • Łatwy do wdrożenia
  • Dostępny link bez rozdętego tekstu
  • Działa na najechaniu i skupieniu

Wady:

  • Nie można wybrać tekstu
  • Możesz tylko animować link, ponieważ jest to element, na który się unosisz.

Nowe podejście: Korzystanie ::after w :has()

Teraz, gdy ustaliliśmy już istniejące podejścia do kart klikalnych, chcę pokazać, jak wprowadzać :has() do miksu rozwiązuje większość tych niedociągnięć.

W rzeczywistości oprzyjmy to podejście na ostatnim, którym przyjrzeliśmy się przy użyciu ::after na elemencie łącza. Możemy faktycznie użyć :has() tam, aby przezwyciężyć ograniczenia animacji tego podejścia.

Zacznijmy od znaczników:

Fluffy gray and white tabby kitten snuggled up in a ball.

Some Heading

Curabitur convallis ac quam vitae laoreet. Nulla mauris ante, euismod sed lacus sit amet, congue bibendum eros. Etiam mattis lobortis porta. Vestibulum ultrices iaculis enim imperdiet egestas.

Będę starał się jak najbardziej uprościć, kierując elementy w CSS zamiast na klasy.

W tym pokazie dodamy powiększenie obrazu i cień do karty po najechaniu myszą, a link będzie animowany za pomocą wyskakującej strzałki i zmiany koloru tekstu linku. Aby to ułatwić, dodamy do naszej karty kilka właściwości niestandardowych. Oto podstawowa stylizacja:

/* The card element */
article {
  --img-scale: 1.001;
  --title-color: black;
  --link-icon-translate: -20px;
  --link-icon-opacity: 0;

  position: relative;
  border-radius: 16px;
  box-shadow: none;
  background: #fff;
  transform-origin: center;
  transition: all 0.4s ease-in-out;
  overflow: hidden;
}
/* The link's ::after pseudo */
article a::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline: 0;
  cursor: pointer;
}

Świetny! Dodaliśmy początkową skalę obrazu (--img-scale: 1.001), początkowy kolor nagłówka karty (--title-color: black) i kilka dodatkowych właściwości, których użyjemy, aby nasza strzałka wyskoczyła z linku. Ustawiliśmy również pusty stan box-shadow deklarację w celu późniejszej jej animacji. To ustawia to, czego potrzebujemy teraz dla klikalnej karty, więc dodajmy do niej resetowanie i stylizację, dodając te niestandardowe właściwości do elementów, które chcemy animować:

article h2 {
  margin: 0 0 18px 0;
  font-family: "Bebas Neue", cursive;
  font-size: 1.9rem;
  letter-spacing: 0.06em;
  color: var(--title-color);
  transition: color 0.3s ease-out;
}
article figure {
  margin: 0;
  padding: 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
article img {
  max-width: 100%;
  transform-origin: center;
  transform: scale(var(--img-scale));
  transition: transform 0.4s ease-in-out;
}
article a {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  color: #28666e;
}
article a:focus {
  outline: 1px dotted #28666e;
}
article a .icon {
  min-width: 24px;
  width: 24px;
  height: 24px;
  margin-left: 5px;
  transform: translateX(var(--link-icon-translate));
  opacity: var(--link-icon-opacity);
  transition: all 0.3s;
}

.article-body {
  padding: 24px;
}

Bądźmy mili dla ludzi, a także dodajmy klasa czytnika ekranu ukryty za linkiem:

.sr-only:not(:focus):not(:active) {
  clip: rect(0 0 0 0); 
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap; 
  width: 1px;
}

Nasza kartka zaczyna wyglądać całkiem słodko. Czas dodać do tego odrobinę magii. Z :has() pseudoklasa, możemy teraz sprawdzić, czy nasz link jest najechany lub skoncentrowany, a następnie zaktualizować nasze niestandardowe właściwości i dodać a box-shadow. Dzięki temu małemu fragmentowi CSS nasza karta naprawdę ożywa:

/* Matches an article element that contains a hover or focus state */
article:has(:hover, :focus) {
  --img-scale: 1.1;
  --title-color: #28666e;
  --link-icon-translate: 0;
  --link-icon-opacity: 1;

  box-shadow: rgba(0, 0, 0, 0.16) 0px 10px 36px 0px, rgba(0, 0, 0, 0.06) 0px 0px 0px 1px;
}

Widzisz, co tam jest? Teraz otrzymujemy zaktualizowane style, jeśli każdy element podrzędny na karcie jest najechany lub skupiony. I chociaż element linku jest jedyną rzeczą, która może zawierać stan najechania lub fokusu w ::after podejście z klikalną kartą, możemy użyć tego, aby dopasować element nadrzędny i zastosować przejścia.

I masz to. Po prostu kolejny potężny przypadek użycia dla :has() selektor. Nie tylko możemy dopasować element nadrzędny, deklarując inne elementy jako argumenty, ale możemy również dopasowywać za pomocą pseudosów do dopasowywania i stylizowania rodziców.

Plusy:

  • Dostępny
  • Animowalny
  • Nie wymaga JavaScript
  • Używa :hover na właściwym elemencie

Wady:

  • Tekst nie jest łatwy do zaznaczenia.
  • Obsługa przeglądarek jest ograniczona do Chrome i Safari (jest obsługiwana w Firefoksie za flagą).

Oto demo wykorzystujące tę technikę. Możesz zauważyć dodatkowe opakowanie wokół karty, ale to tylko ja się bawię zapytania dotyczące kontenerów, który jest tylko jedną z tych fantastycznych rzeczy, które pojawiają się we wszystkich głównych przeglądarkach.

Mam trochę inne przykłady chcesz się podzielić? Inne rozwiązania lub pomysły są mile widziane w sekcji komentarzy.

Znak czasu:

Więcej z Sztuczki CSS