[CSS]Effet porte coulissante (slide)

NoSmoking

Réalisation d'un effet de slide type "porte coulissante" en CSS uniquement.

Slider type #1

L'effet

Au départ une image et son texte associé sont visibles par défaut.

L'effet consiste à faire apparaître un texte descriptif, au survol des images, suivant le principe des portes coulissantes.

Passez la souris sur les images pour voir l'effet.

La structure de base

On utilise une structure classique sur base d'une liste <ul> et de balises HTML5 <figure> et <figcaption>.

<ul class="slider">
  <li class="item_actif">
    <figure>
      <img src="image/image_1.png" alt="">
      <figcaption>Le contenu descriptif</figcaption>
    </figure>
  </li>
  <li>
    <figure>
      <img src="image/image_2.png" alt="">
      <figcaption>Le contenu descriptif</figcaption>
    </figure>
  </li>
</ul>

Chaque image et son texte sont inclus dans un élément <li> dont on n'affiche que la moitié, à savoir l'image dans l'exemple ci-dessus.

La classe "item_actif" détermine quel est l'élément qui doit être affiché par défaut.

Le principe

Le conteneur doit être dimensionné et affecté d'un overflow:hidden pour masquer les dépassements.

ul.slider {
  list-style:none;                  /* reset classique */
  padding:0;
  margin:0 auto;
  height:9.25em;
  width:50em;
  overflow:hidden;                  /* masquage des dépassements */
  border:1px solid #abc;
}

A survol d'un élément on augmente la largeur de celui-ci pour laisser apparaître également le texte qui y est contenu.

/* largeur par défaut */
.slider li {
  width:25%;                        /* ( 100% - Largeur_% LI:hover ) / ( Nbr LI - 1) */
}
/* largeur au survol */
.slider li:hover {
  width:50%;                        /* largeur LI:hover (visible entièrement) */
}

Les deux schémas ci-dessous, pour trois éléments, permettent de visualiser le principe.

schéma #1 de principe
Dimensions et positions initiales des éléments.
schéma #2 de principe
Dimensions et positions au survol de l'élément central.

Pour ajouter un effet de glissement au déploiement, on utilise la propriété CSS3 transition qui est appliquée à la largeur, transition:width .5s ease 0.1s.

Le code CSS pour trois éléments <li> sera donc le suivant :

.slider li {
  float:left;                       /* on place les LI en enfilade */
  white-space:nowrap;               /* pas de passage à la ligne */
  width:25%;                        /* ( 100% - Largeur_% LI:hover ) / ( Nbr LI - 1) */
  height:100%;                      /* occupe toute la hauteur du parent */
  transition: width .5s ease 0.1s;  /* mise en place d'un léger délai pour éviter les éventuels "flash" */
}

L'élément par défaut, <li class="item_actif">, est redéfini lui en largeur.

.slider li.item_actif  {
  width:50%;                        /* largeur LI:hover (visible entièrement) */
}

Le problème

Avec ce seul CSS, le problème que l'on rencontre se situe au niveau de l'élément placé à droite. Celui-ci disparaît lorsque l'on survole un élément, ce qui est lié au fait que l'élément actif reste à 50%.

Nota : dans le cas où c'est l'élément de droite qui est "item_actif", cela fonctionne très bien et l'on peut même supprimer la classe "item_actif".

Pour résoudre ce problème, il est nécessaire de diminuer la largeur de l'élément "item_actif" et de la passer à 25%.

Le CSS cascade, descend, mais ne remonte pas l'arbre du DOM, (du moins pas actuellement), donc il nous faudrait avoir recours à du javascript pour déplacer la classe "item_actif" sur l'élément survolé, mais comme nous sommes partis sur une solution en CSS nous allons appliquer une "astuce".

L'astuce

Pour que cela fonctionne quel que soit l'élément survolé, l'astuce consiste à mettre une pseudo-classe dynamique, :hover également sur le parent <ul>.

Le CSS au survol devient le suivant :

.slider:hover li {                  /* spécificité = 0-0-2-1 */
  width:25%;                        /* ( 100% - Largeur_% LI:hover ) / ( Nbr LI - 1) */
}
.slider li:hover {
  width:50%;                        /* largeur LI:hover (visible entièrement) */
}

ATTENTION : dans les règles ci-dessus :

Slider type #2

Autre présentation

Aquarelles de René CHARRIER

Passez la souris sur les images pour voir l'effet.

Ce qui change

Il n'est plus nécessaire d'avoir une classe "item_actif".

Le calcul de la largeur initiale ne ce fait plus de la même façon mais rien de bien révolutionnaire.

/* EXEMPLE #2 reprise uniquement des valeurs qui changent */
.type_2.slider li {
  width:16.66%;                     /* Largeur_% UL / Nbr LI */
}
.type_2.slider:hover li {
  width:10%;                        /* ( 100% - Largeur_% LI:hover ) / ( Nbr LI - 1) */
}
.type_2.slider li:hover {
  width:50%;                        /* largeur LI:hover (visible entièrement) */
}

Pour le reste le CSS est identique.

Conclusion

Rien de bien compliqué dans ce que l'on vient de voir, de plus sur les navigateurs ne reconnaissant pas la propriété transition, le fonctionnement reste opérationnel.

Peut-être qu'avec CSS4 on verra apparaître un sélecteur <, une pseudo-classe :parent ou :nth-parent, que sais-je encore, pour permettre de cibler un parent et non plus seulement des enfants mais bon le C de CSS, cascading, perdrait quand même un peu de son sens !

Ressources