Le sélecteur d’adjacence indirecte est peu connu en CSS.
Arrivé avec la nouvelle mouture CSS3, ce sélecteur vous permet de sélectionner d’un seul coup tous les frères d’un élément ciblé répondant à un sélecteur précis.
Voyons voir avec quelques exemples comment l’utiliser et quels sont ses effets.
Syntaxe de base
Le sélecteur, que j’appelle incorrectement siblings du fait de sa ressemblance avec la fonction siblings()
de jQuery, utilise le caractère ~ disponible sous PC depuis les touches Alt Gr + 2(é ~).
element1 ~ element2 {
/* mes styles */
}
Ici les styles seront appliqués à tous les element2
frères de element1
, même si un autre frère vient se mêler entre deux element2
, par exemple.
Quelques exemples d’utilisations
En réalité je n’en ai pas trouvé tant que ça, peut-être par habitude d’utiliser d’autres techniques.
Généralement la technique li + li
pour cibler tous les frères du premier li
dans une liste, par exemple, me suffit.
Cibler les frères non identiques à l’élément de départ
Cependant ce sélecteur d’adjacence indirecte (~
) va permettre de combler certaines lacunes du sélecteur d’adjacence directe (+
).
Il sera capable de cibler tous les paragraphes qui suivent un titre, par exemple. Chose qui ne fonctionnera pas en faisant h3 + p
, mais qui fonctionnera avec h3 ~ p
.
Cibler les frères d’un élément survolé, ciblé ou typé
Dans la même logique que précédemment, il est possible de cibler, par exemple, tous les frères d’un li
survolé (donc les autres li
), ou d’un input
typé.
li:hover ~ li {
opacity: 0.4;
}
Cet exemple provient d’un effet produit sur jq.creativejuiz.fr (avec une solution jQuery), ou sur la récente démonstration de Raphaël Goetter sur un fil d’ariane entièrement conçu en CSS : Breadcrumbs without images.
Ou avec le deuxième exemple :
input[type="radio"] ~ input {
margin-left: 2.6em;
}
Ce qui permettrait, dans un enchaînement de input + label
de type radio, d’espacer les choix.
Démonstration
Exemple de factorisation pour les niveaux de titre
J’ai essayé d’aller plus loin encore, avec des choses un peu poussées… un peu trop peut-être.
Je m’explique.
Je ne sais pas si la pratique est courante, mais il peut-être intéressant d’avoir une indentation des blocs de texte en fonction du niveau dans lequel on se trouve dans un document (pas du niveau dans le DOM, mais dans la hiérarchie des titres).
C’est surtout dans un contexte de forte densité de texte que je vois l’intérêt.
Voici une illustration de mon propos : voir la démonstration.
Comme vous pouvez le voir, une marge à gauche est appliquée en fonction du niveau de titre qui précède le contenu.
Ou plutôt, en terme de CSS, tout ce qui suit un niveau de titre se verra appliquer une marge en conséquence.
La marge n’est qu’un exemple parmi d’autres, on peut très bien imager d’autres styles plus colorés.
Vous avez le droit de vous dire que sur le web ça ne sert pas à grand chose et qu’on cherche souvent à avoir un contenu épuré… soit, mais imaginons.
Avant de vous donner du code, je tiens à préciser que ça ne fonctionne pas. En effet, dans le cas présent, je place les uns à la suite des autres des titres, paragraphes et listes.
Il n’y a donc aucune profondeur, aucun sectionnement du contenu.
Voici la CSS (version pour Firefox) de l’exemple, si vous ne l’avez pas déjà analysée directement dans la démo :
.ex2 h3 {
margin-left: 1em;
}
.ex2 h3 ~ :-moz-any(p, ul, blockquote, h4) {
margin-left: 2em;
}
.ex2 h4 {
margin-left: 4em;
}
.ex2 h4 ~ :-moz-any(p, ul, blockquote, h5) {
margin-left: 5em;
}
.ex2 h5 {
margin-left: 7em;
}
.ex2 h5 ~ :-moz-any(p, ul, blockquote, h6) {
margin-left: 8em;
}
/*
permettre de remonter dans la hiérarchie...
mais pas trop...
*/
.ex2 h5 ~ h4 ~ :-moz-any(p, ul, blockquote, h5) {
margin-left: 5em;
}
.ex2 h4 ~ h3 ~ :-moz-any(p, ul, blockquote, h4) {
margin-left: 3em;
}
Vous remarquerez l’utilisation de any()
, pseudo-classe vue précédemment dans l’article « CSS3 – Any(), pseudo-classe prometteuse et économe« , qui me permet d’économiser quelques lignes de code.
Voyez-vous où le problème se pose ?
En fait, un paragraphe (ou liste) qui se trouve après un h3
qui serait lui même après un h4
se verrait appliquer les styles d’un paragraphe (ou liste) se trouvant après un h4
. Et oui ! Puisque dans l’absolu, ce p
, même si précédé d’un h3
, se trouve frère d’un h4
.
Euh… ça va ? Je ne vous ai pas perdu ?
Sinon pour information, ce sélecteur est compatible avec IE7 et version supérieure, génial non ?
C’était une simple réflexion sur l’utilisation de ce sélecteur.
Et vous, vous en pensez quoi ?
Je vous laisse me dire comment vous voyez l’utilisation de ce sélecteur.
Je rends l’antenne.
À vous !
Pour utiliser le caractère tilde (~) dans vos CSS sous Mac OS, la combinaison de touches clavier est la suivante :
Alt + n
Merci pour cette excellent article !
Première visite et une claque directe! Allez add to fav.
Merci
@Jean-Michel : merci pour ton complément (et compliment), je me permets de rajouter cette info sur l’article. 🙂
@Jp : Yay ! Merci 🙂
très bon article et expliquer simplement en plus !
Assez pratique ces sélecteurs quand on les gère bien.
Hello,
Toujours de très bons articles…
Mais j’ai quand même une remarque:
Le sélecteur ~ permet de cibler les éléments frères suivants un autre élément, et pas les éléments frères tout court (comme le fait la fonction siblings de jQuery)
D’ailleurs, je n’ai toujours pas compris pourquoi il n’existait pas de tel sélecteur en CSS, qui permettrait de récupérer tous les frères (précédents et suivants) ou un sélecteur d’adjacence inverse (-). On pourrait alors faire li – li pour récupérer le li précédent un autre.
Vincent
Bonsoir Vincent.
Merci pour ce compliment.
Oui effectivement je parle de cette fausse ressemblance à plusieurs endroits dans mon article, notamment quand je dis « que j’appelle incorrectement siblings », ou encore « tous les paragraphes qui suivent un titre », sans compter l’exemple de la page de démonstration qui présente bien la chose.
Je vais cependant mettre en exergue cette remarque pour ne pas qu’il y ait de confusion.
C’est vraiment que le sélecteur d’adjacence inverse manque cruellement, mais je crois que
nth-child
peut largement convenir, par exemple en faisant :Il est possible de cibler tous les
li
situés avant le quatrièmeli
de la liste.Au plaisir 😉
Bonjour,
concernant le sélecteur d’adjacence inverse, qui nous manque tant, il semble qu’il soit réclamé par bien du monde, et pourtant … rien à signaler à l’horizon concernant un tel sélecteur.
Il faut dire, ce n’est pas simple à implémenter, et si j’ai bien compris, ce serait catastrophique au niveau des performances pour le rendu des pages.
http://www.dailymotion.com/video/xp69td_un-navigateur-comment-ca-marche_news
Sur ce, je disparais, je vais éviter de m’enterrer vivant, mais comme à chaque fois que je lis le maître des lieux, ce n’est pas l’envie qui m’en manque.
Bravo pour vos articles !
Hello nonos,
J’ai proposé un complément à cet article pour la communauté d’Alsacréations que tu trouveras ici :
Sélectionner les frères d’un élément.
Celui-ci propose d’utiliser
nth-child
pour simuler cette sélection d’adjacence inverse. M’enfin c’est expérimental.CSS4 propose également des choses prometteuses (pas forcément spécifiquement sur ce sujet), mais il va encore falloir attendre.
Merci pour le rappel de la vidéo, je n’avais pas pu assister à cette conférence, il faudra que je la visionne dans son ensemble 🙂
Merci pour tes compliments et pour tes échanges !
Hello,
oui, ces vidéos (Paris Web et Sud Web) sont une bouffée d’oxygène pour qui comme moi, s’autodidacte un peu tout seul dans son coin. 🙂
Concernant nth-child, j’avoue avoir cet onglet (ton complément sur Alsacréation) ouvert depuis quelques temps, le temps de refaire une série de tests commencés il y a peu (label, input, champ obligatoire) où j’utilisais nth-child sur la balise universelle *. Le but était de remonter d’un cran, de input au label qui le précédait.
Mais ça n’avait pas l’air de fonctionner. Comme il était tard, voire très tard, je m’étais promis de reprendre à tête reposée, quand un moment propice se présenterait. Pour l’instant, je n’ai rempli qu’une seule des deux conditions à la fois.^^
Un exemple très intéressant d’utilisation de ce sélecteur tilde pour filtrer une liste de résultats en CSS : http://tympanus.net/codrops/2012/01/09/filter-functionality-with-css3/
Hello,
Merci pour cet exemple très intéressant d’utilisation 🙂
Génial.
Merci pour tes tutos, ils sont TOUS vraiment très clairs et très instructifs, remarquablement bien structurés, pas de « bruits parasites », de très bonne qualité.
De plus, le design de ton site n’est pas que pour faire joli, il en rajoute énormément à la compréhension du contenu.
je ne vois absolument rien de négatif ou de mieux à faire.
Merci beaucoup, j’apprends énormément et très vite grâce à ton site.
Bonjour Jérôme,
Merci beaucoup pour ton commentaire très agréable à lire 🙂
Au plaisir.
PS : j’espère que la prochaine version du blog continuera à délivrer la même qualité du message