Creazione di carte animate e cliccabili con la pseudo classe relazionale :has() PlatoBlockchain Data Intelligence. Ricerca verticale. Ai.

Creazione di carte animate cliccabili con la classe pseudo relazionale :has()

Il CSS :has() pseudo class è in fase di implementazione in molti browser con Chrome ed Safari già lo sostiene pienamente. Viene spesso definito "il selettore genitore" - nel senso che possiamo selezionare lo stile di un elemento genitore da un selettore figlio - ma c'è molto di più :has() può aiutarci a risolvere. Una di queste cose è reinventare il modello di carte cliccabili che molti di noi amano usare di tanto in tanto.

Daremo un'occhiata a come :has() può aiutarci a gestire le carte collegate, ma prima...

Cos'è questo :has() pseudoclasse?

Esiste già un file mazzo of grande correlati fluttuando che fanno un ottimo lavoro spiegando cosa :has() cos'è e a cosa serve, ma è ancora abbastanza nuovo che dovremmo spendere qualche parola al riguardo anche qui.

:has() è una pseudo classe relazionale che fa parte di Bozza di lavoro dei selettori W3C di livello 4. Questo è lo scopo delle parentesi: elementi corrispondenti che sono correlati a (o, più precisamente, contengono) determinati elementi figlio.

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

Quindi puoi capire perché potremmo chiamarlo un selettore “genitore”. Ma possiamo anche combinarlo con altre pseudo classi funzionali per essere più specifici. Supponiamo di voler stilare articoli che lo facciano non contenere immagini. Possiamo combinare i poteri relazionali di :has() con i poteri di negazione di :not() fare quello:

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

Ma questo è solo l’inizio di come possiamo combinare i poteri per fare di più :has(). Prima di dedicarci specificamente alla risoluzione dell'enigma delle carte cliccabili, diamo un'occhiata ad alcuni modi in cui attualmente li affrontiamo senza utilizzare :has().

Come gestiamo attualmente le carte cliccabili

Al giorno d'oggi ci sono tre approcci principali su come le persone creano una carta completamente cliccabile e per comprendere appieno il potere di questa pseudo classe, è bello avere un piccolo riassunto.

Questo approccio è qualcosa di usato abbastanza frequentemente. Non utilizzo mai questo approccio ma ho creato una breve demo per dimostrarlo:

Ci sono molte preoccupazioni qui, soprattutto quando si tratta di accessibilità. Quando gli utenti navigano nel tuo sito web utilizzando la funzione del rotore, ne ascolteranno il testo completo elemento: l'intestazione, il testo e il collegamento. Qualcuno potrebbe non voler sopportare tutto ciò. Possiamo fare di meglio. A partire da HTML5, possiamo nidificare elementi di blocco all'interno di un file elemento. Ma non mi sembra mai giusto, soprattutto per questo motivo.

PRO:

  • Veloce da implementare
  • Semanticamente corretto

Contro:

  • Problemi di accessibilità
  • Testo non selezionabile
  • Un sacco di problemi per sovrascrivere gli stili che hai utilizzato sui tuoi collegamenti predefiniti

Il metodo JavaScript

Utilizzando JavaScript, possiamo allegare un collegamento alla nostra carta invece di scriverlo nel markup. Ho trovato questa fantastica demo di CodePen di costdev che ha anche reso selezionabile il testo della carta nel processo:

Questo approccio ha molti vantaggi. I nostri collegamenti sono accessibili in primo piano e possiamo anche selezionare il testo. Ma ci sono alcuni inconvenienti quando si tratta di styling. Se vogliamo animare quelle carte, ad esempio, dovremmo aggiungere :hover stili sul nostro principale .card wrapper invece del collegamento stesso. Inoltre, non trarremmo vantaggio dalle animazioni quando i collegamenti sono messi a fuoco dalla tabulazione della tastiera.

PRO:

  • Può essere reso perfettamente accessibile
  • Possibilità di selezionare il testo

Contro:

  • Richiede JavaScript
  • Fare clic con il tasto destro non è possibile (anche se potrebbe essere risolto con alcuni script aggiuntivi)
  • Richiederà molto stile sulla carta stessa che non funzionerebbe quando si focalizza il collegamento

Il ::after approccio selettivo

Questo metodo richiede di impostare la scheda con il posizionamento relativo, quindi di impostare il posizionamento assoluto sui collegamenti ::after pseudo-selettore di un collegamento. Questo non richiede JavaScript ed è abbastanza facile da implementare:

Ci sono alcuni inconvenienti qui, soprattutto quando si tratta di selezionare il testo. A meno che tu non fornisca uno z-index più alto sul corpo della tua carta, non sarai in grado di selezionare il testo ma, se lo fai, tieni presente che facendo clic sul testo non si attiverà il collegamento. Dipende da te se vuoi o meno il testo selezionabile. Penso che possa essere un problema di UX, ma dipende dal caso d'uso. Il testo è ancora accessibile agli screen reader ma il mio problema principale con questo metodo è la mancanza di possibilità di animazione.

PRO:

  • Facile da implementare
  • Collegamento accessibile senza testo gonfio
  • Funziona al passaggio del mouse e alla messa a fuoco

Contro:

  • Il testo non è selezionabile
  • Puoi animare solo il collegamento poiché questo è l'elemento su cui stai passando il mouse.

Un nuovo approccio: Usare ::after con :has()

Ora che abbiamo stabilito gli approcci esistenti per le carte cliccabili, voglio mostrare come presentarli :has() al mix risolve la maggior parte di queste carenze.

In effetti, basiamo questo approccio sull’ultimo che abbiamo utilizzato ::after sull'elemento collegamento. Possiamo effettivamente utilizzare :has() lì per superare i vincoli di animazione di quell’approccio.

Cominciamo con il 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.

Manterrò le cose il più semplici possibile prendendo di mira gli elementi nel CSS anziché le classi.

Per questa demo, aggiungeremo uno zoom e un'ombra dell'immagine alla scheda al passaggio del mouse e animeremo il collegamento con una freccia che appare e cambiando il colore del testo del collegamento. Per semplificare, aggiungeremo alcune proprietà personalizzate con ambito sulla nostra scheda. Ecco lo stile di base:

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

Grande! Abbiamo aggiunto una scala iniziale per l'immagine (--img-scale: 1.001), il colore iniziale dell'intestazione della carta (--title-color: black) e alcune proprietà extra che utilizzeremo per far uscire la freccia dal collegamento. Abbiamo anche impostato uno stato vuoto del file box-shadow dichiarazione per animarla in seguito. Questo imposta ciò di cui abbiamo bisogno per la scheda cliccabile in questo momento, quindi aggiungiamo alcune reimpostazioni e stili aggiungendo quelle proprietà personalizzate agli elementi che vogliamo animare:

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

Cerchiamo di essere gentili con le persone e aggiungiamo anche a classe di lettura dello schermo nascosto dietro il link:

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

La nostra carta inizia a sembrare piuttosto carina. È ora di aggiungere un po’ di magia. Con il :has() pseudo classe, ora possiamo verificare se il nostro collegamento è al passaggio del mouse o focalizzato, quindi aggiornare le nostre proprietà personalizzate e aggiungere un file box-shadow. Con questo piccolo pezzo di CSS la nostra carta prende davvero vita:

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

Vedi cosa c'è lassù? Ora otteniamo gli stili aggiornati if in qualsiasi l'elemento figlio nella carta è posizionato o focalizzato. E anche se l'elemento link è l'unica cosa che può contenere uno stato hover o focus nel file ::after approccio con scheda cliccabile, possiamo usarlo per abbinare l'elemento genitore e applicare le transizioni.

E il gioco è fatto. Solo un altro potente caso d'uso per il :has() selettore. Non solo possiamo abbinare un elemento genitore dichiarando altri elementi come argomenti, ma possiamo anche usare pseudonimi per abbinare e dare stile anche ai genitori.

PRO:

  • Accessibile
  • Animabile
  • Non è necessario JavaScript
  • si utilizza :hover sull'elemento corretto

Contro:

  • Il testo non è facilmente selezionabile.
  • Il supporto del browser è limitato a Chrome e Safari (è supportato in Firefox dietro un flag).

Ecco una demo che utilizza questa tecnica. Potresti notare un involucro extra attorno alla carta, ma sto solo giocando query contenitore, che è solo una delle altre fantastiche funzionalità disponibili in tutti i principali browser.

Ho qualche altri esempi desideri condividere? Altre soluzioni o idee sono più che benvenute nella sezione commenti.

Timestamp:

Di più da Trucchi CSS