Si vous avez essayé d’utiliser la pseudo-classe :target, présente dans la spécification CSS3, et que vous avez voulu reproduire l’une des nombreuses démos que l’on trouve sur internet, comme par exemple :
- Un volet coulissant en CSS3 (Creative Juiz, par Geoffrey Crofte)
- Un slideshow CSS3 (Alsacréations, par Geoffrey Crofte)
- Navigation slide CSS3 avec :target et transitions
Vous vous êtes confrontés au problème du scroll de la page si le contenu est plus grand que la hauteur de votre écran ! Et cela est tout à fait normal. Il n’existe pas de façon "propre" pour empêcher ce comportement.
Comment contrer ce problème ?
Le principe de la bidouille est la suivante : un élément qui reçoit le :target, mais qui n’est pas affiché, ne déclenchera pas le comportement du scroll du navigateur. Il est alors possible d’utiliser le target pour cibler un autre élément.
Le sélecteur d’adjacence indirecte nous vient en aide !
Il est donc possible d’appliquer le :target sur un élément qui ne sera pas affiché (avec display:none) mais grâce au sélecteur d’adjacence indirecte ~ (tilde), on pourra sélectionner un autre élément qui lui sera affiché. Il suffit alors d’envoyer le target vers le bon élément.
Voici le code HTML utilisé pour la démo :
<div id="demoWrap">
<a id="wrap1" class="ancre"></a>
<a id="wrap2" class="ancre"></a>
<a id="wrap3" class="ancre"></a>
<a id="wrap4" class="ancre"></a>
<div id="liens">
<ul>
<li><a href="#wrap1"><span>...</span></a></li>
<li><a href="#wrap2"><span>...</span></a></li>
<li><a href="#wrap3"><span>...</span></a></li>
<li><a href="#wrap4"><span>...</span></a></li>
</ul>
</div>
<div id="imgs">
<ul>
<li><img src="#" alt="..." /></li>
<li><img src="#" alt="..." /></li>
<li><img src="#" alt="..." /></li>
<li><img src="#" alt="..." /></li>
</ul>
</div>
</div>#liens correspond aux liens de navigation. #imgs correspond aux 4 images. Les a correspondent aux éléments qui recevront le target, puis avec le sélecteur d’adjacence, on récupère la div#imgs pour la déplacer. Voici le CSS "allégé" :
/* on masque les a class="ancre" */
#demoWrap a.ancre{
display: none;
}
#imgs{
transition: all 1s ease;
}
#demoWrap a#wrap1:target ~ #imgs{
margin-left:0px;
}
#demoWrap a#wrap2:target ~ #imgs{
margin-left:-580px;
}
#demoWrap a#wrap3:target ~ #imgs{
margin-left:-1160px;
}
#demoWrap a#wrap4:target ~ #imgs{
margin-left:-1740px;
}Les a sont donc masqués. Et lorsqu’ils reçoivent le :target, on récupère la div#imgs avec le sélecteur d’adjacence pour lui appliquer le margin-left correspondant.
Et voilà ! Ainsi, aucun scroll n’est provoqué, comme sur la démo ci-dessus.
Attention : la technique est à utiliser à bon escient...
Notes
Sous Safari 5.0 Windows (mais pas avec Safari 5.1.2) , j’ai un problème de performance (3 secondes d’attente entre chaque clic) : observez-vous cela aussi ?
Souscrire



#1par PascaleLC, le 5 décembre 2011
Je n’ai peut-être pas les yeux en face des trous (c’est la fin de la journée hein... et j’ai bientôt faim ;) ), mais où elle est ta démo ? que je la visionne bien avant de rugir en terme d’accessibilité (ou pas)
#2par PascaleLC, le 5 décembre 2011
Bon alors pardon, je n’ai rien dit : j’ai trouvé ! Et bien tu devrais la mettre après ton code et pas avant ! Je n’avais pas percuté que c’était la chose tout en haut ;-D (fin de journée toussa, disais-je ^^)
#3par css3create, le 5 décembre 2011
@PascaleLC : pas de soucis ! ;) Je la laisse en haut, parce que je veux que ça reste un site de démos, avant tout. On navigue de page en page pour voir différents effets, trouver des idées. J’ajoute depuis peu des astuces, comme cet article, qui me permettent de partager des techniques de CSS.
Vincent
#4par Geoffrey, le 6 décembre 2011
Hello,
Merci pour cette astuce.
On s’éloigne un peu plus encore de la fonction de base de :target (et on s’éloigne au sens propre de l’élément ciblé), mais ça à l’air de rendre plus agréable ce type de réalisation full CSS.
Je vais tester ça sur mes fichiers de démo pour voir.
Merci pour tes recherches.
Geoffrey (disclaimer : auteur des deux premiers tutoriels cités)
#5par css3create, le 6 décembre 2011
@Geoffrey : C’est vrai. Mais en même temps, l’utilisation de :target pour réaliser une galerie photo s’éloigne de l’utilisation classique, ou en tout cas, de l’utilisation pensée au départ, puisque le principe initial d’une ancre est justement d’envoyer quelque part dans la page, et à priori, non atteignable directement (dans une page très longue par exemple).
Donc détourner :target pour cibler des éléments parents imbriqués ou pour cibler des éléments frères, ça ne me pose pas plus de soucis...
Mais merci de me donner vos différents points de vues.
PS : J’ai édité les liens en ajoutant ton nom. ;) French connection !
#6par Geoffrey, le 6 décembre 2011
Merci pour la French Connection ;)
Oui effectivement, l’usage que j’en ai fait dans mes tutoriels est déjà un détournement. Mon intervention n’était pas là pour dire qu’une solution était meilleure que l’autre, loin de là ^^
Au contraire, ce complément est génial !
D’ailleurs je serai assez fan d’un retour sur ces techniques en terme d’accessibilité. Est-ce une grosse horreur ? Est-ce acceptable ?
Au passage, j’ai mis à jour le tutoriel sur Alsacréations, ci et là, notamment sur cette page : http://www.alsacreations.com/tuto/l...
À bientôt ;)
#7par css3create, le 6 décembre 2011
Oui, j’ai bien compris ton point de vue.
Je suis également preneur de retours au niveau de l’accessibilité de cette technique. Des experts dans la salle ?
A+.
Vincent
#8par cedricici, le 9 décembre 2011
pour :target , ça ne me choque pas quant à son utilisation dans le cadre d’un slide-show, c’est son role : atteindre une ancre et en modifier l’apparence = faire apparaître la photo qui n’était pas visible avant, que ce soit en scrollant la page ou en animant des éléments dans un overflow:hidden, le résultat est le même, le reste c’est du design.
En revanche l’utilisation des <b> Oo la Vincent, je vois pas ? on s’éloigne lde la sémantique de ces balises alors que ceci est parfaitement acceptable (en modifiant légèrement le CSS) :
<div id="imgs"><a id="wrap1" ></a>
<a id="wrap2" ></a>
<a id="wrap3" ></a>
<a id="wrap4" ></a>
<ul>
<li><img src="..." alt="..." /></li>
<li><img src="..." alt="..." /></li>
<li><img src="..." alt="..." /></li>
<li><img src="..." alt="..." /></li>
</ul>
</div>