Suite à un test de Xavier Zalawa (@7studio sur twitter) sur un menu Lavalamp en CSS, j’ai voulu le tenter aussi mais sans utilisation d’élements supplémentaires. Je suis donc passé par les pseudo-éléments, mêmes si ceux-ci leur animation n’est pas encore supportée partout.
Note : en utilisant une technique différente (par @kizmarh), ce même menu devient compatible avec tous les navigateurs supportant les transitions CSS. La démo est en ligne sur CodePen.
Principe de l’exemple
Lors du survol d’un li
du menu, le pseudo-élément ::after
du dernier li
est modifié. C’est cet élément qui crée la barre rose en dessous du menu.
Pour cela, j’utilise le sélecteur (tilde) qui permet de sélectionner le dernier li
frère, comme ceci :
li:hover ~ li:last-child::after{
/* modification de la taille et de la position */
}
De plus, les tailles sont fixées en em
, ce qui permet un redimensionnement de la taille du texte.
Il reste des problèmes. Dommage...
L’état :focus
est géré, mais pas identique au :hover
, puisque le :focus
s’applique sur les a
et non sur les li
. Il est donc impossible de sélectionner le dernier frère d’un parent d’un lien...
Mais surtout, les transitions (et animations) CSS appliquées aux pseudo-éléments ne sont compatibles qu’avec un nombre limité de navigateurs (pour le moment).
Code complet utilisé
<ul>
<li><a href="#">✿</a></li><!--
--><li><a href="#">Lorem</a></li><!--
--><li><a href="#">Ipsum</a></li><!--
--><li><a href="#">Consectetur adipisicing</a></li><!--
--><li><a href="#">Sit amet</a></li>
</ul>
PS : les commentaires entre les li
permettent d’éviter le problème de white-space bien connu.
ul{
position:relative;
height:2em;
margin:30px 100px;
padding:0;
white-space:nowrap;
}
ul li{
display:inline;
text-align:center;
}
ul li:nth-child(1) a{width:2em;}
ul li:nth-child(2) a{width:4em;}
ul li:nth-child(3) a{width:4em;}
ul li:nth-child(4) a{width:12em;}
ul li:nth-child(5) a{width:5em;}
ul li a{
display:inline-block;
box-sizing:border-box;
padding:.4em .2em;
color:#51C3FA;
text-decoration:none;
text-shadow:0 1px 0 white;
background-color:transparent;
transition:background-color .3s ease;
}
ul li a:hover,ul li a:focus{
color:#c351fa;
background-color:rgba(255,255,255,.4);
transition:background-color .3s ease .4s;
}
ul li a:focus{
border-bottom:3px solid #c351fa;
}
ul li:last-child::after{
content:"";
position:absolute;
left:0px;
bottom:-3px;
display:block;
width:2em;
height:3px;
background:#ccc;
border-bottom:1px solid rgba(255,255,255,.8);
transition: all .5s ease;
}
ul li:hover ~ li:last-child::after,
ul li:last-child:hover::after{background:#C351FA;}
ul li:nth-child(1):hover ~ li:last-child::after{left:0;width:2em;}
ul li:nth-child(2):hover ~ li:last-child::after{left:2em;width:4em;}
ul li:nth-child(3):hover ~ li:last-child::after{left:6em;width:4em;}
ul li:nth-child(4):hover ~ li:last-child::after{left:10em;width:12em;}
ul li:last-child:hover::after{left:22em;width:5em;}
Note : Attention, le code CSS présenté ici n’est pas préfixé.
Tous vos retours sont appréciés !
#1par Geoffrey, le 19 janvier 2012
Génial !
Je m’étais penché sur la chose en essayant de trouver une méthode "automatique" pour ne pas avoir à donner manuellement la dimension du pseudo-élément, mais, ce fut un désastre.
Pour la gestion du focus il va falloir attendre les sélecteurs de CSS4, mais là c’est déjà bien :D
Bravo !
PS : ta méthode de sélection au cas par cas avec nth-child me rappelle qu’il existe une méthode CSS2, pour les curieux : http://blog.goetter.fr/post/1330959...
#2par Kikimagik, le 26 janvier 2012
Une petite question me turlupine... Cela n’a rien à voir avec ton test ci-dessus désolé : comment sur ton "textarea", celui par lequel j’écris actuellement ce message, bloque tu son étirement sur l’horizontal ?? Une question à laquelle je ne trouve pas de réponse, sauf ici ou je remarque qu’il est impossible d’étirer le "textarea" sur sa largeur !
#3par css3create, le 26 janvier 2012
@Kikimagik : Tu as 2 solutions :
Utiliser les
min-width
,max-width
etwidth
surtextarea
.Utiliser la règle CSS prévue pour ça :
resize: both, vertical, horizontal ou none
#4par moioli888, le 29 janvier 2012
Encore un super example... Et un grand merci d’avoir mit le code source ! :)
#5par Kikimagik, le 1er février 2012
Je te remercie pour toutes tes infos, tous tes tutos, et toutes cette bonne volonté que tu nous fais partager à travers chaque démos. Cela fais plaisir d’avoir des développeurs comme toi. Continue ainsi !
#6par G11, le 1er février 2012
Pas trop dur avec les dc ?
#7par Beben Koben, le 22 février 2012
Awesome web, glad can be here ♥
Nice to meet you master ☻
Beben Koben si bloglang anu ganteng kalem tea \m/
#8par meetic, le 12 mars 2012
merci
#9par TUF, le 18 mars 2012
Merci pour ce post, ça m’as bien aidé ! J’ai réussi a un faire un menu du même style mais compatible gecko, webkit et firefox. J’ai en faite ajouté un li vide en dernière position que je déplace et agrandis en fonction du qui est survolé. Je le séléctionne de cette manière :nav ul #id du li:hover #border (#border étant le li vide).
Je ne sais pas si vraiment très diffèrent de ton menu mais ça permet d’éviter l’utilisation de pseudo-élément.
#10par css3create, le 18 mars 2012
@TUF : Oui c’est très bien ! C’est exactement le principe du menu de Xavier que j’ai cité en introduction. Ici, je voulais justement me passer de cet élément supplémentaire.
#11par TUF, le 18 mars 2012
Ha oui exacte, je n’avais pas vu ce lien ! Merci, bonne continuation :)
#12par Manumanu, le 26 mars 2012
Je me demandais, pourquoi utilises-tu ::after / ::before au lieu de simplement :after / :before ?
#13par Manumanu, le 26 mars 2012
Après quelques recherches, je viens de trouver qu’il s’agissait de la dénomination de pseudo-éléments pour la différencier des pseudo-classes :after et :before. Sauf que je ne comprend pas leur but, sachant que l’association de plusieurs pseudo-classes fonctionne très bien, et que rien n’y oppose de contre-indication...
Du coup, ma question se porte sur les exemples du site (page "after-before"), ou cette fois tu emploies donc ces pseudo-éléments sur des éléments réels, sur lesquels sont applicables des pseudo-classes directement (ainsi que d’autres fois dans les tutoriels) : Pourquoi ?
#14par gcyrillus, le 29 avril 2012
Bonjour,
Pour le focus sur les item de liste "LI" , c’est faisable avec l’attribut "tabindex" qui fait parti des attributs "globaux" en html5.
#15par H3, le 6 mai 2012
Magnifique !
#16par Mow. , le 13 mai 2012
Super ! comme tout le reste du site d’ailleurs... ( ;
Un grand merci !
#17par Matt, le 17 septembre 2012
Merci beaucoup pour ce tuto, très beau design en passant. Cependant j’ai un petit souci, je souhaiterais mettre des sous-menus sur quelques onglets du menu, mais en bidouillant un peu ton code je n’y parviens pas, aurais-tu une solution ? Merci d’avance.
#18par Alban, le 23 janvier 2013
Fonctionne seulement sous firefox apparemment ?
#19par css3create, le 25 janvier 2013
@Alban : Fonctionne sous Firefox, IE10 et bientôt dans Chrome 26. :)
#20par Renaud, le 3 février 2013
Bonjour, j’ai testé et modifié quelque peu le code, et c’est super propre, merci beaucoup pour ce petit exemple ;) continuez comme ça !
#21par SymSym, le 11 mai 2013
Bonjour, j’ai voulu modifier le code HTML pour que le menu montre : Accueil, Liens extérieurs, Commentaires et Contact, mais le résultat n’est pas le même que ce que j’espérais : les soulignements au :hover sont soit trop petits, soit trop grands. J’ai essayé d changé le code CSS, mais sans succès. Est-ce que quelqu’un peut m’aider ?
#22par stefde3, le 29 mai 2013
Bonjour,
moi j’essaye de centrer ton menu car j’aiemerai qu’il soit au milieu de ma page... les liens s’y mettent bien mais le "li:last-child ::after" lui reste coller à gauche à cause du "position:absolute" mais en "relative" il part de la droite vers la gauche. Jai essayé un left:50% margin-left :-250px mais là encore ça colle pas... un petit coup de pouce stp css3create ou un autre ?
Merci d’avance
Sinon merci à toi c’est justement ce que je cherchais ;)
#23par stefde3, le 30 mai 2013
je tiens à signaler que sous IE9, il n’est pas fonctionnel ce code. y a t’il une solution pour y remédier ?
#24par SymSym, le 4 juin 2013
Bonjour, je voulais signaler que ce code marche parfaitement bien bien pour Google Chrome.
#25par rhaine, le 13 janvier 2014
Salut, juste pour signaler une erreur de code css que vous donnez.
A un moment il est écrit : "lastchild", tandis qu’il faut utiliser "last-child", cette erreur ne se trouve pas dans le code source du site (de la demo).
Cette erreur empêche le changement de couleur du trait lors de sa position initiale.
Cdlt
#26par css3create, le 15 janvier 2014
@rhaine : Bien vu ! :)