En tant que développeur, vous avez certainement déjà été confronté à la création d'une galerie d'images.
Pour un débutant, cela peut rapidement virer au casse-tête. Mais comme vous êtes têtu et avez le goût du travail bien fait, vous lisez ces lignes dans l'espoir de parfaire vos compétences.
Dans cet article, nous allons étudier les différentes possibilités pour construire une galerie d'images. Du plus simple au plus complexe, vous serez en mesure de réaliser tout type de slider, slideshow ou carrousel. La seule limite : votre imagination !
La pseudo-classe :target :
Commençons avec la pseudo-classe :target. Celle-ci permet de cibler un élément afin de déclencher une action (comme on peut le faire en JavaScript). Cette méthode est assez répandue depuis quelques années déjà, mais elle a un gros inconvénient.
Comme elle se base sur les ancres, il en résulte un phénomène connu : le saut de page. Un autre problème intervient également : celui de l'historique des liens. En effet, les id sont reportés dans la barre d'adresse, ce qui contraint l'internaute, s'il utilise la flèche retour du navigateur, à cliquer pour remonter tout l'historique.
Pour être plus clair, vous aurez une adresse à rallonge. Si vous avez cliqué sur une centaine de photos, vous imaginez alors l'ampleur du problème.
Exemple de slider (responsive) avec :target :
Le slider ci-dessous est donc construit en utilisant la pseudo-classe :target. Vous allez constater que la mise en place est assez simple.
Voici comment procéder :
On crée un élément div qui englobe le slider (grandes et petites images). La longueur du slider sera à définir selon vos besoins (dans notre exemple, il s'agit de 600 pixels). Nous allons également déclarer la propriété overflow avec la valeur hidden. Nous verrons pourquoi juste après.
On ajoute un nouvel élément div qui contiendra toutes les grandes photos. Nous allons utiliser le mode de rendu flexbox. Ainsi, va t-on aligner les photos les unes à la suite des autres. C'est pourquoi nous avons déclaré la propriété overflow, de manière à montrer une photo à la fois. Sans cette propriété, nous verrions toutes les photos.
Ensuite, on met en place la navigation. Dans cet exemple, il s'agit d'une liste non ordonnée avec l'élément ul. Nous plaçons chaque miniature à l'intérieur d'un élément li et d'un lien hypertexte en attribuant un identifiant différent pour chaque lien.
On reprend ces mêmes id pour les placer juste au-dessus du tout premier élément div du slider. On déclare une classe qui empêchera le saut de page. L'astuce est plutôt simple. Une autre solution a vu le jour récemment, il s'agit de la propriété scroll-padding, qui fait partie du nouveau module CSS Scroll Snap et qui va résoudre le problème de manière naturelle (voir l'exemple suivant).
Pour finir, il nous faut obtenir l'effet de slide. Nous allons utiliser les transformations CSS.
Ici, nous allons utiliser la pseudo-classe :focus-within afin de faire apparaître les photos. L'avantage de cette pseudo-classe est qu'elle s'applique lorsqu'un élément a reçu le focus via le clavier ou la souris.
Voici comment procéder :
On crée un élément div qui contiendra notre slider. On déclare la largeur et la hauteur.
Puis, on met en place une liste non ordonnée avec l'élément ul. A l'intérieur de chaque élément li, nous aurons un lien hypertexte (élément qui reçoit le focus) dans lequel on place une miniature photo, puis un élément span contenant la grande photo.
L'élément ul sera à déclarer en position relative avec le mode de rendu flexbox (pour aligner les miniatures). Nous engloberons au sein de l'élément les grandes photos avec la propriété overflow et la valeur hidden.
Les grandes photos contenues dans les éléments span seront en position absolute et hors du cadre ( left:-100%) ou en utilisant les transformations (mieux pour les performances).
Enfin, pour faire apparaître les photos, nous allons donc utiliser la pseudo-classe :focus-within et passer la valeur de la position à zéro.
*{box-sizing: border-box}
img{max-width: 100%}
.slider_focus{
max-width: 600px;
margin: 2rem auto
}
.slider_focus ul{
display: flex;
padding-bottom: 66.67%;/* ratio pour le responsive */
position: relative;
overflow: hidden;
list-style-type: none;
margin:0;
}
.slider_focus ul li a img{
flex: 1;/*les photos occupent la même place selon la largeur du conteneur*/
padding: .5rem;
}
.slider_focus ul li span img{
position: absolute;
bottom: 0;
left: -100%;
opacity: 0;
transition: all .6s
}
.slider_focus ul li:focus-within span img{
left: 0;
opacity: 1
}
Cette méthode comporte un avantage certain par rapport à la pseudo-classe :target. Nous n'utilisons plus l'URI pour pointer une ancre.
La conséquence : plus aucun historique de navigation et plus de saut de page !
Mais, à la base, l'élément input est utilisé pour les formulaires. Cette technique n'est donc pas une solution "naturelle". Néanmoins, elle fonctionne bien et permet de réaliser des actions assez complexes (sans pour autant passer par JavaScript).
Si bien qu'au lieu d'utiliser la pseudo-classe :target, nous allons nous orienter vers la pseudo-classe CSS :checked. Il est à noter que celle-ci s'applique uniquement sur les élements radio, les checkbox ou encore les options dans les select.
Voici comment procéder :
On crée un élément div que l'on déclare en position relative. On renseigne également la largeur et la hauteur du slider. Puis on englobe l'élément div avec la propriété overflow et la valeur hidden de manière à garder les photos à l'intérieur du div.
On crée un nouvel élément div dans lequel on déclare la propriété display avec la valeur flex. Il s'agit du conteneur qui va nous permettre d'aligner les photos miniatures.
Aussi, allons-nous placer un nouvel élément div qu'il faudra mettre à chaque nouvelle photo. Dans cet exemple, il y a six photos donc on répétera le div six fois.
A l'intérieur de cet élément, nous trouverons un élément input ainsi qu'un label qui s'y rattache (même identifiant) et une photo miniature, elle-même à l'intérieur du label. Nous prendrons soin de choisir un nom unique que nous placerons dans tous les éléments input de type radio via l'attribut name (par exemple : name="votre_nom"). Si nous avons choisi des input de type radio, c'est pour s'assurer qu'une seule action se déclenche : celle de faire apparaître une photo.
On ajoute à la suite du label la photo en taille réelle. On met l'image en position absolute et qui sera hors du cadre principal avec les transformations sur l'axe X.
Nous aurons également pris soin de renseigner le même attribut class dans chaque input, de telle sorte que lorsqu'on cliquera sur un input et le label rattaché (représentés par une photo miniature), elle déclenchera la même action (le slide).
Enfin, pour obtenir l'effet de slide, il nous suffit de changer la position de l'image en passant la transformation sur l'axe X à zéro.
Pour créer un slideshow en CSS, nous allons devoir utiliser les animations CSS.
Voici comment procéder :
On crée un élément div qui sera le conteneur du slideshow. On déclare la largeur et la hauteur. Il faut également englober les photos à l'intérieur avec la propriété overflow et la valeur hidden.
On crée ensuite une liste non ordonnée dans laquelle on déclare toutes nos photos. Chaque élément li qui contient une photo sera en position absolute et invisible (avec la propriété opacity). Nous allons aussi déclarer notre animation CSS pour faire défiler les photos.
Pour créer cette animation, nous aurons besoin de prendre en compte la durée totale, le délai pour chaque image ainsi que le minutage des images-clés. Comme c'est assez long à expliquer, je vous envoie vers cet article (EN) pour de plus amples informations.
Comme nous l'avons vu dans l'exemple précédent, le slideshow, il est aisé de réaliser en quelques minutes un slider automatique grâce aux animations CSS.
Voici comment procéder :
On crée un élément qui va contenir notre slider. Dans cet exemple, nous avons utilisé l'élément HTML5 figure, mais un élément div peut tout aussi bien être mis en place. Celui-ci sera en position relative.
On va calculer ensuite la longueur totale du conteneur par rapport à la quantité de photos. Dans notre exemple, il y a quatre photos à faire défiler. Nous allons donc renseigner une valeur de 500% (100% par photo).
Mais pourquoi 500%, alors que nous ne disposons que de quatre photos ? Ne conviendrait-il pas mieux d'écrire 400% ? Et pourquoi met-on alors cinq photos dans le conteneur ? C'est justement là que réside l'astuce...
Il faut replacer la première photographie à la fin du diaporama pour donner l'illusion de défilement infini. Sans cela, le défilement va se couper brutalement et revenir au début.
Ceci fait, il faut maintenant créer une animation CSS qui va permettre le défilement automatique. Ce n'est pas très compliqué. Nous avons cinq images. Nous allons donc découper l'animation en cinq étapes. Chaque 20 %, une nouvelle image va effectuer un glissement (slide). Pour déterminer ensuite la durée totale de l'animation, il suffit de donner une durée à chaque photo et de multiplier celle-ci par cinq. (Dans cet exemple, 5 x 6s = 30 secondes)
Enfin, pour que votre diaporama soit compatible avec les mobiles, nous allons nous servir de la propriété object-fit, et indiquer une largeur en pourcentage et une hauteur avec l'unité de mesure viewport (vh). Celle-ci va se charger de calculer le ratio à adopter selon la résolution de l'écran.
Cet exemple est plus complexe dans la mesure où il va falloir gérer à la fois le slider et le défilement automatique.
Voici comment procéder :
On crée un élément div que l'on met en position relative. On détermine une longueur équivalente à la taille des photos (dans cet exemple : 600px)
Nous allons ensuite mettre en place les éléments input qui vont servir au slide des images, ainsi qu'au défilement automatique. Il y aura donc trois input pour le slide (trois photos), un pour lancer le défilement et trois autres pour mettre en pause.
Ensuite, nous allons créer une liste non ordonnée (élément ul) contenant les photos. Ici même technique que pour l'exemple du diaporama automatique fullscreen (vu plus haut) : la première photo doit se placer deux fois dans la liste.
Passons ensuite à la navigation. Nous allons créer un nouvel élément div à la suite de la liste de photos. A l'intérieur de celle-ci, nous allons regrouper trois labels dans lesquels nous reportons les mêmes id que dans les trois input qui permettent la mise en pause du diaporama. Cela va nous permettre de pouvoir cliquer sur pause sur chaque photo. Il y aura donc trois boutons pause. Bien sûr, nous n'en verrons qu'un seul. Pour réaliser cette illusion, nous allons jouer avec z-index, opacity, et une animation CSS. Le but étant qu'à chaque nouvelle photo, le bouton pause disparaisse puis réapparaisse sans que cela ne se voit. Le bouton play, quant à lui, n'ayant comme seule fonction que de remettre le diaporama à l'image de départ, ne sera à renseigner qu'une fois. Pour résumer, nous aurons dans cet élément div quatre labels, un pour le bouton play, trois pour le bouton pause.
Vient maintenant la navigation avec les flèches. Après avoir créer deux nouveaux éléments div, l'un (pour suivant) et l'autre (pour précédent) contenant trois labels reprenant les mêmes id (ce qui nous donne six labels en tout), il va également falloir utiliser la même technique expliquée précédemment.
Pour faire défiler les photos automatiquement, nous allons donc utiliser une animation CSS. C'est à peu près le même principe que l'on a utilisé pour le diaporama automatique. Ici, nous avons quatre photos. Mais nous allons diviser l'animation en trois pour faire défiler les images. Comme la première image ne bouge jamais, nous allons porter l'action à effectuer sur la deuxième et troisième image.
On crée un élément div conteneur dans lequel on va déclarer notre espace en trois dimensions avec la propriété perspective. Plus la perspective est grande, plus l'impression d'éloignement sera important. On détermine également une largeur et une longueur à l'élément (elles doivent correspondre à la taille des photos).
On crée ensuite un nouvel élément div en position relative, où l'on indique le type de transformation que l'on veut appliquer avec la propriété transform-style et la valeur preserve-3d. Notre environnement en trois dimensions est prêt.
Toujours dans ce même élément div, nous allons ajouter une animation CSS assez simple, contrairement aux exemples plus haut. Ici, il s'agit simplement de faire effectuer une simple rotation au contenu se trouvant dans l'élément.
Ensuite, on met en place nos images qui seront en position absolute. Dans cet exemple, nous avons huit images. Il s'agit donc d'un octogone. Nous allons maintenant devoir effectuer quelques calculs. Pour connaître chaque angle de notre carrousel, il suffit de diviser 360 degrés (un cercle complet) par le nombre de faces. Ainsi nous obtenons 45 degrés (360° / 8). Comme nous connaissons la largeur de chaque face du carrousel (400px dans notre exemple), on va pouvoir trouver l'apothème de l'octogone. On reporte le nombre (ici 495px) dans chaque image sur l'axe Z via la propriété transform. On indiquera par ailleurs une rotation sur l'axe Y.
Vous avez remarqué une faute, un oubli, un lien mort ? Vous ne comprenez pas un point précis du tutoriel ? Vous pouvez me contacter par mail (contact@guyom-design.com) et je vous aiderai si je le peux.