Creazione di un componente scroller multimediale

Una panoramica di base su come creare una visualizzazione della scheda orizzontale adattabile per TV, telefoni, computer e così via.

In questo post voglio condividere alcune idee su come creare esperienze di scorrimento orizzontale per il web che siano minimali, responsive, accessibili e che 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

Stiamo creando un layout di scorrimento orizzontale pensato per ospitare 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 inserisce in una griglia. JavaScript viene aggiunto per semplificare le interazioni con l'indice mobile, aiutando gli utenti che utilizzano la tastiera a saltare la visualizzazione di più di 100 elementi. Inoltre, una query multimediale sperimentale, prefers-reduced-data, viene utilizzata per trasformare lo scorrimento dei contenuti multimediali in un'esperienza di scorrimento dei titoli leggera.

Inizia con il markup accessibile

Uno scroller multimediale è composto da solo un paio di componenti principali, un elenco con elementi. Un elenco, nella sua forma più semplice, può viaggiare in tutto il mondo ed essere consumato da tutti in modo chiaro. 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.

Pubblica 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>

Tieni presente gli attributi alt e loading in <img>. Il testo alternativo per un visualizzatore di contenuti multimediali è un'opportunità di UX per fornire un contesto aggiuntivo alla miniatura o come testo di riserva se l'immagine non è stata caricata oppure fornisce un'interfaccia utente vocale per gli utenti che si affidano a tecnologie per la disabilità 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 questa fonte di immagini deve essere recuperata solo quando l'immagine è all'interno dell'area visibile. Questa opzione può essere molto utile per gli elenchi di grandi dimensioni, in quanto gli utenti scaricheranno le immagini solo per gli elementi visualizzati scorrendo.

Supportare la preferenza della combinazione di colori dell'utente

Utilizza color-scheme come tag <meta> per indicare al browser che la tua pagina richiede gli stili dell'agente utente sia chiaro che scuro. È una modalità Buio o chiara senza costi, a seconda dei punti di vista:

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

Il metatag fornisce l'indicatore più precoce possibile, in modo che il browser possa selezionare un colore della tela predefinito scuro se l'utente ha una preferenza per il tema scuro. Ciò significa che le navigazioni tra le pagine del sito non mostreranno un sfondo canvas bianco tra un caricamento e l'altro. Tema scuro senza interruzioni 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, la prossima attività consiste nell'aggiungere immagini e titoli da scorrere. Ho incluso nella demo immagini e testo segnaposto statici, ma non esitare a utilizzare la tua origine dati preferita.

Aggiungere uno stile con CSS

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

Creazione del layout dello scorrimento

È importante evitare di tagliare i contenuti nei layout o di ricorrere alla troncatura del testo con i puntini di sospensione. Molti televisori hanno cursori multimediali come questo, ma troppo spesso ricorrono all'elisione dei contenuti. Questo layout non lo fa. Inoltre, consente ai contenuti multimediali di ignorare le dimensioni della colonna, rendendo un layout sufficientemente flessibile da gestire molte combinazioni interessanti.

2
righe scorrevoli mostrate. Uno non ha l&#39;elipsis, il che significa che è più alto e ogni
titolo è completamente leggibile. L&#39;altra è più breve e molti titoli sono tagliati con i puntini di sospensione.

Il contenitore consente di ignorare la dimensione della colonna specificando la dimensione predefinita come proprietà personalizzata. Questo layout della griglia è vincolato per le dimensioni delle colonne, ma 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 poi utilizzata dall'elemento <picture> per creare il formato base: una casella:

.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 qualche altro stile secondario, 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 con la tastiera tra gli elementi dell'elenco. Poi, a ogni elemento <li> secondario diretto viene rimosso ::marker, ottenendo un nuovo tipo di visualizzazione inline-block.

Tuttavia, le immagini non sono ancora responsive e appaiono fuori dalle scatole in cui si trovano. Regolale con alcune dimensioni, adattamenti e stili di bordi, nonché con 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 scorrimento

L'allineamento ai contenuti della pagina, oltre a una superficie di scorrimento da un lato all'altro, sono fondamentali per un componente armonioso e minimalista.

Per ottenere il layout di scorrimento da un lato all'altro in linea con la nostra tipografia e le 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 di un bug relativo al padding dello scorrimento orizzontale L'esempio riportato sopra mostra quanto dovrebbe essere facile inserire un padding in un contenitore con scorrimento, ma ci sono problemi di compatibilità in sospeso (risolti in Chromium 91 e versioni successive). Visita questa pagina per approfondire la cronologia, ma in breve: il padding non veniva sempre preso in considerazione in una visualizzazione a scorrimento.

Sul lato inline-end dell&#39;ultimo elemento dell&#39;elenco viene evidenziata una casella che mostra che il padding e l&#39;elemento hanno la stessa larghezza per creare l&#39;allineamento desiderato.

Per ingannare i browser e far sì che inseriscano il padding alla fine dello scorrimento, scelgo come target l'ultima figura di ogni elenco e aggiungo uno pseudo elemento che corrisponde alla quantità di spaziatura interna 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 con scorrimento e overflow può diventare un viewport con snap con una riga di CSS, quindi è compito dei figli specificare come allinearsi a quel viewport.

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

Focus

L'ispirazione per questo componente deriva dalla sua enorme popolarità su TV, App Store e altro ancora. Molte piattaforme di videogiochi utilizzano un selettore di contenuti multimediali molto simile a questo come layout principale della schermata Home. La funzionalità di messa a fuoco è un aspetto fondamentale dell'esperienza utente, non solo un piccolo miglioramento. Immagina di utilizzare questo cursore dei contenuti multimediali dal divano con un telecomando, apporta 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 di messa a fuoco 7px viene allontanato dalla casella, lasciando un po' di spazio. Se l'utente non ha preferenze relative alla riduzione del movimento, viene applicata una transizione all'offset, che conferisce un movimento impercettibile all'evento di messa a fuoco.

Indice mobile

Gli utenti di gamepad e tastiera richiedono un'attenzione speciale in questi lunghi elenchi di contenuti e opzioni scorrevoli. Il pattern comune per risolvere questo problema è chiamato indice mobile. Si verifica quando un contenutore di elementi è attivo con la tastiera, ma è consentito attivare solo un elemento secondario alla volta. Questa esperienza che consente di mettere a fuoco un solo elemento alla volta è progettata per consentire di aggirare l'elenco potenzialmente lungo di elementi, anziché premere Tab più di 50 volte per raggiungere la fine.

Il primo scroller della demo contiene 300 elementi. Possiamo fare di più che farli percorrere tutte per raggiungere la sezione successiva.

Per creare questa esperienza, JavaScript deve osservare gli eventi relativi alla tastiera e allo stato attivo. Ho creato una piccola libreria open source su npm per contribuire a semplificare la realizzazione di questa esperienza utente. Ecco come utilizzarlo per i tre scorrevoli:

import {rovingIndex} from 'roving-ux';

rovingIndex({
  element: someElement
});

Questa demo esegue una query nel documento per gli scorrevoli e per ciascuno di essi chiama la funzione rovingIndex(). Passa l'elemento rovingIndex() per ottenere l'esperienza di navigazione, ad esempio un contenitore di elenchi, e un selettore di query target, nel caso in cui i target di attenzione 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 diaspect-ratio è dietro un flag in Firefox, ma è disponibile nei browser Chromium o nelle TV connesse a internet. Poiché il layout della griglia dello scorrimento dei contenuti multimediali specifica solo la direzione e la spaziatura, le dimensioni possono cambiare all'interno di una query sui contenuti multimediali che verifica il supporto del formato. Miglioramento progressivo di alcuni scorrevoli dei contenuti multimediali più dinamici.

Accanto alle altre proporzioni di design utilizzate, 16:9 e 4:3, viene visualizzata una casella 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 alle dimensioni aspect-ratio. Utilizzando la sintassi di nidificazione della bozza, ogni immagine cambia le proprie proporzioni a seconda che si tratti della prima, della seconda o della terza riga. La sintassi nidificata consente anche di impostare alcuni piccoli aggiustamenti del viewport, insieme all'altra logica di dimensionamento.

Con questo CSS, poiché la funzionalità è disponibile in più motori di browser, verrà visualizzato un layout facile da gestire, ma più accattivante dal punto di vista visivo.

Preferisce dati ridotti

Anche se questa tecnica è disponibile solo dietro un flag in Canary, volevo condividere come ho potuto risparmiare una quantità considerevole di tempo di caricamento della pagina e utilizzo dei dati con poche righe di CSS. La query media prefers-reduced-data del livello 5 consente di chiedere se il dispositivo è in qualsiasi stato di dati ridotti, ad esempio una modalità di risparmio dati. In questo caso, posso modificare il documento e 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 di grandi dimensioni. Ecco il sito prima dell'aggiunta del 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 s)

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

Conclusione

Ora che sai come ho fatto, come faresti? 🙂

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.