28172 sujets

CSS et mise en forme, CSS3

Bonjour à tous !

Je me décide à ouvrir un compte sur ce forum pour enfin lever l'ombre sur des questions profondes de code...

Voilà : Je souhaite colorier un élément <li> spécifique en orange :

<div class=menu">
	<ul>
		<li><a href="#">AGENCE</a></li>
		<li><a href="#" class="orange">PROJETS</a></li>
	</ul>
</div>


J'ai déjà une classe orange que j'utilise pour d'autres éléments, mais pour des raisons de priorité des selecteurs, j'ai besoin de spécifier cet élément <li> :

.orange {color:#FEC465; }
.div.menu ul li a.orange {color:#FEC465; }


Je me retrouve donc avec deux fois l'écriture de la classe orange. Ça a pas l'air très propre. Devrais-je donner un nom différent à la deuxième classe ? Comment le navigateur interprète-t-il ce double nommage ?

Merci de vos avis éclairés !
Modifié par acarchi (10 Jun 2014 - 09:49)
Modérateur
Bonjour,

Pour moi tu peux déjà regrouper les sélecteurs (mais c'est plus une question de propreté / maintenabilité du code) :

.orange,
.div.menu ul li a.orange{
   color:#FEC465;
}


Petit article intéressant sur la question http://openweb.eu.org/articles/les-performances-vues-des-css (voir vers la fin la partie "Quid des sélecteurs efficaces").

Extrait 1 :
Premier rappel : un sélecteur efficace peut se définir comme un sélecteur évitant au moteur du navigateur trop d’analyse pour appliquer les styles.
Exemple : #header ul li a.header-link est un sélecteur trop long

Extrait 2 :
Par exemple : .header a semble être un bon sélecteur : court et précis. Le développeur va se dire en l’écrivant : le navigateur va aller prendre tous les a dans .header. Or, cela ne se passe pas du tout comme cela pour le navigateur !
Ce dernier va évaluer cette règle CSS de droite à gauche, autrement dit, il va cibler tous les liens a de la page, et regarder ensuite ceux qui se situent dans .header.

L'extrait 2 est pour moi l'argument le plus percutant pour avoir des sélecteurs courts... Cependant il y a un juste milieu a trouver je pense. Si on se limite a 1 classe par sélecteurs on perd une des forces du css (styler tout les "li a" en 2 caractères).

Pour ma par je m’efforce d'avoir les sélecteurs les plus court possible dans la limite du pratique. Par exemple préférer un ".menu a" à un ".menu ul#navigation li a"...

Si tu ne peux overrider qu'avec un sélecteur long comme un bras ".div.menu ul li a.orange" c'est que le selecteur qui prend le dessus est peut etre trop spécifique Smiley murf
Modifié par _laurent (04 Jun 2014 - 16:58)
Merci pour ces conseils.

J'ignorais que le navigateur évaluait la règle CSS "de droite à gauche" ! Cela me permet de raccourcir le sélecteur et également comme tu le suggères de réduire "le sélecteur qui prend le dessus".

Reste la question, devrais-je donner un nom différent à la deuxième classe ? Comment le navigateur interprète-t-il le double nommage :
.orange {color:#FEC465; }
.menu a.orange {color:#FEC465; }
Modérateur
Après comme il dit dans son article ça devient de la "micro optimisation" ! Smiley ravi
Mais le sujet n'en reste pas moins intéressant.

Pour l’interprétation droite gauche, en fouillant j'ai trouvé cet article https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Writing_efficient_CSS qui remet une couche sur ce principe : "As long as the selector’s subtree continues to check out, the style system continues moving to the left until it either matches the rule, or abandons because of a mismatch."
Je l'ai découvert récemment avec le premier article que je t'ai passé et c'est vrai que je ne m'en doutais absolument pas ! Smiley ravi

Pour ta question ça m'a trituré et après quelques recherches le W3C me répond : http://www.w3.org/TR/CSS2/selector.html#grouping :
In this example, we condense three rules with identical declarations into one. Thus,

h1 { font-family: sans-serif }
h2 { font-family: sans-serif }
h3 { font-family: sans-serif }

is equivalent to:

h1, h2, h3 { font-family: sans-serif }


Ils restent donc indépendant.
Donc dans ton cas .orange {color:#FEC465; } .menu a.orange {color:#FEC465; } ou .orange, .menu a.orange {color:#FEC465; } reviennent au même (sauf niveau maintenabilité, propreté et économie de quelques caractères)

La vrai optimisation serait alors de modifier le premier sélecteur afin que ta classe .orange soit prise en compte direct !

Si jamais d'autres curieux peuvent apporter leurs avis...!

Merci pour le sujet j'ai appris des choses !

Bonne soirée
Modifié par _laurent (04 Jun 2014 - 17:40)
Super ! Merci pour tes interventions, j'avais peur de ne pas arriver à exprimer ma question. Effectivement il s'agit de "micro-optimisation", mais j'ai surtout envie de comprendre comment ça fonctionne ! Smiley biggrin

Le groupement est une solution, mais justement on voit dans l'exemple que h1 est différent de h2, est différent de h3. Or mon sélecteur orange a le même nom que l'autre sélecteur orange.

Dans un soucis de "propreté maximale", devrais-je renommer un des deux sélecteurs orange ? Que veux tu dire par " modifier le premier sélecteur afin que ta classe .orange soit prise en compte direct " ?
Modifié par acarchi (04 Jun 2014 - 17:46)
Modérateur
Le groupement est une solution, mais justement on voit dans l'exemple que h1 est différent de h2, est différent de h3. Or mon sélecteur orange a le même nom que l'autre sélecteur orange.

Ha oui je cerne mieux la question, désolé. Je pense que ça importe peu. C'est le nom de la classe qui est le même, les sélecteur sont totalement différent. Même si .orange {color:#FEC465; } et .menu a.orange {color:#FEC465; } tape sur le même élément et y applique le même style, ce sont deux "requêtes" différentes au même titre que h1 est différent de h2. Les deux sélecteurs sont fondamentalement différent et n'intègre qu'une classe en commun, ils pourrait taper chacun sur un élément différent. Je sais pas si ça répond bien a ta question...
Dans un soucis de "propreté maximale", devrais-je renommer un des deux sélecteurs orange ?
Je ne pense pas, ça reviendrait exactement au même niveau interprétation et par contre niveau "propreté" c'est, à mon avis, bien plus moche d'avoir deux classe différente pour la même propriété (mais c'est peut être personnel).
Que veux tu dire par " modifier le premier sélecteur afin que ta classe .orange soit prise en compte direct " ? 

Je reprend ce que tu as dis dans ton premier post :
J'ai déjà une classe orange que j'utilise pour d'autres éléments, mais pour des raisons de priorité des selecteurs, j'ai besoin de spécifier cet élément 

Le plus "propre" pour moi c'est de faire en sorte que tu n'ai pas ce problème de priorisation afin que ton seul selecteur .orange {color:#FEC465; } puisse être appliqué aussi à ton a

A quoi ressemble le sélecteur qui prend le pas sur ta classe orange ?
salut,
plus simplement, pour forcer la propriété, tu peux passer par "!important". Ton code devient

.orange {color:#FEC465 !important}

Par contre, ça voudra dire que si tu souhaites modifier cette couleur au ":hover", par exemple, tu devras à nouveau passer par "!important".
Modérateur
Bonjour Smiley smile

Zelalsan a écrit :
salut,
plus simplement, pour forcer la propriété, tu peux passer par &quot;!important&quot;. Ton code devient

.orange {color:#FEC465 !important}

Par contre, ça voudra dire que si tu souhaites modifier cette couleur au &quot;:hover&quot;, par exemple, tu devras à nouveau passer par &quot;!important&quot;.

Oui c'est une solution.... que perso je banni.

Le !important c'est vraiment le MAL Smiley angryfire à n'utiliser qu'en dernier dernier recours dans certaines situations (et encore).
Pas franchement poussée l'argumentation... Le "!important" s'utilise plus souvent que tu ne le penses (responsive design, styles d'impression...) et quand on maîtrise ce qu'on fait, c'est très rarement un problème.
La vrai question est plutôt de comprendre pourquoi passer par cette logique. Généralement, on peut établir une mise en page générale que l'on retrouvera sur l'ensemble du site. Si on veut passer par des classes pour donner des couleurs, ce n'est certainement pas pour réécrire à chaque fois les sélecteurs.
Dans ce cas précis, soit l'utilisation de classe est inutile, soit la réécriture du sélecteur est inutile.
Je suppose déjà que ce sélecteur
.div.menu ul li a.orange {}

pourrait s'écrire plus simplement
.div.menu .orange {}

J'ai vraiment l'impression que c'est compliqué pour rien.
Bonjour,

En plus de ce qui a été dit (enfin j'ai lu en diagonale faute de temps peut-être cela a-t-il déjà été relevé ^^), une manière simple d'augmenter la spécificité d'un sélecteur est de répéter le nom de classe ou d'ID :

.orange.orange { }


est équivalent à

.orange { }

mais son poids est double. Cela me semble une bonne alternative au discuté !important pour ne pas se prendre la tête avec les sélecteurs pour du responsive ou du print.

Ainsi, par exemple,
.menu a { }

serait surclassé par
.orange.orange { }

Après, si tu avais un id englobant tout ton contenu, un #contenu .orange suffirait à surpasser tous tes sélecteurs formés de noms d'éléments ou de classes.
Modifié par Candygirl (07 Jun 2014 - 11:12)
Je réponds avec latence, j'étais hors du réseau !

Merci à tous pour vos réponses, vous avez répondu à mes interrogations avec précision. Je comprends désormais comment les requêtes sont interprétées en arrière-plan.

Le "!important" était une solution effectivement, mais que je souhaitais éviter. Merci pour l'astuce de la répétition de la classe, que j'ignorais. Il est vrai qu'un "id" surpasserait le tout, mais c'était aussi une solution que je souhaitais éviter.

A une prochaine fois !
Pour répondre à _laurent :
"A quoi ressemble le sélecteur qui prend le pas sur ta classe orange ?"

Il ressemble à ça :

.menu li:nth-child(3) a:link {color:#FEC465;}

Modifié par acarchi (10 Jun 2014 - 16:32)