Erstellen von animierten, anklickbaren Karten mit der PlatoBlockchain-Datenintelligenz der relationalen Pseudoklasse :has(). Vertikale Suche. Ai.

Animierte, anklickbare Karten mit der relationalen Pseudoklasse :has() erstellen

Das CSS :has() Pseudo-Klasse wird in vielen Browsern mit eingeführt Chrome und Safari unterstützt sie bereits voll und ganz. Es wird oft als „übergeordneter Selektor“ bezeichnet – wie in, wir können ein übergeordnetes Element aus einem untergeordneten Selektor auswählen – aber es gibt noch so viel mehr :has() kann uns bei der Lösung helfen. Eines dieser Dinge ist die Neuerfindung des anklickbaren Kartenmusters, das viele von uns von Zeit zu Zeit gerne verwenden.

Wir schauen uns an, wie :has() kann uns beim Umgang mit verknüpften Karten helfen, aber zuerst …

Was ist das :has() Pseudoklasse?

Es gibt schon eine Bündel of groß Beiträge herumschwimmen die sehr gut erklären, was :has() ist und wofür es verwendet wird, aber es ist immer noch so neu, dass wir hier auch ein paar Worte darüber verlieren sollten.

:has() ist eine relationale Pseudoklasse, die Teil von ist W3C Selectors Level 4 Arbeitsentwurf. Darum geht es bei den Klammern: übereinstimmende Elemente, die sich auf bestimmte untergeordnete Elemente beziehen oder, genauer gesagt, enthalten.

/* 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) { }

Sie können also sehen, warum wir es vielleicht einen „Eltern“-Selektor nennen möchten. Aber wir können es auch mit anderen funktionalen Pseudoklassen kombinieren, um spezifischer zu werden. Angenommen, wir möchten Artikel gestalten, die dies tun nicht irgendwelche Bilder enthalten. Wir können die Beziehungskräfte von kombinieren :has() mit den Verneinungskräften von :not() das zu tun:

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

Aber das ist nur der Anfang, wie wir Kräfte bündeln können, um mehr zu erreichen :has(). Bevor wir uns speziell der Lösung des Rätsels um anklickbare Karten zuwenden, wollen wir uns ein paar Möglichkeiten ansehen, wie wir sie derzeit angehen, ohne sie zu verwenden :has().

Wie wir derzeit mit anklickbaren Karten umgehen

Es gibt drei Hauptansätze, wie Menschen heutzutage eine vollständig anklickbare Karte erstellen, und um die Leistungsfähigkeit dieser Pseudoklasse vollständig zu verstehen, ist es schön, eine kleine Zusammenfassung zu haben.

Dieser Ansatz wird recht häufig verwendet. Ich verwende diesen Ansatz nie, aber ich habe eine kurze Demo erstellt, um ihn zu demonstrieren:

Hier gibt es viele Bedenken, insbesondere wenn es um Barrierefreiheit geht. Wenn Benutzer mit Ihrer Website navigieren die Rotorfunktion, sie werden den vollständigen Text darin hören element — die Überschrift, der Text und der Link. Jemand möchte das vielleicht nicht durchstehen. Wir können es besser. Seit HTML5 können wir Blockelemente innerhalb von verschachteln Element. Aber es fühlt sich für mich nie richtig an, besonders aus diesem Grund.

Vorteile:

  • Schnell umzusetzen
  • Semantisch korrekt

Nachteile:

  • Bedenken hinsichtlich der Zugänglichkeit
  • Text nicht wählbar
  • Viel Aufwand beim Überschreiben von Stilen, die Sie für Ihre Standardlinks verwendet haben

Die JavaScript-Methode

Mit JavaScript können wir einen Link zu unserer Karte hinzufügen, anstatt ihn in das Markup zu schreiben. Ich habe diese großartige CodePen-Demo von gefunden Kostenentwicklung der dabei auch den Kartentext auswählbar gemacht hat:

Dieser Ansatz hat viele Vorteile. Unsere Links sind fokussiert zugänglich und wir können sogar Text auswählen. Aber es gibt einige Nachteile, wenn es ums Styling geht. Wenn wir diese Karten zum Beispiel animieren wollen, müssten wir hinzufügen :hover Stile auf unserer Haupt .card Wrapper anstelle des Links selbst. Wir würden auch nicht von den Animationen profitieren, wenn die Links durch Tastaturtabbing im Fokus sind.

Vorteile:

  • Kann perfekt zugänglich gemacht werden
  • Fähigkeit, Text auszuwählen

Nachteile:

  • Erfordert JavaScript
  • Rechtsklick nicht möglich (könnte aber mit zusätzlichem Scripting behoben werden)
  • Erfordert viel Styling auf der Karte selbst, was beim Fokussieren des Links nicht funktionieren würde

Das ::after Selektor-Ansatz

Bei dieser Methode müssen wir die Karte mit relativer Positionierung einstellen und dann die absolute Positionierung auf den Links einstellen ::after Pseudoselektor eines Links. Dies erfordert kein JavaScript und ist ziemlich einfach zu implementieren:

Hier gibt es ein paar Abstriche, vor allem bei der Textauswahl. Wenn Sie keinen höheren Z-Index auf Ihrem Kartenkörper angeben, können Sie keinen Text auswählen, aber wenn Sie dies tun, seien Sie gewarnt, dass das Klicken auf den Text Ihren Link nicht aktiviert. Ob Sie wählbaren Text wünschen oder nicht, bleibt Ihnen überlassen. Ich denke, es kann ein UX-Problem sein, aber es hängt vom Anwendungsfall ab. Der Text ist immer noch für Screenreader zugänglich, aber mein Hauptproblem mit der Methode sind die fehlenden Animationsmöglichkeiten.

Vorteile:

  • Einfach zu implementieren
  • Zugänglicher Link ohne aufgeblähten Text
  • Funktioniert beim Schweben und Fokussieren

Nachteile:

  • Text ist nicht wählbar
  • Sie können den Link nur animieren, da dies das Element ist, über das Sie schweben.

Ein neuer Ansatz: Using ::after mit :has()

Nachdem wir nun die bestehenden Ansätze für anklickbare Karten etabliert haben, möchte ich die Einführung zeigen :has() to the mix behebt die meisten dieser Mängel.

Lassen Sie uns diesen Ansatz auf den letzten Ansatz stützen, den wir uns angesehen haben ::after auf dem Link-Element. Wir können tatsächlich verwenden :has() um die Animationseinschränkungen dieses Ansatzes zu überwinden.

Beginnen wir mit dem Markup:

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.

Ich werde die Dinge so einfach wie möglich halten, indem ich auf Elemente im CSS statt auf Klassen abziele.

Für diese Demo fügen wir der Karte beim Hover einen Bildzoom und einen Schatten hinzu und animieren den Link mit einem Pfeil, der auftaucht, und ändern gleichzeitig die Textfarbe des Links. Um dies zu vereinfachen, fügen wir einige benutzerdefinierte Eigenschaften hinzu, die auf unserer Karte liegen. Hier ist das grundlegende Styling:

/* 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;
}

Groß! Wir haben eine Anfangsskalierung für das Bild hinzugefügt (--img-scale: 1.001), die Anfangsfarbe der Kartenüberschrift (--title-color: black) und einige zusätzliche Eigenschaften, die wir verwenden werden, damit unser Pfeil aus dem Link herausspringt. Wir haben auch einen leeren Zustand von gesetzt box-shadow Deklaration , um sie später zu animieren . Dies richtet das ein, was wir jetzt für die anklickbare Karte benötigen. Fügen wir also einige Zurücksetzungen und Stile hinzu, indem wir diese benutzerdefinierten Eigenschaften zu den Elementen hinzufügen, die wir animieren möchten:

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;
}

Seien wir freundlich zu den Menschen und fügen Sie auch ein hinzu Screenreader-Klasse hinter dem Link versteckt:

.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;
}

Unsere Karte fängt an, ziemlich süß auszusehen. Es ist Zeit, ein bisschen Magie hinzuzufügen. Mit dem :has() Pseudo-Klasse können wir jetzt prüfen, ob unser Link schwebt oder fokussiert ist, dann unsere benutzerdefinierten Eigenschaften aktualisieren und eine hinzufügen box-shadow. Mit diesem kleinen Stück CSS erwacht unsere Karte wirklich zum Leben:

/* 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;
}

Sehen Sie, was da oben ist? Jetzt erhalten wir die aktualisierten Stile, wenn jedem Das untergeordnete Element in der Karte wird bewegt oder fokussiert. Und obwohl das Link-Element das einzige ist, das einen Schwebe- oder Fokuszustand in der enthalten kann ::after klickbarer Kartenansatz, können wir diesen verwenden, um das übergeordnete Element abzugleichen und die Übergänge anzuwenden.

Und da haben Sie es. Nur ein weiterer leistungsstarker Anwendungsfall für die :has() Wähler. Wir können nicht nur ein übergeordnetes Element abgleichen, indem wir andere Elemente als Argumente deklarieren, sondern wir können auch Pseudos verwenden, um Eltern abzugleichen und zu formatieren.

Vorteile:

  • Für alle
  • Animierbar
  • Kein JavaScript erforderlich
  • Verwendung :hover auf das richtige Element

Nachteile:

  • Text ist nicht einfach auswählbar.
  • Die Browserunterstützung ist auf Chrome und Safari beschränkt (wird in Firefox hinter einem Flag unterstützt).

Hier ist eine Demo mit dieser Technik. Sie bemerken vielleicht eine zusätzliche Verpackung um die Karte, aber damit spiele ich nur herum Containerabfragen, was nur eines dieser anderen fantastischen Dinge ist, die in allen gängigen Browsern eingeführt werden.

Ich habe welche andere Beispiele Sie möchten teilen? Andere Lösungen oder Ideen sind im Kommentarbereich mehr als willkommen.

Zeitstempel:

Mehr von CSS-Tricks