CSS un peu plus avancé
Les sélecteurs combinés
Jusqu'ici on a vu comment sélectionner un ou plusieurs éléments (par #id
, .classe
, ou tag
) afin de modifier leurs propriétés CSS. Et techniquement on pourrait s'en satisfaire, mais en faisant ça on se met à coller des classes et des ids partout et à devoir chercher des noms de classes alambiqués pour essayer de bien communiquer ce qui va et ne va pas ensemble.
,
On va commencer simple avec la virgule ,
qui nous permet de sélectionner plusieurs choses.
En admettant que l'on veuille retirer les puces dans nos <ul>
et les nombres dans nos <ol>
on peut écrire le CSS suivant
ul {
list-style: none;
}
ol {
list-style: none;
}
Mais avec la virgule on peut juste écrire ceci
ul, ol {
list-style: none;
}
Le sélecteurs ul,ol
signifiant "les <ul>
et les <ol>
"
Eh oui, beaucoup de gens pensent intuitivement que pour viser plusieurs éléments il faut juste séparer les différents sélecteurs par un espace
. Mais non, l'espace combine deux sélecteurs pour viser "les enfants de...".
article p {
}
Ce sélecteur combiné visera "les <p>
qui sont enfants d' <article>
"
donc...
<article>
<p>ce p est visé parce qu'il est dans un article</p>
<div>
<p>celui la aussi, même si ce n'est pas un enfant direct</p>
</div>
</article>
<p>par contre celui là non</p>
note : pas seulement les tags
Notez que pour tous ces opérateurs de combinaison, j'ai utilisé uniquement des tags pour les exemples, mais j'aurais très bien pu prendre des classes ou des identifiants.
ex: #presentation p
étant "tous les <p>
de l'élément ayant l'id "presentation"
"
>
Donc si on considère le sélecteur ci-dessous, qui est presque le même
article > p {
}
alors...
<article>
<p>ce p est visé parce qu'il est un enfant direct d'un article</p>
<div>
<p>par contre celui ci non, il est enfant, mais pas direct</p>
</div>
</article>
<p>et celui là non plus</p>
tout ça pour quoi?
Il existe d'autres opérateurs de combinaisons mais on va en rester là parce que mon objectif n'est pas de vous pousser à faire le CSS le plus complexe possible, le but est que vous puissiez appliquer du style à un élément sans avoir besoin de tartiner votre HTML de classes et d'id dans tous les sens.
Prenez cet html par exemple
<article>
<h2>Titre</h2>
<p>ma description</p>
<a><button>Visiter</button></a>
</article>
avant, pour sélectionner vos éléments vous auriez pu être tentés d'écrire ceci
<article>
<h2 class="article-title">Titre</h2>
<p class="article-description">ma description</p>
<a><button class="article-button">Visiter</button></a>
</article>
pour aller avec ce CSS
article {
}
.article-title {
}
.article-description {
}
.article-button {
}
Mais maintenant on peut arriver au même résultat sans rien ajouter ni classe ni identifiant à l'HTML avec le CSS ci-dessous
article {
}
article h2 {
}
article p {
}
article button {
}
Ça communique tout aussi bien ce que ça fait sans pour autant rendre votre HTML plus difficile à fouiller.
Nesting
On va faire une petite pause sur les sélecteurs complexes rapidement et voir le nesting.
Depuis un petit moment, on peut mettre des règles CSS dans d'autres règles. Au lieu d'écrire ...
article {
/*les propriétés de mes articles*/
}
article h2 {
/*les propriétés des titres de mes articles*/
}
pour viser les <h2>
qui sont dans des <article>
on peut écrire ceci
article {
/*les propriétés de mes articles*/
h2 {
/*les propriétés des titres de mes articles*/
}
}
Ce qui fait qu'on peut réécrire le bout de CSS du sous chapitre précédent comme ceci
article {
/*les propriétés de mes articles*/
h2 {
}
p {
}
button {
}
}
Les pseudo-classes
Les pseudo classes sont des compléments que vous pouvez ajouter après votre sélecteur pour le modifier. En règle générale, une pseudo-classe permet de définir que le style s'applique seulement sous certaines conditions et s'écrit après deux points:comme ceci
article:pseudoClasse`, certaines pseudo-classes ont des parenthèses pour préciser leur comportement.
:nth-child(n)
Celui là il est marrant et pas bien loin de ce que l'on faisait parce qu'il est quand même lié à la structure de l'HTML.
nth-child(n)
permet de spécifier que la règle ne s'applique qu'à tous les N enfants.
Par exemple :
li:nth-child(2n) {
background-color: azure;
}
ce bout de css colorera le fond d'un <li>
sur deux. :nth-child(3n)
aurait été un enfant sur 3, :nth-child(4n)
un enfant sur quatre etc...
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
:hover
:hover
n'applique du style que si l'élément est survolé. Tout les débutants trouvent ça super, jusqu'à ce qu'ils réalisent que le survol n'existe pas sur telephone (vous savez, le truc qui représente 70% du trafic)
button:hover {
background-color: azure;
}
:visited
Encore plus spécifique, :visited
permet de donner un style particulier aux liens qui ont été visités.
a {
color: hotpink;
}
a:visited {
color: limegreen;
}
Comme ça, les liens que l'utilisateur n'as pas visités seront roses, et ceux visités seront verts.
Il reste plein de pseudo-classes que vous pouvez explorer ici : https://developer.mozilla.org/fr/docs/Web/CSS/Pseudo-classes
Mais je trouve que ce qu'on a vu est pas mal déjà
Media queries
Les media queries sont une autre forme de style conditionnel. La différence est qu'avec elles ont vérifié des conditions sur l'environnement de la page dans son ensemble.
Elles démarre par @media
et sont valable pendant tout un bloc, comme ceci
@media print {
body {
color: black;
background-color: white;
}
}
La media query étant un bloc dans lequel on peut mettre du CSS, et dans cet example plus precisement on dit que le fond du <body>
sera blanc et son texte noir quand la page sera affichée pour impression. Ce qui pourrait être utile à inclure dans le CSS d'un dark mode (si jamais vous êtes sur un site souvent imprimé sur papier).
screen
Comme print
, mais pour les écrans
min-width
et max-width
Ok, ça c'est le gros poisson. Ces media queries permettent d'appliquer du style si la largeur de l'écran est plus petite ou plus grande qu'une certaine largeur.
@media (min-width: 1000px) {
body {
background-color: red;
}
}
ici, min-width
s'applique si la page est plus large que 1000px, autrement dit si elle fait "au moins" 1000px de large.
max-width
c'est exactement l'inverse.
width
C'est une version alternative et plus récente de min-width
et max-width
@media (width > 1000px) {
body {
background-color: red;
}
}
Ce bloc revient au même, le fond sera rouge quand la page sera plus large que 1000px. Personnellement je trouve ça beaucoup plus clair.
Pourquoi vous avoir montré min-width
et max-width
?
Comme pour les selecteurs complexe au regard du nesting, parce que c'est une solution plus ancienne, et donc plus documentée/répendue, et en l'état les vieilles solutions on ne s'en debarassera pas
Pour l'anecdote, je viens de demander à l'un des tout derniers "thinking models" au moment de l'écriture(21/05/2025) et j'ai eu une recommandation d'utiliser max-width
ou sinon de le faire en javascript.
Les variables
Il est possible de définir des valeurs clefs dans notre CSS avec --monNom
comme ceci
body {
--small: 8px;
--medium: 16px;
--big: 32px;
}
Pour pouvoir les réutiliser par la suite on utilise var(--monNom)
comme ceci
article {
padding: var(--medium);
border: 1px solid black;
margin: var(--big);
}
En utilisant ça on y gagne que tous les éléments qui vont faire usage de ces valeurs resteront consistants. En admettant que j'utilise ces 3 valeurs pour tous les espacements de ma page et qu'ils ne conviennent pas, alors j'ai juste besoin de changer la valeur de mes variables.
Bien sur, il est possible de faire ça avec d'autres types de valeurs et pas uniquement des longueurs
body {
--primary: #3aa63f;
--accent: #a8d47a;
}
Un exemple de thème
Un exemple sympa et pas directement évident dès le début, les thèmes!
Ce qu'on peut faire c'est définir une collection de variables par défaut et une collection de variable par thème
body {
--text: #222323;
--background: #f0f6f0;
--primary: #222323;
--link: #1b4699;
--visited: #4d4daa;
}
body.dark {
--text: #f0f6f0;
--background: #222323;
--primary: #f0f6f0;
--link: #7eb0f0;
--visited: #b0b0ff;
}
body.mint {
--text: #ffffff;
--background: #201b1b;
--primary: #96fbc7;
--link: #bb7749;
--visited: #bb8764;
}
body {
color: var(--text);
background-color: var(--background);
}
a {
color: var(--link);
}
a:visited {
color: var(--visited);
}
Notez que body.dark
veut dire "les <body>
ayant la classe "dark"". Il faudrait qu'il y ait un espace entre body
et .dark
pour que ce soit "les éléments de classe "dark" dans le <body>
".
Et donc, avec le CSS ci-dessus, si mon <body>
a une classe dark
, mint
, ou aucune de ces classes, alors le thème changera parce qu'on utilisera la même collection de variables mais pas avec les mêmes valeurs.
Notez que cet exemple n'est pas poussé jusqu'au bout, parce qu'il faudrait qu'on connaisse un peu de javascript, et aussi on ne prend pas en compte les préférences light/dark de l'utilisateur.