Chapitre 5
Manipulation d'images

Retour Accueil CSS

40 Image pliée en accordéon.

Termes CSS clés employés : transform:translate(), transform:rotate(), :nth-child().
Compatibilité navigateurs : IE10+, Firefox16+. Chrome et Safari avec le préfixe -webkit-.

Problématique

A partir d’une unique image, créer un effet de pliage en accordéon en CSS pur.

Résolution théorique

Une des méthodes permettant de parvenir à ce résultat consiste à diviser l’image en éléments individuels, que l’on va faire pivoter alternativement selon l’axe Y, puis rapprocher pour qu’ils restent consécutifs. Un effet d’ombrage sera appliqué à un élément sur deux, pour accentuer l’effet 3D. Plutôt que d’employer un élément IMG, nous allons toutefois placer dans chaque élément enfant une image sous forme arrière-plan (background-image) décalée à chaque fois d’une largeur d’élément avant pivotement.

Résolution pratique

La structure HTML est simpliste : un élément conteneur DIV, renfermant autant d’éléments DIV que de faces, les DIV pairs renfermant eux-même un élément SPAN qui procurera l’ombrage.
<DIV id="conteneur"> <DIV id="face"></DIV> <DIV id="face"><SPAN></SPAN;gt;</DIV> <DIV id="face"></DIV> … <DIV id="face"><SPAN></SPAN;gt;</DIV> </DIV>
Remarquez que ce squelette HTML est en fait totalement dépourvu de contenu : tout sera effectué en CSS. Commençons par l’élément DIV conteneur. Il définit la taille générale, la seule spécification importante étant la définition de la perspective 3D (dont la valeur peut être modifiée).
DIV.conteneur { margin: 100 auto 20; width:500px; height:350px; perspective: 500px; }

Les caractéristiques globales des faces sont ensuite définies. Les éléments sont définis comme des éléments en ligne de position relative et se voient dotées d’une unique image de fond. Leur largeur est définie à une fraction de la largeur totale du conteneur, ici 9.7% car on va créer 10 faces et l'expérience prouve qu'il faut toujours garder un peu de marge.
DIV .face{ display: inline-block; position: relative; background-image:url("cour.jpg"); padding:0px; margin-left:-5px; width: 9.7%; height: 100%; }
Nous allons maintenant définir les spécificités de chaque face grâce au pseudo-élément nth-child(n). Tout d’abord, on ajuste la position de l’image d’arrière-plan en la décalant d’un dixième de sa largeur pour chaque face à partir de la seconde, soit 50 pixel d’arrière-plan, à l’aide de la propriété background-position. Puis nous allons transformer chaque face, en la faisant pivoter alternativement de 45° à partir de la droite pour les faces paires et de la gauche pour les faces impaires: les faces sont donc groupées par deux, paire-impaire. La première face impaire et la dernière face paire sont seules. Une face ayant pivoté n’occupera plus la même largeur, mais une largeur apparente égale à 50 * cos(45°), soit 35,4 px. Il faut donc décaler les paires de faces, par incrément de 29,2 px (2 fois 14,6 px), en définissant la position à gauche, sauf la première face.
DIV .face:nth-child(1) { transform-origin: top left; transform: rotateY(-45deg); right: auto; left: 0px; } DIV .face:nth-child(2) { background-position:-50px 0; transform-origin: top right; transform: rotateY( 45deg ); left: -29.2px; } DIV .face:nth-child(3) { background-position:-100px 0; transform-origin: top left; transform: rotateY(-45deg); right: auto; left: -29.2px; } DIV .face:nth-child(n pair) { background-position:-(50*n)px 0; transform-origin: top right; transform: rotateY( 45deg ); left:-(14.6*n)px; } DIV .face:nth-child(n impair) { background-position:-(50*n)px 0; transform-origin: top left; transform: rotateY(-45deg); left: :-(14.6*(n-1))px; }
Je n’ai pas cité ici tout le code, largement répétitif : attention à bien remplacer dans votre code les valeurs en italique par les valeurs pertinentes.

Image en accordéon

Le résultat est sympathique, mais manque un peu d’effet 3D. Pour obtenir celui-ci, nous allons définir une ombre à l’aide de l’élément SPAN. Dans un proche futur, la standardisation des filtres CSS permettra de s’affranchir de cet élément en définissant un filtre sur les éléments DIV pairs, mais les filtres ne sont actuellement reconnus que par Chrome et Safari.
Comme nous n’avons placé dans le HTML d’élément SPAN que dans les éléments DIV pairs, il n’est pas nécessaire de recourir à un sélecteur supplémentaire. Si tous les DIV avaient comporté un élément SPAN, nous aurions employé div:nth-child(even).
L’ombre est définie à l’aide de la méthode linear-gradient, en employant des couleurs RGBA pour pouvoir définir la transparence.
DIV .face DIV span{ position: absolute; width: 50px; height: 100%; background: linear-gradient( left, rgba(0,0,0,0.2), rgba(0,0,0,.7)); }

Image en accordéon


Retour Accueil CSS

© 1999-2019 Fabrice "Fyndhorn Elder" Lemainque