Présentation générale de la création d'une vue à défilement horizontal responsive pour les téléviseurs, les téléphones, les ordinateurs de bureau, etc.
Dans cet article, je vais vous expliquer comment créer un défilement horizontal. des expériences Web minimales, réactives, accessibles et qui fonctionnent sur des navigateurs et des plates-formes (comme les téléviseurs !). Essayez le demo.
<ph type="x-smartling-placeholder">Si vous préférez la vidéo, voici une version YouTube de cet article:
Présentation
Nous allons créer une mise en page à défilement horizontal
pour héberger les vignettes de
médias ou produits. Au départ, le composant est une simple liste <ul>
, mais il est
transformées par CSS en une expérience de défilement fluide et satisfaisante,
des images et les
ancrer à une grille. JavaScript est ajouté pour faciliter
Interactions avec un indice temporaire permettant aux utilisateurs de claviers d'éviter de parcourir plus de 100 éléments.
De plus, une requête média expérimentale, prefers-reduced-data
, permet de transformer
en une expérience de défilement de titre légère.
Commencez par un balisage accessible
Un conteneur de défilement multimédia est composé de quelques composants principaux, à savoir une liste d'éléments. A dans sa forme la plus simple, peuvent voyager dans le monde entier et être clairement consommée par tous. Un utilisateur qui accède à cette page peut parcourir une liste et cliquer sur un lien pour afficher un article. C'est notre base accessible.
Diffusez une liste avec un élément <ul>
:
<ul class="horizontal-media-scroller">
<li></li>
<li></li>
<li></li>
...
<ul>
Rendez les éléments de la liste interactifs avec un élément <a>
:
<li>
<a href="#">
...
</a>
</li>
Utilisez un élément <figure>
pour représenter sémantiquement une image et sa légende:
<figure>
<picture>
<img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
</picture>
<figcaption>Legends</figcaption>
</figure>
Notez les attributs alt
et loading
sur <img>
. Texte alternatif d'un contenu multimédia
"défilement" est une opportunité d'expérience utilisateur qui permet d'ajouter du contexte à la miniature.
Texte de remplacement si l'image n'a pas été chargée ou si l'interface utilisateur est lue vocalement
s'appuyant sur une technologie d'assistance
comme un lecteur d'écran. En savoir plus avec Five Golden
règles de texte alternatif
texte.
L'attribut loading
accepte le mot clé lazy
comme moyen de signaler cette image.
La source ne doit être récupérée que lorsque l'image se trouve dans la fenêtre d'affichage. Il peut s'agir
Cette fonctionnalité est très utile pour les longues listes, car les utilisateurs ne téléchargent des images que pour les éléments
jusqu'à ce qu'il s'affiche.
Prendre en charge les préférences de jeu de couleurs de l'utilisateur
Utilisez color-scheme
comme balise <meta>
pour signaler au navigateur que votre page
veut à la fois les styles de user-agent clair et sombre. Mode sombre sans frais
ou clair, selon votre affichage:
<meta name="color-scheme" content="dark light">
La balise Meta fournit le signal le plus tôt possible. Ainsi, le navigateur peut sélectionner une couleur de canevas sombre par défaut si l'utilisateur a une préférence de thème sombre ; Cela signifie que la navigation entre les pages du site n'affiche pas de canevas blanc. entre les chargements. Thème sombre parfait entre les chargements vos yeux.
Pour en savoir plus, consultez Thomas Steiner : https://web.dev/color-scheme/.
Ajouter du contenu
Compte tenu de la structure de contenu de ul > li > a > figure > picture > img
ci-dessus,
la tâche suivante consiste à ajouter des images et des titres à faire défiler. J'ai empaqueté la démo
des images et du texte d'espace réservé statiques, mais n'hésitez pas à l'utiliser
source de données préférée.
Ajouter un style avec CSS
Il est maintenant temps pour le CSS de transformer cette liste de contenus générique en expérience. Netflix, les plates-formes de téléchargement d'applications et de nombreux autres sites et applications utilisent le format horizontal zones de défilement pour empaqueter la fenêtre d'affichage avec des catégories et des options.
Créer la mise en page de type conteneur de défilement
Il est important d'éviter de couper le contenu dans les mises en page ou de s'appuyer sur du texte avec des points de suspension. De nombreux téléviseurs ont des défileurs multimédias comme celui-ci, mais a trop souvent recours à des points de suspension. Ce n'est pas le cas avec cette mise en page. Elle permet aussi au contenu multimédia de remplacer la taille de colonne, ce qui fait une mise en page suffisamment flexible pour gérer de nombreuses combinaisons intéressantes.
Le conteneur permet de remplacer la taille de la colonne en indiquant la taille par défaut une propriété personnalisée. Cette mise en page en grille est avisée sur la taille des colonnes, elle est ne gérant que l'espacement et la direction:
.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 propriété personnalisée est ensuite utilisée par l'élément <picture>
pour créer notre format de base: une zone:
.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);
}
}
Avec seulement quelques styles mineurs, complétez les bases du conteneur de défilement multimédia:
.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);
}
}
Définir overflow
configure <ul>
pour permettre le défilement et la navigation au clavier
dans sa liste, l'élément ::marker
de chaque élément enfant direct <li>
est supprimé
en obtenant un nouveau type d'affichage inline-block
.
Les images ne sont pas encore réactives et explosent immédiatement à l'intérieur. Apprivoisez-les avec quelques tailles, styles et styles de bordures. un dégradé d'arrière-plan en cas de chargement différé:
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%)
);
}
Marge intérieure du défilement
L'alignement sur le contenu de la page et la surface de défilement bord à bord sont essentielle à un composant harmonieux et minimal.
Pour obtenir la mise en page de défilement bord à bord qui s’aligne sur notre typographie
et les lignes de mise en page, utilisez padding
qui correspond à 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 */
}
Correction d'un bug concernant la marge intérieure du défilement horizontal Ce qui précède montre à quel point il devrait être remplir un conteneur de défilement, mais il présente des problèmes de compatibilité en suspens. (corrigé dans Chromium 91 ou version ultérieure). Voir cliquez ici pour en savoir plus. de l'historique, mais la version courte est que la marge intérieure n'a pas toujours été prise en compte dans une vue de défilement.
Pour inciter les navigateurs à placer la marge intérieure à la fin du conteneur de défilement, cibler la dernière figure de chaque liste et ajouter un pseudo-élément qui est le de marge intérieure souhaitée.
.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'utilisation de propriétés logiques permet au conteneur de défilement multimédia de fonctionner dans n'importe quel mode d'écriture. et l'orientation du document.
Alignement sur le défilement
Un conteneur à défilement avec dépassement peut devenir une fenêtre d'affichage ancrée avec une ligne de code CSS. Les enfants doivent ensuite spécifier la manière dont ils souhaitent s'aligner sur cette fenêtre d'affichage.
.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;
}
}
Mise au point
Ce composant s'inspire de sa popularité considérable sur les téléviseurs, sur les plates-formes de téléchargement d'applications, etc. De nombreuses plateformes de jeux vidéo utilisent un conteneur de défilement multimédia similaire à celui-ci, comme mise en page d'écran d'accueil principal. La concentration est un énorme et pas seulement un petit ajout. Imaginez utiliser ce défileur multimédia de votre canapé avec une télécommande, apportez de petites améliorations à cette interaction:
.horizontal-media-scroller a {
outline-offset: 12px;
&:focus {
outline-offset: 7px;
}
@media (prefers-reduced-motion: no-preference) {
& {
transition: outline-offset .25s ease;
}
}
}
Le style de contour du focus 7px
est ainsi éloigné de la zone, ce qui lui donne
l'espace de stockage. Si l'utilisateur n'a aucune préférence de mouvement pour réduire le mouvement, le décalage
lors d'une transition, ce qui donne un mouvement subtil à l'événement de focus.
Indice de rotation
Les utilisateurs de manettes de jeu et de claviers ont besoin d'une attention particulière dans ces longues listes de le contenu et les options de défilement. Le modèle courant pour résoudre ce problème s'appelle indice mobile. C'est lorsqu'un Le conteneur d'éléments est sélectionné avec le clavier, mais un seul enfant est autorisé à le placer à la fois. Cet élément sélectionnable à la fois est conçu pour permettre de contourner la liste d'éléments potentiellement longue, au lieu d'appuyer sur la touche Tab 50+ fois pour atteindre la fin.
Le premier conteneur de la démo contient 300 éléments. Nous pouvons faire mieux que ils les traversent tous pour atteindre la section suivante.
Pour créer cette expérience, JavaScript doit observer les événements de clavier et sélectionner événements. J'ai créé une petite bibliothèque Open Source npm pour aider à rendre cet utilisateur une expérience utilisateur plus facile à réaliser. Voici comment l'utiliser pour les trois éléments de défilement:
import {rovingIndex} from 'roving-ux';
rovingIndex({
element: someElement
});
Cette démonstration interroge le document à la recherche des éléments de défilement et, pour chacun d'eux, appelle
fonction rovingIndex()
. Transmettre à rovingIndex()
l'élément pour obtenir l'itération
du modèle, comme un conteneur de liste et un sélecteur de requête cible, au cas où
les cibles de ciblage ne sont pas des descendants directs.
document.querySelectorAll('.horizontal-media-scroller')
.forEach(scroller =>
rovingIndex({
element: scroller,
target: 'a',
}))
Pour en savoir plus sur cet effet, consultez la bibliothèque Open Source roving-ux.
Format
Au moment de la rédaction de ce post, la compatibilité
aspect-ratio
est derrière un
dans Firefox, mais disponible dans les navigateurs Chromium ou les boîtiers décodeurs. Depuis le
la mise en page de la grille de défilement des éléments multimédias spécifie uniquement la direction et l'espacement,
modification dans une requête média de la fonctionnalité
qui vérifie si les proportions sont acceptées.
Amélioration progressive avec des défilements multimédias plus dynamiques.
@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);
}
}
}
}
Si le navigateur accepte la syntaxe aspect-ratio
, les images du conteneur de défilement multimédia sont
mise à niveau vers la taille aspect-ratio
. En utilisant la syntaxe d'imbrication de brouillon, chaque image
modifie son format selon qu'il s'agit de la première, de la deuxième ou de la troisième ligne. La
la syntaxe Nest permet également de définir de petites
les ajustements de la fenêtre d'affichage, juste là, avec l'autre logique de dimensionnement.
Avec ce CSS, comme la fonctionnalité est disponible dans un plus grand nombre de moteurs de navigation, il est facile de une mise en page plus visuellement attrayante.
Préfère les données réduites
Bien que la technique suivante ne soit disponible
derrière un indicateur dans
Canary
Je voulais vous expliquer comment je pourrais gagner
un temps considérable en termes de temps de chargement des pages et
l'utilisation des données avec quelques lignes de CSS. La requête média prefers-reduced-data
de
level 5 permet de demander si l'appareil est en
tout état de données réduit, comme un mode Économiseur de données. Si c'est le cas, je peux modifier
document, et dans ce cas, masquer les images.
figure {
@media (prefers-reduced-data: reduce) {
& {
min-inline-size: var(--size);
& > picture {
display: none;
}
}
}
}
Il est toujours possible de naviguer dans le contenu, sans que les images volumineuses soient trop lourdes.
téléchargée. Voici le site avant d'ajouter le CSS prefers-reduced-data
:
(7 requêtes, 100 Ko de ressources en 131 ms)
Voici les performances du site après l'ajout du CSS prefers-reduced-data
:
(71 requêtes, 1,2 Mo de ressources en 1,07 s)
64 requêtes de moins, soit environ 60 images dans la fenêtre d'affichage (tests effectués sur un grand écran) de cet onglet du navigateur, le chargement de la page a augmenté d'environ 80 % et 10% des données sur le fil. Le CSS est plutôt efficace.
Conclusion
Maintenant que tu sais comment j'ai fait, comment faire ?! 🙂
Diversifiez nos approches et découvrons toutes les manières de créer des applications sur le Web. Créez un Codepen ou hébergez votre propre démo, envoyez-moi un tweet pour que je l'ajoute au section "Remix de la communauté" ci-dessous.
Source
Remix de la communauté
Rien à afficher pour le moment !