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.
Se preferisci i video, ecco una versione di questo post su YouTube:
Panoramica
Creeremo un layout a 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, viene utilizzata una query multimediale 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 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>
Nota 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 senza costi o una
modalità Luce, a seconda di come la visualizzi:
<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 perfettamente integrato tra un caricamento e l'altro, molto più bello per gli occhi.
Scopri di più da Thomas Steiner all'indirizzo https://web.dev/color-scheme/.
Aggiungi contenuti
Data la precedente struttura dei contenuti di ul > li > a > figure > picture > img
,
l'attività successiva è 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 dispongono di 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 delle colonne, rendendo un layout sufficientemente flessibile da gestire molte combinazioni interessanti.
Il container consente di eseguire l'override delle dimensioni delle colonne fornendo 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
tramite l'elenco, quindi a ogni elemento <li>
secondario diretto viene rimosso il ::marker
ottenendo un nuovo tipo di visualizzazione di inline-block
.
Tuttavia, le immagini non sono ancora reattive e vengono mostrate subito dalle scatole in cui si trovano. Domali con alcune dimensioni, adattamenti, stili di bordo 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 edge-to-edge sono fondamentali per un componente armonioso e minimale.
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.
Per indurre con l'inganno i browser a inserire la spaziatura interna alla fine dello scorrimento, scelgo come target l'ultima figura di ogni elenco e aggiungerò uno pseudoelemento che corrisponde alla quantità di spaziatura 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'uso delle 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 dell'elemento attivo 7px
si allontana dal riquadro e lascia spazio sufficiente. 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 attivazione.
Indice mobile
Gli utenti di gamepad e tastiere richiedono un'attenzione particolare in questi lunghi elenchi di opzioni e contenuti a scorrimento. Il pattern comune per risolvere questo problema è chiamato indice mobile. Si verifica quando un contenitore di elementi è incentrato sulla tastiera, ma può essere attivato da un solo elemento secondario per volta. Questa esperienza su un singolo elemento attivabile 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 meglio che farli attraversare tutti per passare alla sezione successiva.
Per creare questa esperienza, JavaScript deve osservare gli eventi della tastiera e gli eventi di 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 dinamica, 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 scoprire 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 a griglia dello scorrimento dei contenuti multimediali specifica solo la direzione e la spaziatura, il dimensionamento può cambiare all'interno di una query multimediale che verifica il supporto delle proporzioni.
Miglioramento progressivo di alcuni scorrevoli dei contenuti multimediali più dinamici.
@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. Se è così, posso modificare il
documento e, in questo caso, nascondere le immagini.
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 di aggiungere il CSS prefers-reduced-data
:
(7 richieste, 100kb di risorse in 131ms)
Ecco il rendimento del sito dopo l'aggiunta del CSS prefers-reduced-data
:
(71 richieste, 1,2 MB di risorse in 1,07 secondi)
64 richieste in meno, ovvero circa 60 immagini all'interno dell'area 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 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, twittami e lo aggiungerò alla sezione Remix della community qui sotto.
Origine
Remix della community
Ancora nessun elemento da visualizzare.