🔮 Le cours : aller plus loin avec les sélecteurs
Un sélecteur ne se limite pas à « cet élément » : il peut dire « cet élément quand on le survole », « le troisième de la liste », « la première lettre de ce paragraphe ». Les pseudo-classes (un seul :) expriment un état ou une position, les pseudo-éléments (deux ::) désignent une partie d'un élément, et les variables évitent de répéter les valeurs.
Pseudo-classes d'interaction
| Pseudo-classe | S'applique quand… |
:hover | la souris est au-dessus de l'élément (inexistant sur un écran tactile) |
:focus | l'élément reçoit le clavier (champ, lien, bouton) |
:focus-visible | le focus doit être montré (navigation au clavier) : à préférer à :focus pour les contours |
:focus-within | un descendant a le focus (mettre en valeur tout un formulaire) |
:active | pendant l'appui (clic ou toucher) |
Pour les liens, l'ordre d'écriture compte (à spécificité égale, le dernier gagne) : a:link, a:visited, a:hover, a:active. Une astuce pour s'en souvenir : « LoVe HAte ». Et quel que soit le style du survol, prévois le même pour :focus-visible : tout le monde n'a pas de souris.
Pseudo-classes de formulaire
:checked, :disabled, :enabled, :required, :optional, :valid, :invalid, :placeholder-shown, :read-only permettent de styler un champ d'après son état, sans JavaScript.
input:required {
border-left: 4px solid #ef4a34;
}
input:valid {
border-color: #16a34a;
}
/* invalide, mais seulement une fois que l'utilisateur a commencé à écrire */
input:invalid:not(:placeholder-shown) {
border-color: #dc2626;
}
Pseudo-classes de position
| Pseudo-classe | Cible | Exemple |
:first-child :last-child | le premier / le dernier enfant de son parent | li:last-child { border-bottom: 0; } |
:nth-child(n) | l'enfant en position n, ou selon une formule | tr:nth-child(2n) (positions paires) |
:nth-of-type(n) | comme :nth-child, mais en ne comptant que les éléments de même balise | p:nth-of-type(1) |
:only-child | l'enfant unique | |
:empty | un élément sans aucun contenu | p:empty { display: none; } |
Les formules de :nth-child : 3 (le troisième), even (pairs), odd (impairs), 2n+1 (1, 3, 5…), 3n (3, 6, 9…), -n+3 (les trois premiers).
not, is, where et has
:not(.note) exclut, :is(h1, h2, h3) regroupe plusieurs sélecteurs sans les répéter, :where() fait de même sans ajouter de spécificité. :has() est un sélecteur de parent : .carte:has(img) cible les cartes qui contiennent une image (disponible dans les navigateurs récents).
:is(h1, h2, h3) {
line-height: 1.2;
}
.carte:has(img) {
padding: 0;
}
li:not(:last-child) {
margin-bottom: 0.5rem;
}
Pseudo-éléments
::before et ::after insèrent un contenu décoratif juste avant ou après le contenu de l'élément. Ils ne s'affichent que si la propriété content est définie (même vide, content: "", pour dessiner une forme). Les autres : ::first-letter, ::first-line, ::placeholder, ::selection, ::marker (la puce d'une liste).
blockquote::before {
content: "«";
font-size: 2rem;
}
a[href^="https"]::after {
content: " ↗";
}
.titre::first-letter {
font-size: 2em;
font-weight: 800;
}
::selection {
background: #fde68a;
}
Le contenu généré n'est pas du vrai contenu
Ce qu'ajoute content n'existe pas dans le HTML : il n'est pas sélectionnable et certains lecteurs d'écran l'ignorent ou le lisent mal. Réserve-le à la décoration (puces, guillemets, flèches), jamais à une information indispensable.
Les variables CSS
Une propriété personnalisée commence par deux tirets (--accent) et se lit avec var(--accent). Déclarée sur :root (l'élément html), elle est disponible dans toute la page. Changer la couleur d'accent d'un site, c'est modifier une ligne. var(--x, valeur) fournit une valeur de secours si la variable n'existe pas.
Contrairement aux variables d'un préprocesseur, elles vivent dans le navigateur : elles suivent la cascade et l'héritage, et on peut les redéfinir sur un élément pour changer son apparence et celle de ses enfants (un thème sombre, une carte d'une autre couleur).
:root {
--fond: #ffffff;
--texte: #14141a;
}
[data-theme="sombre"] {
--fond: #14141a;
--texte: #f7f2ea;
}
body {
background: var(--fond);
color: var(--texte);
}
RenduLa page est blanche avec du texte presque noir. Si l'élément html reçoit data-theme="sombre" (par un petit script), tout s'inverse sans toucher aux autres règles.
calc(), min(), max() et clamp()
calc() mélange les unités : width: calc(100% - 2rem). Les espaces autour de + et - sont obligatoires (100%-2rem est invalide). On peut y utiliser des variables : calc(var(--espace) * 2). min(), max() et clamp(min, préféré, max) choisissent entre plusieurs valeurs (voir Responsive).