Retour des tutoriels CSS avec quelque chose d’un peu original pour cet article : un effet parallaxe uniquement en CSS3.
C’est à la suite de l’article de Simon Kern sur Alsacréations que m’est venue l’envie de tenter d’utiliser CSS pour reproduire cet effet initialement conçu avec JavaScript.
L’article zoom sur l’effet parallaxe de Simon est bien conçu, je vous invite à le lire si vous préférez l’utilisation de jQuery, ou si vous souhaitez découvrir une alternative ou un complément à ce tutoriel.
J’en profite pour remercier Simon qui m’a autorisé à reprendre son design ainsi que la base du code qu’il a conçu pour l’article sur Alsacréations.
Place à l’explication !
Concept
Pour réaliser cet effet il nous faut plusieurs éléments qui vont nous permettre de simuler différents plans. Ces plans vont se mouvoir dans le même sens mais à vitesses différées afin de donner l’impression que certains sont en premier plan (mouvements rapides) d’autres sont en arrières plan (mouvements plus lents).
Lorsque un tel effet est mis en place sur un site web, il l’est souvent pour offrir une transition originale entre deux vues, un peut comme lors d’un diaporama pour passer d’une slide à l’autre.
Schématisation
Nous utiliserons trois plans pour réaliser cet effet : un fond imagé en CSS (dernier plan), notre contenu qui se trouve naturellement dans le flot du document (second plan), et des éléments placés ci et là (premier plan) pour ajouter de la profondeur.

Le principe de l’animation étant établi, il nous faut également garder en tête que CSS ne permet pas de positionner les éléments en fonction de la position du contenu dans la page, ou en fonction de la position de la souris.
Nous allons donc utiliser la pseudo classe target afin de déterminer à quelle slide nous nous trouvons, et effectuer les animations en conséquence.
Base HTML
Voici un code allégé qui reprend le contenu du document de démonstration. (je n’ai repris que le contenu de body)
<!-- éléments cachés pour jouer avec :target -->
<span id="s1"></span>
<span id="s2"></span>
<span id="s3"></span>
<!-- Le gros conteneur qui va glisser -->
<div id="wrap">
<!-- La navigation -->
<ul id="nav">
<li><a href="#s1">Splash</a></li>
<li><a href="#s2">Lorem Schnapsum</a></li>
<li><a href="#s3">Credits</a></li>
</ul>
<!-- La slide 1 -->
<div id="slide1">
<div class="slide_inside">
<!-- Le logo -->
<h1><img src="images/logo-stop-wars.png" alt="Stop Wars"></h1>
</div> <!-- /.slide_inside-->
</div> <!-- /#slide1 -->
<!-- La slide 2 -->
<div id="slide2">
<div class="slide_inside">
<!-- Les deux éléments en 1er plan -->
<!-- Mettez ici les images que vous voulez
-->
<img src="images/bomb-squad-trooper.png" id="trooper" alt="">
<img src="images/clone.png" id="clone" alt="">
<h2>Star Wars Parallax</h2>
<p>Lorem Salu bissame !</p>
</div> <!-- /.slide_inside-->
</div> <!-- /#slide2 -->
<!-- La slide 2 -->
<div id="slide3">
<div class="slide_inside">
<h2>Credits</h2>
[…]
</div> <!-- /.slide_inside-->
</div> <!-- /#slide3 -->
</div>Pour reprendre la structure de manière schématique, nous avons à peu près cela :

Nous aurions pu utiliser HTML5 sans aucun problème, le principe est le même.
Maintenant nous devons passer au CSS.
Beaucoup de styles
Dimensionnons nos conteneurs et plaçons nos images de fond. Le code suivant est commenté pour vous aider à le comprendre.
body {
margin: 0; padding: 0; /* annulation des marges */
overflow: hidden; /* on cache le débordement de contenu */
color: #fff;
background: #000;
}
#wrap {
/* position du conteneur pour le préparer à bouger */
position: relative;
top: 0;
/* on prépare la transition à venir */
transition: top 1.4s cubic-bezier(.49,.22,.52,1.35);
}
#nav {
/* on fixe le menu en haut */
position: fixed;
top: 0; left: 0; right: 0;
padding: 1em 0;
margin: 0;
/* on centre les liens */
text-align: center;
background: #000;
}
#nav li {
/* on aligne les éléments de liste */
display: inline;
margin:0;
}
#nav a {
/* on applique des marges aux liens */
display: inline-block;
margin: 0 3em;
color: #eee;
/* on applique une petite lueur */
text-shadow: 0 0 5px #fff;
/* on prévoit une petite transition (lueur) */
transition: all 1s;
}Ça c’était pour l’aspect du cadre, nous allons mettre en styles les différents slides et leur attribuer une image de fond tout en prévoyant les transitions.
Nous allons en profiter pour styler les contenus.
/* slides */
#slide1, #slide2, #slide3 {
/* height à adapter avec media queries */
height: 1000px;
padding-top:100px;
/* préparation des transitions */
transition: background-position 1.4s cubic-bezier(.49,.22,.52,1.35);
}
/* attribution des images de fond */
#slide1 { background:url(images/slide1-bg.jpg) center 0 no-repeat fixed; }
#slide2 { background: url(images/slide2-bg.jpg) center 0 no-repeat fixed; }
#slide3 { background: url(images/slide3-bg.jpg) center 0 no-repeat fixed; }
/* Contenus des slides */
.slide_inside {
width: 770px;
margin: 0 auto;
position: relative;
background-color: rgba(0, 0, 0, .6);
padding: 50px;
}
#slide1 .slide_inside {
text-align: center;
background-color: transparent;
}
#slide2 .slide_inside p {
width: 500px;
text-align: justify;
}
#slide3 .slide_inside {
margin-top: 50px;
}Les images de fond et les contenus sont prêts.
On va maintenant positionner et déformer (transform) nos petits personnages en prévoyant également leurs transitions.
/* positionnement des personnages animés */
#trooper, #clone {
position: absolute;
left:-180px; top: 300px;
/* on tourne légèrement les images */
transform: rotate(10deg);
/* et on prévoit une transition */
transition: all 1.4s cubic-bezier(.49,.22,.52,1);
}
/* positionnement différé d'un des 2 personnages */
#clone {
left: -280px;
top: 400px;
}Voilà, tous nos éléments sont positionnés.
Maintenant il faut revoir le positionnement de tous ces éléments en fonction de l’élément ciblé lors d’un clic, c’est là que la pseudo classe target va jouer son rôle.
Animation en fonction de la cible
Le principe va être le même pour chaque élément ciblé par notre menu de navigation.
Je vais donc expliquer le code pour le second élément ciblé (lorsque nous cliquons sur le deuxième élément de menu).
Nous allons utiliser la méthode proposée par Vincent De Oliveira dans son article « Empêcher le scroll avec l’utilisation de target » afin d’éviter qu’un saut dans la page soit effectué lorsque l’on demande à rejoindre une ancre.
/* décalage du conteneur vers le haut */
#s2:target ~ #wrap {
top:-1000px;
}
/* décalage des fonds de chaque slide */
#s2:target ~ #wrap #slide1 { background-position: 50% 36%; }
#s2:target ~ #wrap #slide2 { background-position: 50% 0%; }
#s2:target ~ #wrap #slide3 { background-position: 50% -30%; }
/* mouvements d'un des personnages */
#s2:target ~ #wrap #trooper {
left: -180px;
top: -100px;
transform: rotate(-7deg);
}
/* mouvements de l'autre personnage */
#s2:target ~ #wrap #clone {
left: -350px;
top: 50px;
transform: rotate(0deg);
}
/* juste pour la déco (lueur sur le lien cliqué) */
#s2:target ~ #wrap #nav li:first-child + li a {
text-shadow: 0 0 5px #eca603, 0 0 5px #eca603, 0 0 5px #eca603, 0 0 5px #eca603;
}Pour traduire l’un des sélecteurs CSS avancés en français, on pourrait dire : « Lorsque #s2 est ciblé, je cherche un #wrap directement ou indirectement frère et je style l’élément #clone qui se trouve dedans » (interprétation du sélecteur de la ligne 19).
Le principe est le même lorsque l’on cible les autres slides.
Le plus dur pour vous maintenant, c’est de trouver quels changements appliquer, à quelle vitesse (distance/temps) et dans quelle condition.
Je vous donne le code CSS pour les deux slides restantes. (quand même !)
/* vers Slide 1 */
#s1:target ~ #wrap { top:0px; }
#s1:target ~ #wrap #nav li:first-child a { text-shadow: 0 0 5px #eca603, 0 0 5px #eca603, 0 0 5px #eca603, 0 0 5px #eca603; }
#s1:target ~ #wrap #slide1 { background-position: 50% 0%; }
#s1:target ~ #wrap #slide2 { background-position: 50% -35%; }
#s1:target ~ #wrap #slide3 { background-position: 50% -60%; }
#s1:target ~ #wrap #trooper { left: -180px; top: 300px; transform: rotate(10deg); }
#s1:target ~ #wrap #clone { left: -280px; top: 300px; transform: rotate(10deg); }
/* vers Slide 3 */
#s3:target ~ #wrap { top:-2150px; }
#s3:target ~ #wrap #nav li:last-child a { text-shadow: 0 0 5px #eca603, 0 0 5px #eca603, 0 0 5px #eca603, 0 0 5px #eca603; }
#s3:target ~ #wrap #slide1 { background-position: 50% 60%; }
#s3:target ~ #wrap #slide2 { background-position: 50% 35%; }
#s3:target ~ #wrap #slide3 { background-position: 50% 0%; }
#s3:target ~ #wrap #trooper { left:-1500px;top:-1000px; transform: rotate(-15deg); }
#s3:target ~ #wrap #clone { left:-1000px;top: -800px; transform: rotate(-15deg); }Le code CSS complet se trouve ici : CSS de la démo
Vous aurez noté que les éléments ciblés sont nos span du tout début du code HTML. À partir de ce type de cible, nous pouvons parcourir tout le DOM afin de sélectionner l’élément à styler.
N’hésitez pas si vous avez des questions ![]()



Effet très intéressant et tuto toujours aussi complet à mon goût.
Merci.
Super tutoriel, toujours intéressant de trouver des alternatives full CSS. Merci
Merci pour les explications avec un tuto encore une fois clair.
Bravo pour l’ensemble du site, très complet et simple d’accès.
Merci pour ce super tuto !
Très bon !
Merci à vous pour vos retours
Bravo, ce tuto est excellent et bien traité.
Merci ^^
Juste parfait cet effet ! merci pour le tuto.
super effet, super explications, super article
bonjour
est il possible d’appliquer cet effet sur un thème wordpress ?
merci
Bonjour,
Il s’agit d’une expérimentation CSS3 qui risque d’être paralysante pour les visiteurs qui naviguent encore sur de vieilles versions de navigateur.
Je préfère le rappeler.
Cependant il est possible d’utiliser cet effet sur WordPress. Ce CMS n’est là que pour gérer le contenu, la mise en forme vous appartient
salut!
merci pour se tuto très complet !
petites questions cependant:
Comment fait-on pour rajouter une page?
Peu on adapter se tuto pour un parallax horizontal?
Merci encore!
Bonjour Philippe,
Ce code fonctionne avec un principe d’une division HTML par « slide », ce que vous appelez des pages.
Il est donc possible d’en rajouter autant que vous le souhaitez.
La difficulté va être de personnaliser la CSS à vos besoins : il faudra rajouter un gros bloc de règles à chaque slide ajoutée.
De même, pour la navigation horizontale, il faudra prévoir un changement sur
#wrapde la valeur deleftet non plus detop.Bon courage.
bonjour à tous !
Tout d’abord excellent tuto ! J’ai un petit souci… quand j’ouvre mon site ‘raphael-maddelein.fr’ il s’ouvre en plein milieu de deux menus (« réalisation » et « me contacter ») alors que ça devrait s’ouvrir sur le premier qui est « présentation ».
Quelqu’un a une solution ?
Merci beaucoup
Bonjour Raphaël,
Il semblerait que ton sélecteur « html, body » pose problème.
En ne ciblant que body ça résout ton problème au chargement.
Sympa les effets avec tes boules (pas de sous-entendu s’il vous plait).
Bonne soirée et bon week-end.
Merci pour … mes effets
et cette réponse aussi rapide ! J’ai changé mon sélecteur en indiquant seulement body et le problème persiste.
Bonne soirée également
Si le problème est moins évident qu’il ni parait, comment faire pour qu’à l’ouverture du site on aille directement sur le premier menu sélectionné (présentation)
Merci
Bon week-end
Bizarrement je ne vois pas d’où peut venir le problème… Désolé de ne pouvoir faire plus.
Il y a des erreurs JS sur ta page. (simple info)
En JS il est possible de renvoyer à la première ancre avec cette fonction anonyme, mais c’est dommage d’utiliser JS ici.
(function(){window.location.href='/#s1';}())Bon courage pour la suite.
Ne soyez pas désolé !
Oui je corrige (j’essaye) toutes mes erreurs. Je suis d’accord mais là le JS est ma seule solution… problème résolu.
Encore merci
bonne continuation
Bonjour,
Votre tutoriel est superbe, par contre, est-il possible de remettre l’option scroll ?
Car si ‘lon retire le « :target » plus rien ne défile. Je sais que les mouvements sont provoqués grâce au clic, mais peux-ton allié clic et scroll ?
Hello,
C’est possible, sauf que le scroll devra être utilisé (en l’état) seulement quand le premier élément est ciblé. Il ne faudrait pas qu’il y ait eu de déplacement du contenu en gros.
Ou alors il faut trouver une solution pour activer le scroll sur body directement.
C’est expérimental, donc ouvert à toute suggestion d’amélioration
Bon courage.
Bonjour,
Je reviens vers vous car j’ai trouver la solution à mon problème qui était :
quand j’ouvre mon site ‘raphael-maddelein.fr’ il s’ouvre en plein milieu de deux menus (« réalisation » et « me contacter ») alors que ça devrait s’ouvrir sur le premier qui est « présentation ».
Sur mes input dans le formulaire j’avais mis des autofocus !
Alors « prévention » ci vous souhaitez utiliser ce superbe tuto, ne m’était pas les autofocus.
Bon courage a tous.
Hey !
Merci pour l’info.
Bonne continuation
Super ça fonctionne super bien ! Merci pour ce tuto full CSS
Merci pour ton retour Greg
Merci beaucoup Geoffrey
un bon tutoriel à conseiller …
seul bémol : ça ne fonctionne sous IE (aucunes versions) ni Opera il me semble.
Y-a-t-il un moyen pour que l’effet fonctionne sous tous les navigateurs?
Merci …
Merci.
Oui, il faut passer par JavaScript.
Cela fonctionne sous Opera, mais les effets ne sont pas les mêmes.
Ressource en JavaScript : http://www.alsacreations.com/tuto/lire/1417-zoom-sur-effet-parallaxe.html
bonjour,
super effet que j’essaye d’adapter à une page wordpress.
le changement de fond se fait bien entre les différents div, mais la transition n’opère pas. je n’ai pas encore la page en ligne, je la test en local. le header est bien en place dans le wrap avec le menu wordpress qui fonctionne et renvoie bien aux div mais pas de transition. j’appelle le header.php dans l’index.php. comment faire pour que la transition fasse son effet ? merci pour votre réponse.
Bonjour,
D’après ce que tu me dis l’ancre fonctionne bien, mais pas la transition ?
A priori ça serait donc plutôt un problème de CSS que de template (PHP ou HTML).
As-tu bien préfixé le code pour les transitions ?
Quel navigateur utilises-tu pour ton test ?
C’est vrai qu’un exemple en ligne est vraiment pratique pour ce genre de petit souci
Bon courage.
merci pour ta réponse rapide.
y aurait-il un moyen d’envoyer les fichiers sources en pièce jointe par mail par hasard ?
car là c’est un peu difficile de visualiser et de coller un code de fou ici ça serait pas raisonnable
cordialement
je me rend compte que je n’ai même pas répondu aux questions lol. j’utilise firefox pour le développement et par la suite je regarde si sur les autres navigateurs ça fonctionne, une fois le site réalisé.
en ce qui concerne les préfixes, les au nombre de 5 sont bien avant le div wrap, j’ai donc 5 ancres (par des id autres que #slide mais ça fonctionne).
j’ai bien changé les id des ancres dans le css mais la transition ne se fait pas malheureusement. je rejoins mon premier message pour demander s’il y avait moyen de faire une pièce jointe pour te passer les sources ?
cordialement
Bonsoir, juste pour vous dire que votre design est très sympa voir original à ma connaissance sur la toile.Vos tutoriaux très bien aussi.Mais mon post concerne surtout la richesse de votre design encore bravo ; )
Merci Gérald
Celui-ci devrait changer avant la fin de l’année si le temps me le permet, il date de quelques années (avant même que le blog ne soit public, il existait déjà).
Mais comme j’ai eu pas mal de retours positifs sur ce design, il est possible que j’offre le choix de la décoration au visiteur.
Bonne journée.
cet exemple ne fonctionne absolument pas sur mobile
Wahou ! Merci de vous cacher derrière un Yopmail. Vous n’assumez pas ce commentaire ? Mais pourquoi ?
Il n’est écrit nulle part que cette démonstration doit fonctionner sur mobile, mais je suis ouvert à toute proposition d’amélioration, très cher inconnu.
merci pour ce superbe tuto.
J ‘ais essayer de rajouter un slide , la transition se fait bien mais rien n’apparait , je me retrouve avec une image noir.
Une idée sur le probleme ? adresse du site ci-dessus)
merci d’avance
Hello,
Je te réponds dès que possible. Là je n’ai pas de quoi analyser ton code en détail, mais a priori tu as fait ce qu’il fallait (afficher un code source sur SmartPhone c’est pas très lisible :p)
À plus tard.
merci bien pour ce tuto donc, ça fonctionne très bien sur le site bravo pour ce merveilleux effet sans appel de javascript
Ravi d’avoir pu aider. Et bien joué pour l’adaptation
Bonjour,
Votre tuto est vraiment bien fait.
Cependant j’aurais une question, certes, un peu stupide mais je préfère la poser avant de ma lancer.
Est ce que cet effet est déclinable de façon à faire 4 pages?
Merci d’avance!
Bonjour,
C’est faisable mais il faut ajouter plusieurs composant (un élément slide, un élément span en début de document, et modifier les CSS au niveaux des :target).
Bonne soirée.
Pour etayer la reponse de geoffrey je me suis servi de son code pour faire le site d un pote et j ai rajouter des pages donc si tu veux voir le code je te donne l adresse http://www.studioatsmusic.com et sur le site de ma copine je n ai pas rajouter de page mais des animations si cela peut t aider chris you’re welcome
Excuse moi Chris j ai oublie de te donner l adresse du site de ma cop’s http://www.morgane-laouenan.fr d’ailleurs cela peut , peut etre t’aider il est constituer de 4 pages bon courage
Super
Merci pour la présentation de ton travail !
Ce n’est Geoffrey qu une humble contribution au vue du travail que tu as gentiment fourni a toutes les personnes comme moi
Merci encore a toi, j ai eu beaucoup de succes avec cette architecture
Très heureux d’avoir ce type de retour
Merci beaucoup.
Passez de bonnes fêtes !
Merci beaucoup Gorrevod.
Je vais mater ça.
J’ai rajouté une page hier, j’ai réussi mais j’ai un soucis avec le menu, quand je vais à la troisième page, le menu indique la 4 eme!
Lol pas cool quoi!
Je vais m’y replonger demain!
Merci à toi également Goeffrey pour ta réponse (rapide)
Bonjour!
Génial ce tuto!
Il m’inspire pour mon site perso.
Par contre, je tente en vain depuis une bonne heure de faire une transition comme les objets de gauche(trooper et clone) à droite et je n’y arrive pas, il ne se passe rien…
C’est bien ces valeurs qu’il faut changer:
transition: background-position 1.4s cubic-bezier(.49,.22,.52,1.35)????
Hello,
Non ça ce sont les valeurs de la fonction d’animation pour les images de fond des slides.
Pour les images « volantes » il faut voir du côté de #clone. Les sélecteurs ressemblent à cela dans le code :
#s2:target ~ #wrap #clone. Les valeurs de top, left et rotate permettent de faire bouger les éléments à la vitesse déterminée par la fonction d’animation.Ce n’est pas évident à comprendre au début.
Bon courage.
Merci, super tuto
Continue comme ça
_
Merci m’sieur
Merci ! Au moins maintenant je peux me faire plaisir et jouer avec !
Bonne continuation.
Bonjour à vous les pros,
ca a l’air génial ce tuto! mais je ne comprends rien du tout! je suis superdébutante!! Après de nombreuses recherches je souhaiterais réaliser un site qui ressemble à cette présentation. Mais avant tout, est ce que l’on peut faire cet effet avec la cs5? est ce qu’il faut créer une seule page ou 3 pour réaliser cet effet? Bref, pouvez-vous me donner des conseils pour débuter…
Merci d’avance
Bonjour,
Théoriquement en suivant le tutoriel tu ne devrais pas avoir de souci.
Il s’agit bien d’une seule page proposant plusieurs « slides », plusieurs divisions avec des contenus spécifiques.
Concernant la CS5, je ne comprends pas bien la question, tu peux très bien utiliser Paint et un bloc-note, le résultat pourrait être identique
Tu as besoin de quelques images de fond, d’un fichier HTML (éventuellement CSS) et d’un navigateur.
Bon courage.
Salut,
Excellent tuto très claire et complet.
Je me permet de te dire qu’il y as cependant un soucis, quand on fait défilé la page avec les fleches le texte défile mais le fond non.
Il aurait une alternative full HTML/CSS pour pouvoir faire le scrolling avec les fleches comme sur ce site: http://www.thechrisbox.com?
Merci en tout cas pour ce tuto.
Bonjour,
Je ne comprends pas, mon alternative en CSS ne propose pas de flèches..
Si tu parles des flèches du clavier, effectivement le fond ne bouge pas puisque je n’utilise pas de JS pour connaître l’emplacement du scroll, mais uniquement du CSS et les pseudo-classes
:targetqui permettent de connaître l’élément ciblé. Il n’y a donc pas d’alternative CSS.Merci pour ta réponse, je parlait effectivement des flèche dirrecctionnel du clavier.
Merci encore pour ce tuto!
Je te donne l’adresse de mon site si tu as envie de voir ce que donne mon site grâce à ton tuto
http://chris-lanugue.com/
Hey pas mal l’idée des flèches du slideshow ! Bien joué
Bonjour,
Merci pour ce tuto !
Je prépare un site dans le quel j’utilise vos conseils.
Par contre en utilisant le navigateur Firefox le scroll de la page via les flèches du clavier reste actif. Ce n’est pas le cas avec Chrome.
Comment peut-on complètement désactiver le défilement de la page ?
Merci.
Bonjour Pnow,
Il n’est pas dans l’intérêt de l’utilisateur de bloquer la navigation au clavier, pour des raisons évidentes d’accessibilité.
Bonne soirée
Salut, bravo pour le tutoriel il est simple et clair. Par contre j’ai une question, j’essaye de le réaliser de manière horizontale mais j’ai un problème avec les transitions. Le fond disparaît directement puis on voit doucement l’autre arriver. J’aimerais avoir le même effet que celui en vertical c’est à dire d’avoir l’impression qu’une image pousse l’autre ^^. Comme tu l’as dit dans une ancien commentaire, j’ai modifié top en left dans le wrap d’où peut venir le problème ?
Bonjour,
Hélas, bien que professionnel du métier, je n’arrive pas encore à lire dans la matrice, et ne suis pas doté du don de voyance.
Merci.
Bonjour je n’arrive vraiment pas a creer une nouvelle pourtant j’ai bien rajouter un « slide4″, modifié les targets et tout mais l image du background ne s’affiche toujours pas… Avez vous une solution a me proposer ?
C’est bon j’ai resolu mon probleme, y avait un probleme avec les slides sur ma page html
Excellent !! Très bien fait et très bien commenté comme toujours un régal !!!
Merci Max