Oprettelse af animerede, klikbare kort med :has() Relationel Pseudo Class PlatoBlockchain Data Intelligence. Lodret søgning. Ai.

Oprettelse af animerede, klikbare kort med :has() Relational Pseudo Class

CSS :has() pseudo klasse ruller ud i mange browsere med Chrome , Safari allerede fuldt ud støtter det. Det omtales ofte som "forældrevælgeren" - som i, vi kan vælge stil et overordnet element fra en underordnet vælger - men der er så meget mere, at :has() kan hjælpe os med at løse. En af disse ting er at genopfinde det klikbare kortmønster, som mange af os elsker at bruge fra tid til anden.

Vi tager et kig på hvordan :has() kan hjælpe os med at håndtere linkede kort, men først...

Hvad er dette :has() pseudo klasse?

Der er allerede en flok of stor indlæg flyder rundt der gør et fremragende stykke arbejde med at forklare hvad :has() er og hvad det bruges til, men det er stadig nyt nok til, at vi også burde sige et par ord om det her.

:has() er en relationel pseudoklasse, der er en del af W3C Selectors Level 4 arbejdsudkast. Det er, hvad parenteserne handler om: matchende elementer, der er relateret til - eller mere præcist, indeholder - visse underordnede elementer.

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

Så du kan se, hvorfor vi måske vil kalde det en "forældre"-vælger. Men vi kan også kombinere det med andre funktionelle pseudoklasser for at blive mere specifik. Sig, at vi vil style artikler, der gør ikke indeholde eventuelle billeder. Vi kan kombinere de relationelle kræfter af :has() med negationsbeføjelserne :not() at gøre det:

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

Men det er kun begyndelsen på, hvordan vi kan kombinere kræfter til at gøre mere med :has(). Inden vi retter os specifikt mod at løse problemet med klikbare kort, lad os se på nogle få måder, vi i øjeblikket nærmer os dem uden at bruge :has().

Hvordan vi i øjeblikket håndterer klikbare kort

Der er tre hovedtilgange til, hvordan folk opretter et fuldt klikbart kort i disse dage, og for fuldt ud at forstå styrken af ​​denne pseudo-klasse, er det rart at have lidt af en runde.

Denne tilgang er noget, der bruges ret ofte. Jeg bruger aldrig denne tilgang, men jeg lavede en hurtig demo for at demonstrere det:

Der er mange bekymringer her, især når det kommer til tilgængelighed. Når brugere navigerer på din hjemmeside vha rotorfunktionen, vil de høre den fulde tekst inde i det element — overskriften, teksten og linket. Nogen vil måske ikke sidde igennem alt det. Vi kan gøre det bedre. Siden HTML5 kan vi indlejre blokelementer inde i en element. Men det føles aldrig rigtigt for mig, især ikke af denne grund.

Fordele:

  • Hurtig at implementere
  • Semantisk korrekt

Ulemper:

  • Bekymringer om tilgængelighed
  • Tekst kan ikke vælges
  • En masse besvær med at overskrive stilarter, som du brugte på dine standardlinks

JavaScript-metoden

Ved hjælp af JavaScript kan vi vedhæfte et link til vores kort i stedet for at skrive det i opmærkningen. Jeg fandt denne fantastiske CodePen-demo af costdev som også gjorde kortteksten valgbar i processen:

Denne tilgang har mange fordele. Vores links er tilgængelige på fokus, og vi kan endda vælge tekst. Men der er nogle ulemper, når det kommer til styling. Hvis vi for eksempel vil animere disse kort, skal vi tilføje :hover stilarter på vores hoved .card wrapper i stedet for selve linket. Vi ville heller ikke have gavn af animationerne, når linkene er i fokus fra tastaturtabning.

Fordele:

  • Kan gøres perfekt tilgængelig
  • Mulighed for at vælge tekst

Ulemper:

  • Kræver JavaScript
  • Højreklik er ikke muligt (selv om det kunne løses med noget ekstra scripting)
  • Vil kræve en masse styling på selve kortet, hvilket ikke ville fungere, når du fokuserer linket

::after vælgertilgang

Denne metode kræver, at vi indstiller kortet med relativ positionering og derefter indstiller absolut positionering på linkets ::after pseudovælger af et link. Dette kræver ikke noget JavaScript og er ret nemt at implementere:

Der er et par ulemper her, især når det kommer til at vælge tekst. Medmindre du angiver et højere z-indeks på din korttekst, vil du ikke være i stand til at vælge tekst, men hvis du gør det, skal du blive advaret om, at et klik på teksten ikke vil aktivere dit link. Hvorvidt du ønsker valgbar tekst er op til dig. Jeg tror, ​​det kan være et UX-problem, men det afhænger af use-casen. Teksten er stadig tilgængelig for skærmlæsere, men mit største problem med metoden er manglen på animationsmuligheder.

Fordele:

  • Let at implementere
  • Tilgængeligt link uden oppustet tekst
  • Arbejder på svæv og fokus

Ulemper:

  • Tekst kan ikke vælges
  • Du kan kun animere linket, da dette er det element, du svæver over.

En ny tilgang: Brug ::after med :has()

Nu hvor vi har etableret de eksisterende tilgange til klikbare kort, vil jeg vise, hvordan introducerende :has() til blandingen løser de fleste af disse mangler.

Faktisk, lad os basere denne tilgang på den sidste, vi så på at bruge ::after på linkelementet. Vi kan faktisk bruge :has() der for at overvinde den tilgangs animationsbegrænsninger.

Lad os starte med markeringen:

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.

Jeg vil holde tingene så enkle som muligt ved at målrette elementer i CSS i stedet for klasser.

Til denne demo vil vi tilføje en billedzoom og skygge til kortet, når du svæver, og animere linket med en pil, der popper op, og mens du ændrer linkets tekstfarve. For at gøre dette nemt vil vi tilføje nogle brugerdefinerede egenskaber på vores kort. Her er den grundlæggende 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;
}

Store! Vi tilføjede en indledende skala for billedet (--img-scale: 1.001), den indledende farve på kortets overskrift (--title-color: black) og nogle ekstra egenskaber, vi vil bruge til at få vores pil til at springe ud af linket. Vi har også indstillet en tom tilstand for box-shadow erklæring for at animere den senere. Dette sætter det op, vi har brug for til det klikbare kort lige nu, så lad os tilføje nogle nulstillinger og styling til det ved at tilføje disse brugerdefinerede egenskaber til de elementer, vi vil animere:

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

Lad os være venlige over for folk og også tilføje en skærmlæser klasse skjult bag linket:

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

Vores kort begynder at se ret sødt ud. Det er tid til at tilføje lidt magi til det. Med :has() pseudo klasse, kan vi nu kontrollere, om vores link er svævet eller fokuseret, og derefter opdatere vores tilpassede egenskaber og tilføje en box-shadow. Med denne lille del af CSS kommer vores kort virkelig til live:

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

Se hvad der er deroppe? Nu får vi de opdaterede styles if enhver underordnet element i kortet er svævet eller fokuseret. Og selvom linkelementet er det eneste, der kan indeholde en hover- eller fokustilstand i ::after klikbare korttilgang, kan vi bruge det til at matche det overordnede element og anvende overgangene.

Og der har du det. Bare endnu en kraftfuld use case til :has() vælger. Ikke alene kan vi matche et overordnet element ved at erklære andre elementer som argumenter, men vi kan også matche bruge pseudoer til at matche og style forældre.

Fordele:

  • Accessible
  • Animerbar
  • Der er ikke behov for JavaScript
  • Du bruger :hover på det rigtige element

Ulemper:

  • Tekst er ikke let at vælge.
  • Browserunderstøttelse er begrænset til Chrome og Safari (det understøttes i Firefox bag et flag).

Her er en demo, der bruger denne teknik. Du kan måske bemærke en ekstra indpakning omkring kortet, men det er bare mig, der leger med containerforespørgsler, som bare er en af ​​de andre fantastiske ting, der ruller ud i alle større browsere.

Fik nogle andre eksempler vil du dele? Andre løsninger eller ideer er mere end velkomne i kommentarfeltet.

Tidsstempel:

Mere fra CSS-tricks