Creazione di un componente scroller multimediale

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

In questo post voglio condividere idee su come creare esperienze di scorrimento orizzontale sul web che siano minime, reattive, accessibili e funzionino su tutti i browser e le piattaforme (come la TV). Prova la demo.

Demo

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

Panoramica

Creeremo un layout di scorrimento orizzontale pensato per l'hosting di 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, mostrando le immagini e agganciandole a una griglia. JavaScript viene aggiunto per facilitare le interazioni con l'indice ininterrotto, aiutando gli utenti che usano la tastiera a evitare di attraversare più di 100 elementi. Inoltre, viene utilizzata una query supporti sperimentale, prefers-reduced-data, per trasformare lo scorrimento dei contenuti multimediali in un'esperienza di scorrimento dei titoli leggera.

Inizia con un markup accessibile

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

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

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

Osserva gli attributi alt e loading nella sezione <img>. Il testo alternativo di uno scorrimento multimediale è un'opportunità UX per aggiungere contesto alla miniatura oppure come testo di riserva se l'immagine non si carica oppure come testo di riserva per gli utenti che si affidano a tecnologie per la disabilità come uno screen reader. Per saperne di più, consulta le Cinque regole fondamentali per un testo alternativo conforme.

L'attributo loading accetta la parola chiave lazy come modo per indicare che l'origine dell'immagine deve essere recuperata solo quando l'immagine si trova all'interno dell'area visibile. Questo può essere molto utile per gli elenchi di grandi dimensioni, in quanto gli utenti scaricheranno solo le immagini degli elementi che hanno visualizzato.

Supporto della preferenza della combinazione di colori dell'utente

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

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

Il meta tag fornisce il primo indicatore possibile, quindi il browser può selezionare un colore canvas predefinito scuro se l'utente ha una preferenza per il tema scuro. Ciò significa che le navigazioni tra le pagine del sito non mostrano uno sfondo bianco tra i caricamenti. Tema scuro senza interruzioni tra i caricamenti, molto più bello per gli occhi.

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

Aggiungi contenuti

Data la struttura di contenuti di ul > li > a > figure > picture > img riportata in alto, la prossima attività è aggiungere immagini e titoli da scorrere. La demo contiene testo e immagini segnaposto statici, ma puoi comunque utilizzarla dall'origine dati preferita.

Aggiungi stile con CSS

È arrivato il momento che CSS trasformare questo elenco generico di contenuti in un'esperienza. Netflix, App Store e molti altri siti e app utilizzano le aree di scorrimento orizzontale per includere categorie e opzioni nell'area visibile.

Creazione del layout di scorrimento

È importante evitare di tagliare i contenuti nei layout o appoggiarsi al troncamento del testo con i puntini di sospensione. Molti televisori hanno dei rotoli di scorrimento come questo, ma troppo spesso ricorrono ai contenuti con puntini di sospensione. a differenza di questo layout. Inoltre, consente ai contenuti multimediali di sostituire le dimensioni della colonna, rendendo un solo layout abbastanza flessibile da gestire molte combinazioni interessanti.

2 righe di scorrimento mostrate. Uno non contiene i puntini di sospensione, il che significa che è più alto e ogni titolo è completamente leggibile. L&#39;altro è più breve e molti titoli sono troncati
dai puntini di sospensione.

Il contenitore consente di sostituire la dimensione della colonna fornendo la dimensione predefinita come proprietà personalizzata. Questo layout a griglia è basato sulle dimensioni delle colonne, gestisce solo spaziatura e 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 nostre 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 pochi stili minori, completa gli elementi essenziali 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);
  }
}

La configurazione di overflow consente di impostare <ul> in modo da consentire lo scorrimento e la navigazione da tastiera nell'elenco, quindi per ogni elemento <li> secondario diretto viene rimosso il valore ::marker tramite un nuovo tipo di visualizzazione inline-block.

Tuttavia, le immagini non sono ancora reattive e esplodono appena fuori dalle scatole che si trovano all'interno. Personalizzali con alcune dimensioni, stili e stili di bordi e un gradiente di sfondo per il caricamento lento:

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 e un'area di scorrimento da un lato all'altro sono fondamentali per creare componenti armoniosi e minimi.

Per ottenere il layout di scorrimento da un bordo all'altro in linea con le nostre linee tipografiche e di layout, usa 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 bug relativi alla spaziatura interna dello scorrimento orizzontale L'articolo riportato sopra mostra quanto sia facile inserire un contenitore di scorrimento, ma esistono problemi di compatibilità in sospeso con quest'ultimo (risolto in Chromium 91 e versioni successive). Consulta questa pagina per un po' di cronologia, ma la versione breve indica che la spaziatura interna non veniva sempre considerata in una visualizzazione a scorrimento.

Sul lato in linea dell&#39;ultimo elemento dell&#39;elenco è evidenziata una casella, che mostra la spaziatura interna e l&#39;elemento che hanno la stessa larghezza utilizzata per creare l&#39;allineamento desiderato.

Per indurre i browser a inserire la spaziatura interna alla fine dello scorrimento, sceglierò come target l'ultima cifra in ogni elenco e aggiungerò uno pseudo elemento corrispondente 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.

Aggancio scorrimento

Un contenitore a scorrimento con overflow può diventare un'area visibile agganciata con una riga di CSS, dopodiché spetta all'elemento secondario specificare come deve essere allineato all'area visibile.

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

Fulcro del video

L'ispirazione per questo componente deriva dalla sua enorme popolarità su TV, negli store e non solo. Molte piattaforme di videogiochi usano come layout principale la schermata Home, molto simile a questa. In questo caso l'attenzione è fondamentale, non solo una piccola aggiunta. Immaginate di usare questo rotore multimediale dal divano con un telecomando e di apportare all'interazione alcuni piccoli miglioramenti:

.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 viene rimosso 7px dalla casella, lasciando un po' di spazio. Se l'utente non ha preferenze per il movimento riguardo alla riduzione del movimento, l'offset viene trasferito, conferendo un movimento sottile all'evento di messa a fuoco.

Indice mobile

Gli utenti di gameplay e tastiera richiedono un'attenzione particolare in questi lunghi elenchi di opzioni e contenuti a scorrimento. Il modello comune per risolvere questo problema è chiamato indice mobile. Si tratta di un contenitore di elementi con l'elemento attivo tramite tastiera, ma che può mantenere lo stato attivo a un solo elemento secondario alla volta. Questo singolo elemento attivabile in un'esperienza di volta in volta è progettato per consentire di saltare l'elenco di elementi potenzialmente lungo, anziché premere Tab più di 50 volte per raggiungere la fine.

Ci sono 300 elementi nel primo scorrimento della demo. Possiamo fare di meglio che farli attraversare tutti per passare alla sezione successiva.

Per creare questa esperienza, JavaScript deve osservare gli eventi della tastiera e impostare lo stato attivo sugli eventi. Ho creato una piccola libreria open source su npm per semplificare l'esperienza utente. Ecco come si usa per i tre dispositivi di scorrimento:

import {rovingIndex} from 'roving-ux';

rovingIndex({
  element: someElement
});

Questa demo esegue una query nel documento per cercare gli scorrimenti e per ognuno di essi chiama la funzione rovingIndex(). Passa l'elemento rovingIndex() per ottenere l'esperienza di navigazione, ad esempio un contenitore di elenco e un selettore di query di destinazione, nel caso in cui i target con stato attivo non siano discendenti diretti.

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

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

Proporzioni

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

Accanto agli altri formati utilizzati di 16:9 e 4:3 è 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, viene eseguito l'upgrade delle immagini di scorrimento dei contenuti multimediali alle dimensioni aspect-ratio. Con la sintassi di nidificazione della bozza, ogni immagine modifica le proporzioni a seconda della prima, della seconda o della terza riga. La sintassi nidificata consente anche di impostare alcune piccole modifiche dell'area visibile, proprio lì con l'altra logica di dimensione.

Con questo CSS, poiché la funzionalità è disponibile in più motori del browser, verrà visualizzato un layout facile da gestire ma visivamente più accattivante.

Preferisco dati ridotti

Anche se questa tecnica successiva è disponibile solo dietro un flag in Canary, volevo spiegarti come avrei potuto risparmiare una notevole quantità di tempo di caricamento della pagina e utilizzo dei dati con poche righe di CSS. La query multimediale prefers-reduced-data dal livello 5 consente di chiedere se il dispositivo si trova in uno stato dei dati ridotto, ad esempio in modalità Risparmio dati. In tal caso, 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 le prestazioni del sito dopo l'aggiunta del CSS prefers-reduced-data:

ALT_TEXT_HERE

(71 richieste, 1,2mb di risorse in 1,07s)

64 richieste in meno, corrispondenti a circa 60 immagini all'interno dell'area visibile (test effettuati su un display widescreen) di questa scheda del browser, un aumento del caricamento pagina dell'80% circa e il 10% dei dati over-the-wire. CSS davvero potente.

Conclusione

Ora che sai come ci sono riuscito, come faresti?! 🙂

Diversifica i nostri approcci e scopriamo tutti i modi per creare sul web. Crea un Codepen o ospita la tua demo, inviami un tweet e lo aggiungerò alla sezione Remix della community qui sotto.

Fonte

Remix della community

Ancora niente da visualizzare