Pseudo-éléments : pseudos mais puissants !
Un constat que je ne comprends pas : pourquoi autant de développeurs front-end n’exploitent-ils pas le potentiel énorme des pseudo-éléments, en particulier ceux qui génèrent du contenu, pourtant compatibles depuis bien longtemps sur tous les navigateurs ?
Je pense que c’est par méconnaissance ou par habitude.
En juin dernier, je me suis donc employé, grâce à Raphaël Goetter et son équipe de Alsacréations, à démontrer qu’on peut faire énormément de choses avec ces pseudo-éléments.
Je ne vais pas refaire ma conférence ici, mais en profiter pour approfondir des techniques qui j’espère pourront vous permettre de comprendre comment les exploiter au mieux, et tenter de libérer votre créativité en CSS par la même occasion.
Rafraîchissement de mémoire
D’abord rappelons une vérité : le HTML, ça ne doit servir que pour la structuration et la mise en valeur du contenu. Dès lors que vous en venez à ajouter des éléments vides pour des questions de mise en forme, vous faites — très souvent — fausse route. Et c’est là que les pseudo-éléments de génération de contenu ::before
et ::after
vont vous servir.
Rappelons aussi que ces pseudo-éléments s’écrivent désormais avec double deux-points ‘::’ depuis leur écriture CSS3. Aucun problème de compatibilité toutefois pour les navigateurs récents.
Et un dernier rappel pour les néophytes — non ce n’est pas une tare, nous sommes tous passés par là — : les pseudo-éléments ::before
et ::after
génèrent du contenu à l’intérieur de l’élément ciblé, respectivement avant et après son contenu. Vous devrez d’ailleurs obligatoirement spécifier ce contenu par la propriété content
, même s’il doit être vide, sinon… bah ça marche pas. Cette propriété peut prendre plusieurs valeurs différentes, dont notamment attr(X)
qui est à mon sens la plus intéressante.
Les doigts dans le code
Ces rappels étant posés, voyons ce qu’on peut faire avec ces choses. Je vais passer les exemples classiques de la clearfix et des polices d’icônes.
Dans la suite de cet article, vous verrez des exemples que j’ai codés, hébergés sur CodePen. N’hésitez pas à parcourir les onglets pour voir comment chaque exemple est construit. Je vous indiquerai l’onglet concerné par la description par [HTML], [CSS], [SCSS] et [Result].
Vous pouvez également alterner entre le code SCSS et compilé en CSS en cliquant sur le bouton VIEW COMPILED
de l’onglet [SCSS], ou Edit on CodePen
si le petit aperçu ne vous suffit pas.
Ok… let’s code !
La base
Quelques cas simples pour s’échauffer…
/* Afficher l’extension sur un lien de téléchargement */
[href$=".pdf"]::after { content: "(pdf)"; }
[href$=".zip"]::after { content: "(zip)"; }
/* Spécifier un lien externe par une icône */
[target="_blank"]::after { content: url("external.svg"); }
/* Spécifier un lien sécurisé par une icône */
[href^="https"]::before { content: url("secure.svg"); }
/* Spécifier qu'un lien est une ancre */
[href^="#"]:hover::before,
[href^="#"]:focus::before { content: "#"; }
Voilà qui est fait. N’hésitez pas à aller plus loin avec les sélecteurs d’attribut.
Passons aux choses sérieuses.
L’effet de survol
C’est l’utilisation classique des pseudo-éléments. Vous pouvez ajouter “virtuellement” un élément dont vous avez besoin pour améliorer un effet au survol d’un élément.
Note : pour des questions d’accessibilité, il est fortement recommandé de dupliquer l’effet au focus. Sachez toutefois qu’un nombre limité d’éléments peuvent prendre cet état : liens, boutons, éléments de formulaire.
Voir le pen Image with « clic to zoom » overlay par Twikito (@Twikito) sur CodePen.
[HTML]
Dans cet exemple, simplement une image dans un lien.
[CSS]
Ici, le principe est de placer un pseudo-élément au dessus de l’image pour afficher cette loupe au survol.
Pour ce faire, mettez la propriété position: relative
sur le lien afin de spécifier à tous ses enfants de le prendre en référence de positionnement. Ainsi, puisque le pseudo-élément a::before
se trouve à l’intérieur du lien, la propriété position: absolute
, suivie de top: 0
right: 0
bottom: 0
left: 0
, fera en sorte qu’il le recouvre entièrement, qu’importe ses dimensions. Puis une opacité à 0 vous assure l’invisibilité à l’état normal.
Vous remarquerez la propriété content
effectivement présente, mais initialisée par une chaîne vide. Ici, je ne me sers pas du contenu de ce pseudo-élément, mais de son arrière-plan pour afficher une loupe en SVG encodé en base64.
Il ne vous reste plus qu’à spécifier la ou les propriétés qui doivent changer au survol — et focus — en sélectionnant a:hover::before
— et a:focus::before
—. Ici, vous changez simplement l’opacité… et voilà !
Ensuite, une version plus évoluée : prenons l’exemple d’un lien vers une galerie de photos.
Voir le pen Picture hover effect with pseudo-elements par Twikito (@Twikito) sur CodePen.
[Result]
Ici, je me sers des deux pseudo-éléments afin de simuler une superposition de photos. Je les fais recouvrir le lien de la même façon que dans l’exemple précédent, mais cette fois je les place derrière l’image par un z-index: -1
.
[SCSS]
Je donne la même apparence à l’image et aux pseudo-éléments : fond blanc et ombre portée. Une légère rotation différente sur chacun des trois me permet d’obtenir cette impression de superposition, et une image différente en arrière-plan de chaque pseudo-élément termine l’état initial.
Enfin, il suffira d’appliquer une translation sur les pseudo-éléments lors du survol et focus pour terminer l’effet choisi. Bon… après vous pouvez ajouter du scale, du filtre, toussa pour affiner l’effet waouh, ça marche toujours ;-)
Des bubulles
Les infos-bulles sont une chose qu’on voit souvent sur le Web, et c’est triste de devoir charger un plugin jQuery pour ça. Je ne dis pas, quelque fois ce sera nécessaire, mais dans la plupart des cas, non. Voici comment faire.
Voir le pen Tooltip with pseudo-element par Twikito (@Twikito) sur CodePen.
[SCSS]
Forcément, vous spécifiez le lien comme référence avec une position: relative
, puis son pseudo-élément ::before
— ou ::after
, comme vous voulez — en position: absolute
afin de le déplacer librement. Vous choisissez son emplacement — ici, au dessus — puis vous ajoutez une opacité à 0 pour son état initial.
Vous remarquerez la propriété content
, cette fois initialisée à attr(title)
afin que le contenu généré corresponde à la valeur de l’attribut title
de l’élément ciblé — ici le lien.
Il ne reste plus qu’à mettre l’opacité à 1 lors du survol et focus — et une petite translation, pourquoi pas — et l’info-bulle est terminée. C’était simple.
[HTML]
Malheureusement, il y a un inconvénient avec cette technique : si vous voulez insérer des retours à la ligne dans votre info-bulle, vous devrez obligatoirement spécifier une largeur à votre pseudo-élément, ce qui peut être assez contraignant.
Si toutefois vous souhaitez une alternative en JS, je vous conseille la version accessible de Nicolas Hoffmann.
Le contenu dupliqué tu éradiqueras
Dupliquer du contenu en HTML, c’est mal ! Ne le faites pas !
Mais si l’effet voulu impose de dupliquer du contenu… ne le faites toujours pas ! C’est moche, ça pue, et vous serez pendu haut et court pour ça.
Vous pouvez par contre le faire sans problème par CSS.
Voir le pen Item menu effect with pseudo-element par Twikito (@Twikito) sur CodePen.
[HTML]
Tout ce que vous avez à faire, c’est mettre le même texte dans un data-*
attribut sur votre lien.
[SCSS]
Puis le récupérer dans la propriété content
de votre pseudo-élément avec attr(data-*)
. Vous faites ensuite ce que vous voulez avec.
Une version un peu plus évoluée ?
Voir le pen Menu item 3D effect on hover with only css par Twikito (@Twikito) sur CodePen.
[HTML]
Ici, le contenu du lien est placé dans une <span>
afin de le déplacer indépendamment des pseudo-éléments, mais le reste est sur le même principe.
Fun with forms
Oui c’est sûr, les formulaires, c’est relou à designer.
Alors quitte à devoir le faire, autant s’amuser un peu, non ?
Voir le pen Input focus effect with only CSS par Twikito (@Twikito) sur CodePen.
[HTML]
Ici, l’important est l’élément parent <div>
qui servira de référence pour placer tous les éléments nécessaires. Ensuite, le champ de saisie doit impérativement se situer avant son label associé — avec l’attribut for
— dans le code HTML.
Le principe est de simuler un placeholder
avec le <label>
en le plaçant derrière le champ de saisie — qui doit donc avoir un background: none
. Ainsi, lorsque vous donnez le focus à celui-ci, vous pouvez déplacer le <span>
qui se trouve à l’intérieur du label — comme ça le label reste en place — et vous pouvez vous amuser avec ses pseudo-éléments.
[SCSS]
Dans la .demo1
, chacun des pseudo-éléments recouvre la moitié de la surface.
Dans la .demo2
, chacun représente un trait.
Dans la .demo3
, uniquement besoin d’un seul pseudo-élément et d’un SVG en arrière-plan de celui-ci.
Et vous n’avez plus qu’à les bouger au focus du champ de saisie, grâce au sélecteur input:focus + label::before
et input:focus + label::after
, qui vous est permis justement parce que vous avez fait attention de bien placer l’élément <input>
avant son <label>
.
[Result]
Une petite subtilité cependant : vous remarquerez que le <span>
ne revient pas à son état initial lorsqu’un <input>
renseigné perd le focus. C’est son attribut required
qui me permet d’utiliser la pseudo-classe :valid
pour obtenir cet effet.
Attention : si vous changez le type du champ de saisie par email — par exemple —, la pseudo-classe :valid
ne correspondra non plus à un champ simplement renseigné, mais bien à un champ renseigné par une adresse email. Vous ne pourrez plus vous reposer sur cette pseudo-classe et devrez avoir recours au JS.
Allez, un autre petit effet sur le même principe, que j’affectionne particulièrement.
Voir le pen Input awesome effect on focus with only css par Twikito (@Twikito) sur CodePen.
[HTML]
Ici, vous trouverez de la même façon une <div>
en parent, puis à l’intérieur, un <input>
et son <label>
, et enfin un <span>
dans ce label.
[SCSS]
Le principe est donc le même. Je m’assure simplement de la bonne superposition des éléments et pseudo-élément — du label — afin de placer le <span>
au dessus — qui simule toujours un placeholder
— et le label::before
derrière tout le monde.
Celui-ci se retrouve en position: fixed
. Il prend alors le viewport en référence, c’est à dire l’espace d’affichage du navigateur. Je fais en sorte qu’il recouvre tout cet espace avec top: 0
right: 0
bottom: 0
left: 0
, et voilà.
Si je m’étais arrêté là, un clic sur le pseudo-élément — celui qui recouvre tout — provoquerait en fait un clic sur le label — son parent — et donc du même coup un focus sur son input associé… ce qui signifie que je ne pourrai jamais faire disparaître ce pseudo-élément. C’est balo, hein ?
La simplicité réside — oui, dans l’alcôve bleue, et jaune, et mauve — dans la propriété pointer-events: none
. Ainsi, le pseudo-élément n’interceptera pas les événements du pointeur, laissant les éléments derrière lui les capter. Je peux donc cliquer en dehors du label, et donc perdre le focus de l’input.
Attention tout de même à la compatibilité de pointer-events
.
Allez, un dernier sur les formulaires.
Voir le pen Realistics radio buttons with only css par Twikito (@Twikito) sur CodePen.
[HTML]
Ici, chaque ligne est un label. Les divisions ne me servent qu’à mettre des marges. Ces labels sont précédés de leur checkbox associé. Encore une fois, ce placement est important.
[SCSS]
La première chose à faire est de rendre ces checkboxes invisibles — opacity: 0
— et un positionnement absolu fait en sorte qu’ils ne prennent pas de place dans le flux.
Ensuite il faut s’occuper du switch : le pseudo-élément ::before
du label me sert de fond et le ::after
de “bouton” — ou l’inverse, comme vous voulez —, tout deux positionnés en absolu pour les placer librement.
Un clic sur le label provoquera le changement d’état du checkbox associé. Une fois que vous avez designé les pseudo-éléments du label, il ne vous reste plus qu’à déplacer le “bouton” lors du check du checkbox grâce au sélecteur input:checked + label::after
.
[Result]
Bon évidemment j’aurai pu faire plus simple, mais avouez que ça a plus de gueule comme ça, non ? ;-)
Les compteurs
Une valeur intéressante de la propriété content
est le compteur automatique. Prenons l’exemple d’un cas classique de tunnel d’achat.
Voir le pen Breadcrum for shopping path with only css par Twikito (@Twikito) sur CodePen.
[HTML]
Une liste de liens, tout ce qu’il y a de plus simple.
[SCSS]
Vous allez déclarer un compteur grâce à counter-reset: step
sur l’élément <ul>
— par exemple — puis décider de l’élément qui incrémentera ce compteur avec counter-increment: step
. Ici, c’est donc chaque lien qui incrémentera automatiquement le compteur “step”, par défaut de 1. Ensuite vous récupérez ce compteur dans le content
du pseudo-élément a::before
par content: counter(step)
. Et voilà.
Vous pouvez bien sûr aller plus loin en imbriquant les compteurs. Et aucun problème niveau compatibilité.
Garder un ratio l/h
Garder le ratio largeur/hauteur n’est décidément pas une chose simple à réaliser sur le Web. Le plus souvent, vous ferez le calcul par JS, puis appliquerez les valeurs en style inline.
Voici une manière — pas — simple de réaliser cette opération via CSS. Attention c’est tricky — ne jamais dire ça en public.
Voir le pen Keep the ratio w/h of an element with CSS par Twikito (@Twikito) sur CodePen.
[Result]
Pour voir que le ratio largeur/hauteur est bien conservé, éditez sur CodePen et redimensionnez la fenêtre.
[JS]
No JS !
[HTML]
Des <div>
et des <span>
imbriqués. C’est tout.
[SCSS]
Les margin
et padding
sont des propriétés à priori simples à comprendre et à manipuler, mais qui cachent une subtilité de taille : leurs valeurs exprimées en pourcentage sont un rapport de largeur. C’est à dire que si vous spécifiez sur un élément une margin
en haut et en bas en pourcentage, il s’agira d’un pourcentage de la largeur de son élément parent référent, et non pas sa hauteur — idem pour les padding
. Votre rapport à exploiter se trouve donc ici.
Dans cet exemple — fortement inspiré de BADA55.io —, je veux que les carrés restent carrés, même en responsive. Pour ce faire, je définis la division comme référence avec une position relative, puis la recouvre avec le span en le positionnant en absolu, et tous ses côtés à 0. C’est dans ce <span>
que vous mettrez votre contenu.
Enfin — et c’est là que la “magie” opère —, pour forcer une hauteur à la division, il lui faut un flux interne. Je m’occupe donc de son pseudo-élément ::before
: je donne à son padding
du haut ou du bas une valeur de 100%, c’est à dire donc 100% de la largeur de son parent, la division. Vous avez donc votre rapport 1:1.
Le <span>
étant positionné en absolu, le pseudo-élément est seul dans le flux de la <div>
. Elle restera carrée. Évidemment ça marche aussi avec d’autres rapports.
Attention toutefois : comme je le disais, ce trick est valable avec les padding
, mais aussi les margin
. Cependant dans ce dernier cas, vous devrez vous assurer que votre élément parent est bien un contexte d’affichage.
Améliorer l’UX ?
Évidemment il est possible d’améliorer l’UX de votre site grâce aux pseudo-éléments :
Voir le pen UI with UX improvement with only css par Twikito (@Twikito) sur CodePen.
[Result]
N’hésitez pas à consulter cet exemple en pleine page pour avoir réellement l’expérience voulue. Notez qu’il est possible d’observer quelques ralentissements, malheureusement dus à l’effet de flou filter: blur(2px)
. Désactivez-le ci nécessaire.
Ici, il y a trois concepts : l’icône ‘burger’ qui se transforme en croix, le fond du menu de biais, et la zone en dehors du menu ouvert qui permet de le refermer.
Les améliorations d’UX via CSS que je vois ici sont cette icône qui s’adapte à la nouvelle action après ouverture du menu, et cette zone cliquable qui simplifie et rend plus naturelle l’action de fermeture du menu.
[JS]
Non, toujours pas de JS ! \o/
[HTML]
Nous sommes d’accord que j’ai besoin d’un élément qui comporte deux états possibles, tout comme le menu : ouvert et fermé. Je me sers donc d’un checkbox, que je cacherai par la suite. Comme dans les exemples précédents, il est important de placer cet élément avant tous les autres, et sans imbrication. Ensuite, un <label>
pour l’icône, un <nav>
et un <main>
, tous adjacents.
[SCSS]
D’abord voyons le menu. Je le positionne en fixé sur toute la hauteur de la fenêtre, puis le translate en dehors vers la gauche pour son état initial. Je ne lui met pas de fond : c’est son pseudo-élément ::before
qui va le simuler. Je le positionne quant à lui en absolu — son parent le <nav>
est son référent — et en z-index: -1
pour qu’il se retrouve derrière. J’opère ensuite une transformation skew
pour lui donner son apparence de biais, et translateX
pour le rendre prêt à dégainer un peu plus loin sur la gauche. Il ne reste plus qu’à déplacer tout ça au checked
du checkbox grâce à [id="navcheck"]:checked ~ nav
et [id="navcheck"]:checked ~ nav::before
.
Ensuite, le ‘fameux’ <label>
.
J’ai construit l’icône ‘burger’ — malheureusement, on la demande encore — dans le label pour pouvoir interagir avec son checkbox associé. Cependant, je ne me sers de ce label que de conteneur sans autre style particulier.
À l’intérieur se trouve l’élément de classe burger
qui comporte un <span>
avec du texte — pour les lecteurs d’écran — qui fait office de barre du milieu, et ses deux pseudo-éléments qui font les barres du haut et bas. Lors du clic sur le label — ce qui coche le checkbox — je manipule ce span et les pseudo-éléments pour transformer cette icône en croix.
Maintenant, la fourberie : ce label comporte un autre pseudo-élément. J’ai ajouté un pseudo-élément label::before
, qui se trouve donc adjacent au .burger
. C’est celui-là qui va me servir de zone cliquable pour refermer le menu.
Dans cette page, vous avez une superposition de trois éléments — et pseudo-élément — en position: fixed
, tous donc dépendants du viewport : la zone cliquable, le menu et l’icône, tous rangés respectivement dans cet ordre par z-index
… et là vous avez compris. La zone est derrière, le menu par dessus, et l’icône tout devant pour rester toujours visible.
Attention tout de même, cette technique peut facilement provoquer du repaint sur navigateur de smartphone. Afin d’éviter cela, la zone est en fait déjà en place à l’état initial — elle recouvre toute la page — et je ne joue que sur son opacité lors de l’affichage du menu. Et pour éviter que ce pseudo-élément ne capture le clic sur toute la page — ce qui provoquerait l’ouverture du menu n’importe où —, je lui mets un pointer-events: none
à son état initial et le remets à auto
lorsque le menu s’ouvre. Et voilà.
Grâce à cette technique, vous pouvez gérer l’ouverture et fermeture améliorée d’un menu par checkbox, ou par simple toggleClass
sur deux éléments via JS.
Des filtres d’images comme toshop
Allez, un dernier pour la route que j’ai découvert alors que je rédigeais ce long article : CSSgram de Una Kravets.
Le principe est en fait très simple : une <figure>
contenant une <img>
, puis un pseudo-élément ::after
sur cette <figure>
placé pour recouvrir toute l’image. Vous mettez un filter
sur l’image, puis une couleur d’arrière-plan et un mode de fusion avec mix-blend-mode
sur le pseudo-élément en fonction de l’effet voulu, et c’est tout.
Évidemment, pensez à consulter la compatibilité de filter
et de mix-blend-mode
avant de les utiliser.
Article::after{content:‘conclusion’;}
J’aurais pu continuer, mais on me dit dans l’oreillette que ça suffit.
Ces quelques exemples vont auront démontré deux choses :
La première est que vous pouvez simplement — d’accord, pas tout le temps — séparer la structure et la mise en forme, même pour des interfaces ou des interactions évoluées grâce aux pseudo-éléments. Vous pourrez ainsi garder un code propre et performant, et vous passer de JS dans la plupart des cas.
La deuxième est qu’il suffit bien souvent d’y penser ! Faire preuve d’imagination et de créativité, c’est possible aussi pour les codeurs ! (~˘▾˘)~
Merci d’avoir lu jusqu’ici, et j’espère vous avoir inspiré. N’hésitez pas à laisser vos commentaires, ou à venir me parler sur Twitter.
Et high five à Geoffrey Crofte pour le titre de cet article, assez badass ! ;-)
À retenir
- Compatibilité des pseudo-éléments
::before
et::after
sur CanIUse (anglais) - La propriété
content
sur MDN - Les sélecteurs d’attribut sur MDN
- Les compteurs CSS sur MDN et leur compatibilité sur CanIUse (anglais)
- Les containing blocks expliqués par Vincent de Oliveira
- Les contextes d’affichage expliqués sur Alsacréations
- Les problématiques de repaint et reflow (anglais)
- La propriété
pointer-events
sur MDN et sa compatibilité sur CanIUse (anglais) - La propriété
mix-blend-mode
sur CSS-Tricks (anglais) et sa compatibilité sur CanIUse (anglais) - La propriété
filter
sur MDN et sa compatibilité sur CanIUse (anglais) - Le plugin jQuery de tooltip accessible par Nicolas Hoffmann sur GitHub
- Votre récompense lorsque vous utilisez des pseudo-éléments
17 commentaires sur cet article
MoOx, le vendredi 4 décembre 2015 à 08:51
Simple question : pourquoi ne faut-il pas dupliquer du contenu en HTML ? Quel est le problème (si ce n’est qu’on risque d’être pendu) ?
Nathan Peixoto, le vendredi 4 décembre 2015 à 09:02
@MoOx : Ça pose des problèmes de référencement ?
@rbwebdev, le vendredi 4 décembre 2015 à 09:26
Encore une preuve de la puissance de CSS, je suis cependant agréablement surpris par les compatibilités.
Très bon article, ne reste plus qu’à mettre en application.
J’ai récemment mis en place sur un site « drawsvg », avec du js. Le rendu est plutôt pas mal, je te laisse jeter un œil à la démo :
http://lcdsantos.github.io/jquery-drawsvg/#demos
Matthieu Bué, le vendredi 4 décembre 2015 à 09:52
@MoOx > Ça pose des problèmes de référencement, et niveau accessibilité c’est pas génial non plus, mais je vois ça surtout comme une bonne pratique.
Twidi, le vendredi 4 décembre 2015 à 10:17
Merci pour cet article que je suis encore en train de lire.
Je m’arrête cependant sur ce point :
« […] dupliquer l’effet au focus. Sachez toutefois qu’un nombre limité d’éléments peuvent prendre cet état : liens, boutons, éléments de formulaire. »
Je dirais que ce n’est pas exactement vrai. Même un DIV ou un P peut avoir le focus si il lui est attribué un « tabindex » (par exemple la valeur ‑1 pour que la navigation via la touche « tab » ne s’y arrête pas)
On peut le voir sur cette page an ajoutant « tabindex=-1 » sur p.author-description puis en ajoutant ce style :
p.author-description:focus {
background : red ;
}
Nico, le vendredi 4 décembre 2015 à 10:22
Woot, ça envoie bien tes idées, j’adore. :)
Même mes grandes gueules de collègues (pour eux :p) ont halluciné sur le burger-icon et le formulaire qui se casse en deux, je viens de leur montrer.
Perso, une technique toute simple/basique mais qui est super-cool avec les pseudo-éléments : un bloc qui contient un lien, et rendre tout le bloc cliquable. Un pseudo-élément sur le lien, positionné en absolu, top/left/right/bottom à 0, un relatif sur le bloc, et la magie opère =>
– pas de contenu/code dupliqué ;
– pas de problème de rendu de plusieurs liens avec les synthèses vocales si y a des éléments block dans des éléments inline ;
– pas d’intitulé de lien non-sensique ;
– et ça marche partout.
Histoire de rigoler, une anecdote : en expliquant à ma gentille stagiaire l’utilisation de Voice Over sur iPad, on a eu un cas très rigolo sur un pseudo-élément. J’avais signalé les liens externes ainsi : content : » ↗ »
En utilisant la synthèse vocale de l’iPad, le lien a été vocalisé ainsi : « lien flèche Nord-Est ». Un petit speak : none ; sur le pseudo-élément a solutionné ce petit souci. :)
Sacripant, le vendredi 4 décembre 2015 à 10:44
Très jolie série d’exemples. Merci, je bookmark :).
J’ai une question sur ton dernier exemple :
Je sais que l’utilisation d’un checkbox + :checked est une bonne solution « pur CSS » pour gérer un toggle. Mais j’ai vraiment un blocage cognitif à utiliser un label et un checkbox en dehors d’un form. Sémantiquement, il ne faudrait pas utilisé un ou un ancre vers l’id de la nav ? Ça ne pose pas de problème d’accessibilité ?
Cédric Clavier, le vendredi 4 décembre 2015 à 11:12
Super article, pleins de nouveaux horizons s’ouvrent à moi grâce à la puissance des pseudo-element
Merci
Nicolas Chevallier, le vendredi 4 décembre 2015 à 12:46
Excellente présentation, j’ai vraiment été bluffé des possibilités offertes par les pseudo sélecteurs, le problème pour des projets importants étant (toujours) la compatibilité avec les navigateurs IE anciens… Vivement que Edge remplace IE !
MoOx, le vendredi 4 décembre 2015 à 14:42
Avez-vous des ressources sur les problèmes de référencement ?
Pour l’accessibilité, il y a moyen d’indiquer quand des éléments HTML sont à ignorer il me semble.
Matthieu Bué, le vendredi 4 décembre 2015 à 20:10
@Nico > Effectivement, mettre le lien au plus proche du texte permettrait d’éviter les problèmes avec les synthèses vocales. Par contre, je crois que speaker : none ; n’est pas correctement interprété par toutes les synthèses, mais c’est à mon sens la bonne façon de faire ;-)
@Sacripant > Effectivement, utiliser des éléments de formulaire en dehors d’un formulaire est assez « risqué », mais on peut changer l’interprétation en modifiant les rôles. Après, ici c’était surtout pour l’exercice « full css » :-)
@MoOx > Effectivement il y a moyen, mais avoue que c’est quand même bien mieux de ne mettre qu’une et une seule fois le contenu, non ? Pour les ressources : https://support.google.com/webmasters/answer/66359?hl=fr et http://www.webrankinfo.com/dossiers/techniques/contenu-duplique :-)
Anthony Deruywe, le vendredi 4 décembre 2015 à 21:05
@MoOx , outre le problème d’accessibilité, « pondre » du contenu via un pseudo-élément est une plait pour les sites Multi-langues, rien de simple ou de « propre » ne permet de faire la traduction. C’est mon point de vue, et bien sur si vous connaissez une solution a ce problème je suis preneur.
Une petite ?
Geoffrey, le samedi 5 décembre 2015 à 13:29
Hey, très bon article :)
Je vois que tu as mis ton effet « burger » à jour avec un filter. J’ai tendance à l’utiliser sur mes fonds de fenêtres modales en ce moment, ça fait son effet.
See ya !
Marie Guillaumet, le lundi 7 décembre 2015 à 18:58
Merci Matthieu pour ces exemples créatifs ! Tes idées sont chouettes.
C’est hyper agréable de voir des démos CSS écrites par un vrai inté, accessibles, sémantiques, et interopérables, parce que mine de rien, le web pullule d’exemples qui ne fonctionnent que dans Webkit Canary. Le problème de ce genre de démos, c’est qu’elles sont souvent copiées/collées aveuglément, souvent dans le rush ; or, c’est comme ça qu’on dégrade le web. Bref !
C’est vrai que les pseudo éléments pour skinner les éléments de formulaire de façon accessible au clavier, ça poutre ; je trouve que ta démo avec les « switch » est top, même si j’ai un petit doute sur l’accessibilité du compteur.
J’apprécie aussi l’approche « sans JS », car c’est vrai qu’on a facilement tendance à penser « JS first » quand on pense une interface, alors que CSS permet de réaliser énormément de choses. (Je repense à ce dev qui était mal en point de devoir recalculer le positionnement d’un élément en JS par rapport au viewport, alors qu’il lui manquait juste un position : relative CSS sur le parent du dit élément… ^.^;)
@Anthony Deruywe : si tu utilises la méthode content : attr(data-text); indiquée par Matthieu dans une de ces démos, tu peux facilement récupérer le contenu déjà traduit d’un élément présent dans le DOM et le réutiliser en CSS.
Nico, le vendredi 11 décembre 2015 à 11:41
@ Anthony Deruywe :
:lang(fr) > .ton_sélecteur ?
Matthieu Bué, le lundi 14 décembre 2015 à 12:00
@Nico > Roh le CSS win ! \o/
François, le jeudi 24 décembre 2015 à 15:22
Wow ! J’adore quand le « code » stimule la créativité et cet article est une mine d’or : merci Matthieu.
J’avais utilisé la solution « tricky » pour un projet afin de conserver un ratio l/h : cela fonctionne très bien.
Merci encore pour ce bel article ;-)