Aller au contenu principal
Guillaume Duverger Code & graphisme

CSS Slider/slideshow avec navigation

La construction du slider en HTML :




<div class='diapo_auto_rwd'>

<input name="diapo" id='slide1' type="radio" class='slide_diapo'>
<input name="diapo" id='slide2' type="radio" class='slide_diapo'>
<input name="diapo" id='slide3' type="radio" class='slide_diapo'>
<input name="diapo" id='lance-diapo' type="radio" checked>
<input name="diapo" id='pause1' type="radio" class='pause_diapo'>
<input name="diapo" id='pause2' type="radio" class='pause_diapo'>
<input name="diapo" id='pause3' type="radio" class='pause_diapo'>

<ul>

<li class='image1 slide_diapo'><img src='1.jpg' alt></li>
<li class='image2 slide_diapo'><img src='2.jpg' alt></li>
<li class='image3 slide_diapo'><img src='3.jpg' alt></li>

</ul>

<div class='lancement_arret'>
<label class='lance_diapo' for='lance-diapo'></label>
<label class='pause_diapo image1' for='pause1'></label>
<label class='pause_diapo image2' for='pause2'></label>
<label class='pause_diapo image3' for='pause3'></label>
</div>

<div class='precedent'>
<label class='image1' for='slide1'></label>
<label class='image2' for='slide2'></label>
<label class='image3' for='slide3'></label>
</div>

<div class='suivant'>
<label class='image1' for='slide1'></label>
<label class='image2' for='slide2'></label>
<label class='image3' for='slide3'></label>
</div>		
</div>



Voici comment procéder en CSS :

  1. Le contenur global

    On crée un élément div en CSS qui sera notre conteneur global. On détermine une longueur maximale (dans cet exemple : 600px) avec la propriété max-width ainsi qu'une position relative puisque nous allons disposer les différents contrôles en positionnement absolu. De plus, nous allons prévenir le débordement des images qui se trouveront côte à côte avec la propriété overflow et la valeur hidden.

  2. La navigation globale

    Dans la partie HTML, vous pouvez constater des éléments input de type radio qui suivent le conteneur global et 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. En ce qui concerne la partie CSS, dans un premier temps, il nous faut faire disparaître les input afin de les styliser. Il existe plusieurs méthodes pour cela.

  3. Liste d'images

    Vous pouvez voir également dans la partie HTML une liste non ordonnée (élément ul) contenant nos images où nous allons déclarer une disposition flexible display: flex, de manière à ce que les images se trouvent les unes à la suite des autres. Chaque image est placée à l'intérieur d'un élément li. Nous déclarons avec une largeur à 100% (flex-basis : 100%) et on ajoute une transition sur la transformation pour le slide. Le conteneur de la première image se place donc à 0%, le second à 100% et le troisième à 200%.

    Nous déclarons également la propriété object-fit et la valeur cover sur nos images au cas où certaines possèderaient un rapport d'aspect différent ainsi u'une largueur et une hauteur à 100%.

  4. Mise en place des contrôles

    Passons ensuite à la navigation proprement dite. Nous allons créer un nouvel élément div à la suite de la liste d'images. A l'intérieur de celui-ci, nous allons regrouper trois label dans lesquels nous reportons les mêmes identifiants que dans les trois input (ceux juste après le conteneur global) qui permettent la mise en pause du diaporama. Cela va nous permettre de pouvoir cliquer sur pause sur chaque photo. Nous allons également ajouter un label pour le défilement (bouton play).

    Il y a donc trois boutons pause. Bien sûr, nous n'en verrons qu'un seul. Le bouton play, quant à lui, n'ayant comme seule fonction que de remettre le diaporama à l'image de départ, ne possèdera pas d'animation. On se contentera juste de le faire apparaître et disparaître selon l'image sur lequel il se trouve.

    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 chacun trois label reprenant les mêmes identifiants, ce qui nous donne six éléments label en tout.

  5. Animations et transitions

    Pour faire défiler les photos automatiquement, nous allons donc utiliser une animation CSS. Ici, nous avons trois photos. Nous allons donc diviser l'animation en trois étapes-clé qui, pour chacune va s'étaler sur 25%, pour faire défiler les images. Dès lors qu'on clique sur le bouton play, on lance l'animation. La première image n'a pas besoin d'être déplacée, la seconde étant positionnée à 100% (comme dit à l'étape 3), il nous suffit d'utiliser une transformation négative sur l'axe x (-100%) pour la faire revenir au premier plan. La troisième image étant à 200%, la transformation sera de -200%.

    En ce qui concerne les éléments de contrôle, nous allons devoir ruser. Il faut les gérer à la fois lors du défilement et aussi sur la partie slide. Pour ce faire, nous allons utiliser les propriétés z-index et opacity dans une animation CSS. Le but étant qu'à chaque nouvelle photo, le bouton pause ainsi que les flèches disparaissent puis réapparaissent.

    Pour la partie slide nous allons reprendre le même principe que l'animation du défilement en utilisant les transformations, non pas avec une animation mais une simple transition.





*,
*::before,
*::after {
  box-sizing: border-box;
}

.diapo_auto_rwd input{
	
position: absolute;
left:-100vw;
bottom:0
	
	}
	
.diapo_auto_rwd{
	
display:grid;
position:relative;
max-width:600px;
margin:2rem auto;
overflow:hidden;
border-radius:.75rem;

	}



.diapo_auto_rwd label{
	
	cursor:pointer
	
	}

.diapo_auto_rwd ul {
	
display:flex;	
margin: 0;
padding: 0;
list-style-type: none;

		
		}

.diapo_auto_rwd ul li {
	
flex:0 0 100%;
transition:translate .4s;
background-color: white	
	}


.diapo_auto_rwd ul li img{
display: block;
width:100%;
height:100%;
object-fit: cover;

	
	}
	
/*slide images*/

#slide1:checked ~ ul li,
#pause1:checked ~ ul li {

translate:0 0
	
	}

#slide2:checked ~ ul li,
#pause2:checked ~ ul li {

translate:-100% 0
	
	}

#slide3:checked ~ ul li,
#pause3:checked ~ ul li{

translate:-200% 0
	
	}


/*defilement automatique des photos lorsqu'on clique sur le bouton play*/
#lance-diapo:checked ~ ul li {

animation: slide-diapo 12.3s infinite
	
	}

/*animation css3 defilement automatique des photos*/


@keyframes slide-diapo {
	
0%,25%{
	
translate:0 0
	
	}
	
33%,58%{
	
translate:-100% 0
	
	}
	
66%,91%{
	
translate:-200% 0
	
	}
	
	}

.diapo_auto_rwd img,
.precedent,
.suivant,
.lancement_arret {
	
user-select: none;
	
	}

#lance-diapo:checked ~ ul .slide_diapo,
.pause_diapo:checked ~ ul .slide_diapo,
.pause_diapo:checked ~ .precedent label,
.pause_diapo:checked ~ .suivant label,
.slide_diapo:checked ~ .precedent label,
.slide_diapo:checked ~ .suivant label{

transition:none
	
	}
/*navigation fleches droite et gauche*/
.precedent,
.suivant {
display: flex;
align-items: center;
justify-content: center;
height:50px;
width:50px;	
position: absolute;
top: 50%;
translate:0 -50%;
z-index: 1
	
	}

.precedent label,
.suivant label {
	
position: absolute;
opacity: 0;
z-index: -1;
height: 20px;
width: 20px;
border-width: 5px 5px 0 0;
border-style: solid;
border-color: #f2f2f2;
		
	}
	
.precedent {left: 1rem}
	
.suivant {right:1rem}

.precedent label{
	

rotate:-135deg;
	
	}
	
.suivant label{
	
 
rotate:45deg;
	
	}




#slide1:checked ~ .precedent .image3,
#pause1:checked ~ .precedent .image3,
#slide1:checked ~ .suivant .image2,
#pause1:checked ~ .suivant .image2, 
#slide2:checked ~ .precedent .image1,
#pause2:checked ~ .precedent .image1,
#slide2:checked ~ .suivant .image3,
#pause2:checked ~ .suivant .image3, 
#slide3:checked ~ .precedent .image2,
#pause3:checked ~ .precedent .image2,
#slide3:checked ~ .suivant .image1,
#pause3:checked ~ .suivant .image1 {
	
	opacity: 1;
	z-index: 1
	
	}




#lance-diapo:checked ~ .precedent .image3,
#lance-diapo:checked ~ .suivant .image2 {

animation: fleche_diapo 12.3s infinite -1s
	
	}

#lance-diapo:checked ~ .precedent .image1,
#lance-diapo:checked ~ .suivant .image3 {

animation: fleche_diapo 12.3s infinite 3.1s
	
	}
  
  
#lance-diapo:checked ~ .precedent .image2,
#lance-diapo:checked ~ .suivant .image1 {

animation: fleche_diapo 12.3s infinite 7.2s
	
	}


/*Play-Pause*/
.lancement_arret,
.lancement_arret label{

position: absolute
	
	}

.lancement_arret {
	
top: 50%;
left: 50%;
z-index: 2

}

.lancement_arret label {
	
translate:-50% -50%
	}

.lance_diapo::after{

background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 485 485' style='enable-background:new 0 0 485 485' xml:space='preserve'%3E%3Cg fill='%23fff'%3E%3Cpath d='M413.974 71.026C368.171 25.225 307.274 0 242.5 0S116.829 25.225 71.026 71.026C25.225 116.829 0 177.726 0 242.5s25.225 125.671 71.026 171.474C116.829 459.775 177.726 485 242.5 485s125.671-25.225 171.474-71.026C459.775 368.171 485 307.274 485 242.5s-25.225-125.671-71.026-171.474zM242.5 455C125.327 455 30 359.673 30 242.5S125.327 30 242.5 30 455 125.327 455 242.5 359.673 455 242.5 455z'/%3E%3Cpath d='M181.062 336.575 343.938 242.5l-162.876-94.075z'/%3E%3C/g%3E%3C/svg%3E%0A");
content: ''	
	}
	
.pause_diapo:after{
background-image: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='iso-8859-1'%3F%3E%3C!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 512 512' style='enable-background:new 0 0 512 512;' xml:space='preserve'%3E%3Cg fill='%23fff'%3E%3Cpath d='M256,0C114.842,0,0,114.842,0,256s114.842,256,256,256s256-114.842,256-256S397.158,0,256,0z M256,465.455 c-115.493,0-209.455-93.961-209.455-209.455S140.507,46.545,256,46.545S465.455,140.507,465.455,256S371.493,465.455,256,465.455z '/%3E%3Cpath d='M318.061,139.636c-12.853,0-23.273,10.42-23.273,23.273v186.182c0,12.853,10.42,23.273,23.273,23.273 c12.853,0,23.273-10.42,23.273-23.273V162.909C341.333,150.056,330.913,139.636,318.061,139.636z'/%3E%3Cpath d='M193.939,139.636c-12.853,0-23.273,10.42-23.273,23.273v186.182c0,12.853,10.42,23.273,23.273,23.273 c12.853,0,23.273-10.42,23.273-23.273V162.909C217.212,150.056,206.792,139.636,193.939,139.636z'/%3E%3C/g%3E%3C/svg%3E%0A");
content:""
	
	}

.lancement_arret label::after{
height:50px;
width:50px;
	
		}



#lance-diapo:checked ~ .lancement_arret .pause_diapo,
.slide_diapo:checked ~ .lancement_arret .lance_diapo,
.pause_diapo:checked ~ .lancement_arret .lance_diapo {
	
display: flex;
z-index: 1
	
	}

#lance-diapo:checked ~ .lancement_arret .lance_diapo,
.slide_diapo:checked ~ .lancement_arret .pause_diapo,
.pause_diapo:checked ~ .lancement_arret .pause_diapo {
	

z-index: -1
	
	}

#lance-diapo:checked ~ .lancement_arret .pause_diapo.image1,
#lance-diapo:checked ~ .lancement_arret .pause_diapo.image2,
#lance-diapo:checked ~ .lancement_arret .pause_diapo.image3{
	
opacity: 0;
z-index: -1
	
	} 



#lance-diapo:checked ~ .lancement_arret .pause_diapo.image1 {

animation: fleche_diapo 12.3s infinite -1s
	
	}

#lance-diapo:checked ~ .lancement_arret .pause_diapo.image2 {

animation: fleche_diapo 12.3s infinite 3.1s
	
	}

#lance-diapo:checked ~ .lancement_arret .pause_diapo.image3 {

animation: fleche_diapo 12.3s infinite 7.2s
	
	}

@keyframes fleche_diapo {
	
0%,33.33%{
	
opacity: 1;
z-index: 0
	
	}
	
33.34%,100%{
	
opacity: 0;
z-index: -1
	
	}
	
	}