Découvrez comment créer une expérience semblable aux stories Instagram sur le Web.
Dans cet article, je vais vous expliquer comment créer un composant Stories pour le Web. Il doit être responsif, compatible avec la navigation au clavier et compatible avec tous les navigateurs.
Si vous préférez suivre une démonstration pratique de la création de ce composant Stories, consultez l'atelier de programmation du composant Stories.
Si vous préférez la vidéo, voici une version YouTube de ce post:
Présentation
Les stories Snapchat et Instagram (sans oublier les flottes) sont deux exemples populaires d'expérience utilisateur pour les stories. De manière générale, les stories se présentent sous la forme d'une interface tactile permettant de parcourir plusieurs abonnements, uniquement sur mobile. Par exemple, sur Instagram, les utilisateurs ouvrent l'histoire d'un ami et parcourent les photos qu'elle contient. En général, ils font autant d'amis à la fois. En appuyant sur le côté droit de l'appareil, l'utilisateur passe à l'histoire suivante de cet ami. En balayant l'écran vers la droite, un utilisateur passe directement à un autre ami. Un composant Story est assez semblable à un carrousel, mais il permet de naviguer dans un tableau multidimensionnel par opposition à un tableau à une seule dimension. C'est comme s'il y avait un carrousel à l'intérieur de chaque carrousel. 🤯
Choisir les bons outils pour une tâche
Dans l'ensemble, j'ai trouvé ce composant assez simple à créer, grâce à quelques fonctionnalités essentielles de la plate-forme Web. C'est parti !
Grille CSS
Notre mise en page s'est avérée peu complexe pour la grille CSS, car elle est dotée de moyens efficaces pour superposer le contenu.
Présentation des amis
Notre principal wrapper de composant .stories
est une vue de défilement horizontale orientée mobile:
.stories {
inline-size: 100vw;
block-size: 100vh;
display: grid;
grid: 1fr / auto-flow 100%;
gap: 1ch;
overflow-x: auto;
scroll-snap-type: x mandatory;
overscroll-behavior: contain;
touch-action: pan-x;
}
/* desktop constraint */
@media (hover: hover) and (min-width: 480px) {
max-inline-size: 480px;
max-block-size: 848px;
}
Récapitulons cette mise en page grid
:
- Nous remplissons explicitement la fenêtre d'affichage sur mobile avec
100vh
et100vw
, et limitons la taille sur les ordinateurs. /
sépare nos modèles de ligne et de colonneauto-flow
correspond àgrid-auto-flow: column
- Le modèle de flux automatique est
100%
, qui correspond ici à la largeur de la fenêtre de défilement.
Sur un téléphone mobile, considérez cela comme la taille de ligne correspondant à la hauteur de la fenêtre d'affichage et chaque colonne à la largeur de la fenêtre d'affichage. Pour continuer avec les stories Snapchat et Instagram, chaque colonne sera celle d'un ami. Nous voulons que les histoires d'amis se poursuivent en dehors de la fenêtre d'affichage. Nous devons donc faire défiler la page jusqu'à un endroit. La grille crée le nombre de colonnes dont elle a besoin pour mettre en page votre code HTML pour chaque récit, créant ainsi un conteneur à défilement dynamique et responsif. La grille nous a permis de centraliser l'ensemble de l'effet.
Empilement
Nous avons besoin que les histoires de chaque ami soient prêtes à être paginées. Pour préparer l'animation et suivre d'autres tendances amusantes, j'ai choisi une pile. Quand je dis empiler, je veux dire que vous regardiez un sandwich par le bas, pas comme si vous regardiez de côté.
Avec la grille CSS, nous pouvons définir une grille à une seule cellule (c'est-à-dire un carré), dans laquelle les lignes et les colonnes partagent un alias ([story]
), puis chaque enfant est affecté à cet espace à une seule cellule aliasé:
.user {
display: grid;
grid: [story] 1fr / [story] 1fr;
scroll-snap-align: start;
scroll-snap-stop: always;
}
.story {
grid-area: story;
background-size: cover;
…
}
Cela permet à notre code HTML de contrôler l'ordre d'empilement et permet également de maintenir le flux de tous les éléments. Notez que nous n'avons rien à faire avec le positionnement de absolute
ou z-index
, et que nous n'avons pas besoin d'encadrer correctement avec height: 100%
ou width: 100%
. La grille parente
définit déjà la taille de la fenêtre d'affichage de l'image de l'histoire. Il n'est donc pas nécessaire de dire à ces composants
pour la remplir.
Points d'ancrage de défilement CSS
La spécification des points d'ancrage de défilement CSS permet de verrouiller facilement des éléments dans la fenêtre d'affichage lors du défilement. Avant que ces propriétés CSS n'existent, il fallait utiliser JavaScript, et c'était... pour le moins délicat. Lisez l'article Présentation des points d'ancrage CSS Scroll de Sarah Drasner pour en savoir plus sur leur utilisation.
.stories { display: grid; grid: 1fr / auto-flow 100%; gap: 1ch; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior: contain; touch-action: pan-x; }
.user { display: grid; grid: [story] 1fr / [story] 1fr; scroll-snap-align: start; scroll-snap-stop: always; }
J'ai choisi les points d'ancrage de défilement pour plusieurs raisons:
- Accessibilité sans frais : La spécification de défilement des points d'ancrage indique que le fait d'appuyer sur les touches Flèche vers la gauche et Flèche vers la droite doit passer d'un point d'ancrage à l'autre par défaut.
- Une spécification qui ne cesse de s'améliorer : la spécification des points d'ancrage de défilement bénéficie constamment de nouvelles fonctionnalités et améliorations, ce qui signifie que mon composant "Stories" s'améliorera probablement à partir de maintenant.
- Facilité d'implémentation. Les points d'ancrage de défilement sont pratiques pour le cas d'utilisation de pagination horizontale axée sur l'écran tactile.
- Une inertie libre comme celle d'une plate-forme : Chaque plate-forme défile et reste dans son style, par opposition à une inertie normalisée qui peut avoir un style de défilement et de repos étrange.
Compatibilité multinavigateur
Nous avons testé Opera, Firefox, Safari et Chrome, ainsi qu'avec Android et iOS. Voici un bref aperçu des fonctionnalités Web dans lesquelles nous avons constaté des différences au niveau des fonctionnalités et de l'assistance.
Cependant, certains CSS ne s'appliquent pas, c'est pourquoi certaines plates-formes manquent actuellement d'optimisation de l'expérience utilisateur. J'aimais ne pas avoir à gérer ces fonctionnalités et je suis sûr qu'elles finiront par être disponibles sur d'autres navigateurs et plates-formes.
scroll-snap-stop
Les carrousels sont l'un des principaux cas d'utilisation de l'expérience utilisateur à l'origine de la création de la spécification des points d'ancrage de défilement CSS. Contrairement aux stories, un carrousel ne doit pas toujours s'arrêter sur chaque image après qu'un utilisateur a interagi avec. Il peut être acceptable ou encouragé de
faire défiler rapidement le carrousel. En revanche, il est préférable de parcourir les stories une par une, et c'est exactement ce que fournit scroll-snap-stop
.
.user {
scroll-snap-align: start;
scroll-snap-stop: always;
}
Au moment de la rédaction de cet article, scroll-snap-stop
n'est compatible qu'avec les navigateurs basés sur Chromium. Consultez la section Compatibilité du navigateur pour obtenir des mises à jour. Mais ce n’est pas un obstacle. Cela signifie simplement que sur un navigateur non compatible,
les utilisateurs peuvent ignorer un ami par erreur. Les utilisateurs devront donc être plus prudents, ou bien nous devrons écrire du code JavaScript pour nous assurer qu'un ami ignoré ignoré ne soit pas marqué comme vu.
Pour en savoir plus, consultez la spécification si cela vous intéresse.
overscroll-behavior
Avez-vous déjà fait défiler une fenêtre modale lorsque vous commencez soudainement
à faire défiler le contenu derrière la modale ?
overscroll-behavior
permet au développeur d'emprisonner ce défilement et de ne jamais le laisser partir. Elle est idéale pour toutes sortes d'occasions. Le composant "Mes histoires" l'utilise pour éviter que des balayages et des gestes de défilement supplémentaires ne quittent le composant.
.stories {
overflow-x: auto;
overscroll-behavior: contain;
}
Safari et Opera sont les deux navigateurs qui ne sont pas compatibles avec cette fonctionnalité, et c'est tout à fait normal. Ces utilisateurs bénéficieront d'une expérience de défilement hors limites comme à leur habitude et ne remarqueront peut-être jamais cette amélioration. Personnellement, je suis un grand fan et j'aime l'inclure dans presque toutes les fonctionnalités de défilement hors limites que j'implémente. C'est un ajout inoffensif qui ne peut qu'améliorer l'expérience utilisateur.
scrollIntoView({behavior: 'smooth'})
Lorsqu'un utilisateur appuie ou clique et atteint la fin de l'ensemble d'histoires d'un ami, il est temps de passer à l'ami suivant dans l'ensemble de points d'ancrage de défilement. Avec JavaScript, nous avons pu référencer l'ami suivant et demander à le faire défiler. La prise en charge des principes de base est excellente : tous les navigateurs l'ont fait défiler pour la faire défiler. Cependant, tous les navigateurs ne l'ont pas fait 'smooth'
. Cela signifie simplement qu'il est affiché
par défilement au lieu d'être ancré.
element.scrollIntoView({
behavior: 'smooth'
})
Safari est le seul navigateur à ne pas accepter behavior: 'smooth'
ici. Consultez la section Compatibilité du navigateur pour obtenir des mises à jour.
Pratique
Maintenant que tu sais comment j'ai fait, comment tu en ferais ?! Diversifions nos approches et apprenons toutes les façons de créer sur le Web. Créez un Glitch, puis envoyez-moi votre version par tweet et je l'ajouterai à la section Remix de la communauté ci-dessous.
Remix de la communauté
- @geoffrich_ avec Svelte: démo et code
- @GauteMeekOlsen avec Vue: démonstration et code
- @AnaestheticsApp avec Lit: démonstration et code