Creazione di un componente di scorrimento dei contenuti multimediali

Una panoramica di base su come creare una visualizzazione a scorrimento orizzontale reattiva per TV, smartphone, computer e così via.

In questo post voglio condividere alcune idee su come creare esperienze di scorrimento orizzontale per il web che siano minimaliste, reattive, accessibili e funzionino su browser e piattaforme (come le TV). Prova la demo.

Demo

Se preferisci i video, ecco una versione di questo post su YouTube:

Panoramica

Creeremo un layout a scorrimento orizzontale pensato per ospitare le miniature di contenuti multimediali o prodotti. Il componente inizia come un semplice elenco <ul>, ma viene trasformato con CSS in un'esperienza di scorrimento soddisfacente e fluida, che mostra le immagini e le aggancia a una griglia. JavaScript viene aggiunto per facilitare le interazioni con l'indice mobile, aiutando gli utenti della tastiera a evitare di attraversare più di 100 elementi. Inoltre, viene utilizzata una media query sperimentale, prefers-reduced-data, per trasformare lo scorrimento dei contenuti multimediali in un'esperienza di scorrimento dei titoli leggera.

Inizia con il markup accessibile

Uno scorrimento multimediale è composto da un paio di componenti principali, un elenco con elementi. Una lista, nella sua forma più semplice, può viaggiare in tutto il mondo ed essere chiaramente compresa da tutti. Un utente che arriva a questa pagina può sfogliare un elenco e fare clic su un link per visualizzare un articolo. Questa è la nostra base accessibile.

Fornisci un elenco con un elemento <ul>:

<ul class="horizontal-media-scroller">
  <li></li>
  <li></li>
  <li></li>
  ...
<ul>

Rendi interattivi gli elementi dell'elenco con un elemento <a>:

<li>
  <a href="#">
    ...
  </a>
</li>

Utilizza un elemento <figure> per rappresentare semanticamente un'immagine e la relativa didascalia:

<figure>
  <picture>
    <img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
  </picture>
  <figcaption>Legends</figcaption>
</figure>

Nota gli attributi alt e loading in <img>. Il testo alternativo per uno scroller multimediale è un'opportunità UX per fornire un contesto aggiuntivo alla miniatura o come testo di riserva se l'immagine non è stata caricata. Inoltre, fornisce un'interfaccia utente vocale per gli utenti che si affidano a tecnologie assistive come uno screen reader. Scopri di più con le cinque regole d'oro per un testo alternativo conforme.

L'attributo loading accetta la parola chiave lazy per indicare che l'origine di questa immagine deve essere recuperata solo quando l'immagine si trova all'interno della finestra. Questa funzionalità può essere molto utile per gli elenchi di grandi dimensioni, in quanto gli utenti scaricheranno solo le immagini degli elementi che hanno visualizzato.

Supportare la preferenza della combinazione di colori dell'utente

Utilizza color-scheme come tag <meta> per segnalare al browser che la tua pagina vuole gli stili user agent forniti sia per la modalità Luce che per la modalità Buio. È una modalità Buio o una modalità Chiaro senza costi, a seconda di come la vedi:

<meta name="color-scheme" content="dark light">

Il metatag fornisce il segnale più tempestivo possibile, in modo che il browser possa selezionare un colore di sfondo scuro predefinito se l'utente ha una preferenza per il tema scuro. Ciò significa che la navigazione tra le pagine del sito non mostrerà uno sfondo bianco tra un caricamento e l'altro. Tema scuro fluido tra i caricamenti, molto più piacevole per gli occhi.

Scopri di più da Thomas Steiner all'indirizzo https://web.dev/color-scheme/.

Aggiungi contenuti

Data la struttura dei contenuti di ul > li > a > figure > picture > img riportata sopra, il passaggio successivo consiste nell'aggiungere immagini e titoli da scorrere. Ho inserito nella demo immagini e testo segnaposto statici, ma puoi utilizzare la tua origine dati preferita.

Aggiungere stile con CSS

Ora è il momento che il CSS prenda questo elenco generico di contenuti e lo trasformi in un'esperienza. Netflix, gli app store e molti altri siti e app utilizzano aree di scorrimento orizzontale per riempire il riquadro con categorie e opzioni.

Creazione del layout dello scorrimento

È importante evitare di tagliare i contenuti nei layout o di affidarsi al troncamento del testo con i puntini di sospensione. Molti televisori hanno dei selettori multimediali come questo, ma troppo spesso ricorrono all'ellissi per i contenuti. Questo layout no. Consente inoltre ai contenuti multimediali di ignorare le dimensioni della colonna, rendendo un layout abbastanza flessibile da gestire molte combinazioni interessanti.

2
righe scorrevoli mostrate. Una non ha puntini di sospensione, il che significa che è più alta e ogni
titolo è completamente leggibile. L&#39;altro è più corto e molti titoli sono troncati con
i puntini di sospensione.

Il contenitore consente di ignorare le dimensioni della colonna fornendo le dimensioni predefinite come proprietà personalizzata. Questo layout a griglia è orientato alle dimensioni delle colonne, in quanto gestisce solo la spaziatura e la direzione:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2); /* parent owned value for children to be relative to*/
  margin: 0;
}

La proprietà personalizzata viene quindi utilizzata dall'elemento <picture> per creare le proporzioni di base: un riquadro:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  & picture {
    inline-size: var(--size);
    block-size: var(--size);
  }
}

Con solo alcuni stili secondari, completa la struttura di base dello scorrimento dei contenuti multimediali:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  & > li {
    display: inline-block; /* removes the list-item bullet */
  }

  & picture {
    inline-size: var(--size);
    block-size: var(--size);
  }
}

L'impostazione overflow configura <ul> in modo da consentire lo scorrimento e la navigazione da tastiera nell'elenco, quindi a ogni elemento secondario diretto <li> viene rimosso ::marker assegnando un nuovo tipo di visualizzazione inline-block.

Le immagini non sono ancora responsive e escono direttamente dalle caselle in cui si trovano. Domali con dimensioni, adattamento e stili del bordo e un gradiente di sfondo per il caricamento differito:

img {
  /* smash into whatever box it's in */
  inline-size: 100%;
  block-size: 100%;

  /* don't squish but do cover the space */
  object-fit: cover;

  /* soften the edges */
  border-radius: 1ex;
  overflow: hidden;

  /* if empty, show a gradient placeholder */
  background-image:
    linear-gradient(
      to bottom,
      hsl(0 0% 40%),
      hsl(0 0% 20%)
    );
}

Spaziatura interna di scorrimento

L'allineamento ai contenuti della pagina e una superficie di scorrimento da bordo a bordo sono fondamentali per un componente armonioso e minimalista.

Per ottenere il layout di scorrimento da bordo a bordo in linea con la nostra tipografia e le nostre linee di layout, utilizza padding che corrisponde a scroll-padding:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  padding-inline: var(--gap);
  scroll-padding-inline: var(--gap);
  padding-block: calc(var(--gap) / 2); /* make space for scrollbar and focus outline */
}

Correzione del bug del padding di scorrimento orizzontale L'esempio precedente mostra la facilità con cui è possibile aggiungere padding a un contenitore di scorrimento, ma esistono problemi di compatibilità in sospeso (risolti in Chromium 91 e versioni successive). Consulta questa pagina per un po' di storia, ma la versione breve è che il padding non è sempre stato preso in considerazione in una visualizzazione a scorrimento.

Una
casella è evidenziata sul lato finale in linea dell&#39;ultimo elemento dell&#39;elenco, mostrando che
il padding e l&#39;elemento hanno la stessa larghezza per creare l&#39;allineamento desiderato.

Per indurre i browser a inserire il padding alla fine dello scorrimento, selezionerò l'ultima cifra di ogni elenco e aggiungerò uno pseudo elemento che corrisponde alla quantità di padding desiderata.

.horizontal-media-scroller > li:last-of-type figure {
  position: relative;

  &::after {
    content: "";
    position: absolute;

    inline-size: var(--gap);
    block-size: 100%;

    inset-block-start: 0;
    inset-inline-end: calc(var(--gap) * -1);
  }
}

L'utilizzo di proprietà logiche consente allo scorrimento dei contenuti multimediali di funzionare in qualsiasi modalità di scrittura e direzione del documento.

Allineamento dello scorrimento

Un contenitore scorrevole con overflow può diventare una finestra di visualizzazione con snapping con una riga di CSS, quindi spetta ai figli specificare come vogliono allinearsi a quella finestra di visualizzazione.

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  padding-inline: var(--gap);
  scroll-padding-inline: var(--gap);
  padding-block-end: calc(var(--gap) / 2);

  scroll-snap-type: inline mandatory;

  & figure {
    scroll-snap-align: start;
  }
}

Concentrazione

L'ispirazione per questo componente deriva dalla sua enorme popolarità su TV, store di app e altro ancora. Molte piattaforme di videogiochi utilizzano uno scorrimento dei contenuti multimediali molto simile a questo come layout principale della schermata Home. La messa a fuoco è un elemento fondamentale dell'esperienza utente, non solo una piccola aggiunta. Immagina di utilizzare questo selettore multimediale dal divano con un telecomando e di apportare alcuni piccoli miglioramenti all'interazione:

.horizontal-media-scroller a {
  outline-offset: 12px;

  &:focus {
    outline-offset: 7px;
  }

  @media (prefers-reduced-motion: no-preference) {
    & {
      transition: outline-offset .25s ease;
    }
  }
}

In questo modo, lo stile del contorno della messa a fuoco 7px viene spostato lontano dalla casella, lasciando un po' di spazio. Se l'utente non ha preferenze di movimento per la riduzione del movimento, l'offset viene spostato, dando un movimento sottile all'evento di messa a fuoco.

Indice mobile

Gli utenti di gamepad e tastiera richiedono un'attenzione particolare in queste lunghe liste di contenuti e opzioni scorrevoli. Il modello comune per risolvere questo problema è chiamato indice mobile. Si verifica quando un contenitore di elementi è attivo con la tastiera, ma solo un elemento secondario può essere attivo alla volta. Questa esperienza di messa a fuoco di un solo elemento alla volta è progettata per consentire di ignorare l'elenco potenzialmente lungo di elementi, anziché premere il tasto Tab più di 50 volte per raggiungere la fine.

Nel primo scroller della demo ci sono 300 elementi. Possiamo fare di meglio che farli attraversare tutte le sezioni per raggiungere quella successiva.

Per creare questa esperienza, JavaScript deve osservare gli eventi della tastiera e gli eventi di messa a fuoco. Ho creato una piccola libreria open source su npm per semplificare questa esperienza utente. Ecco come utilizzarlo per i tre selettori:

import {rovingIndex} from 'roving-ux';

rovingIndex({
  element: someElement
});

Questa demo esegue query sul documento per gli scorrimenti e per ognuno di essi chiama la funzione rovingIndex(). Passa rovingIndex() all'elemento per ottenere l'esperienza di spostamento dello stato attivo, come un contenitore di elenco, e un selettore di query di destinazione, nel caso in cui i target dello stato attivo non siano discendenti diretti.

document.querySelectorAll('.horizontal-media-scroller')
  .forEach(scroller =>
    rovingIndex({
      element: scroller,
      target: 'a',
}))

Per saperne di più su questo effetto, consulta la libreria open source roving-ux.

Proporzioni

Al momento della stesura di questo post, il supporto di aspect-ratio è disponibile in Firefox tramite un flag, ma è disponibile nei browser Chromium o nei set-top box. Poiché il layout a griglia dello scorrimento dei contenuti multimediali specifica solo la direzione e la spaziatura, le dimensioni possono cambiare all'interno di una media query, la cui funzionalità verifica il supporto delle proporzioni. Miglioramento progressivo di alcuni scorrimenti di contenuti multimediali più dinamici.

Accanto alle altre proporzioni di progettazione utilizzate di 16:9 e 4:3 viene mostrato un
riquadro con proporzioni 4:4.

@supports (aspect-ratio: 1) {
  .horizontal-media-scroller figure > picture {
    inline-size: auto; /* for a block-size driven ratio */
    aspect-ratio: 1; /* boxes by default */

    @nest section:nth-child(2) & {
      aspect-ratio: 16/9;
    }

    @nest section:nth-child(3) & {
      /* double the size of the others */
      block-size: calc(var(--size) * 2);
      aspect-ratio: 4/3;

      /* adjust size to fit more items into the viewport */
      @media (width <= 480px) {
        block-size: calc(var(--size) * 1.5);
      }
    }
  }
}

Se il browser supporta la sintassi aspect-ratio, le immagini dello scorrimento dei contenuti multimediali vengono aggiornate al dimensionamento aspect-ratio. Utilizzando la sintassi di nidificazione delle bozze, ogni immagine cambia le proporzioni a seconda che si trovi nella prima, nella seconda o nella terza riga. La sintassi nidificata consente anche di impostare piccoli aggiustamenti della finestra, insieme all'altra logica di dimensionamento.

Con questo CSS, man mano che la funzionalità sarà disponibile in più motori del browser, verrà visualizzato un layout facile da gestire ma più accattivante dal punto di vista visivo.

Preferenza per la riduzione dei dati

Anche se questa tecnica è disponibile solo dietro un flag in Canary, volevo condividere come ho potuto risparmiare una notevole quantità di tempo di caricamento della pagina e di utilizzo dei dati con poche righe di CSS. La media query prefers-reduced-data del livello 5 consente di verificare se il dispositivo si trova in uno stato di riduzione dei dati, ad esempio una modalità di risparmio dati. Se è così, posso modificare il documento e, in questo caso, nascondere le immagini.

ALT_TEXT_HERE

figure {
  @media (prefers-reduced-data: reduce) {
    & {
      min-inline-size: var(--size);

      & > picture {
        display: none;
      }
    }
  }
}

I contenuti sono ancora navigabili, ma senza il costo del download delle immagini pesanti. Ecco il sito prima di aggiungere il CSS prefers-reduced-data:

(7 richieste, 100 KB di risorse in 131 ms)

ALT_TEXT_HERE

Ecco il rendimento del sito dopo l'aggiunta del CSS prefers-reduced-data:

ALT_TEXT_HERE

(71 richieste, 1,2 MB di risorse in 1,07 secondi)

64 richieste in meno, ovvero circa 60 immagini all'interno del riquadro visibile (test eseguiti su un display widescreen) di questa scheda del browser, un aumento del caricamento della pagina di circa l'80% e il 10% dei dati via cavo. CSS piuttosto potente.

Conclusione

Ora che sai come ho fatto, come faresti tu? 🙂

Diversifichiamo i nostri approcci e impariamo tutti i modi per creare sul web. Crea un Codepen o ospita la tua demo, inviami un tweet e la aggiungerò alla sezione Remix della community di seguito.

Origine

Remix della community

Ancora nessun elemento da visualizzare.