Chapitre 623 minDébutant
Les bases du CSS : sélecteurs, couleurs, unités et polices
Par Josselyn C., prof de BTS SIO. Mis à jour le .
À la fin de ce chapitre, tu sauras
- ajouter du CSS à une page et écrire une règle ;
- cibler des éléments avec les sélecteurs, les combinateurs, les pseudo-classes et les pseudo-éléments ;
- choisir une couleur et la bonne unité : px, %, em, rem, vw ou vh ;
- mettre en forme le texte, les polices et les fonds.
4 exercices corrigés
Une règle CSS associe un sélecteur, qui désigne les éléments HTML visés, à des déclarations propriété: valeur;, qui disent comment les afficher. Ce chapitre montre comment relier une feuille de style à une page, puis passe en revue les sélecteurs (classes, combinateurs, pseudo-classes), les couleurs, les unités, le texte, les polices et les fonds : de quoi mettre en forme une page entière.
Les trois façons d'ajouter du CSS
| Méthode | Exemple | Verdict |
|---|---|---|
Attribut style (en ligne) | <p style="color: red;"> | à éviter : mélange contenu et présentation, non réutilisable, très difficile à surcharger |
Élément <style> dans le <head> | <style> p { color: red; } </style> | pour un test rapide ou une page unique |
| Feuille de style externe | <link rel="stylesheet" href="css/style.css"> | la bonne pratique |
La feuille externe a trois avantages : une seule feuille met en forme toutes les pages du site (changer la couleur des titres partout, c'est changer une ligne) ; le navigateur la garde en cache et ne la retélécharge pas à chaque page ; le HTML reste propre, sans aucune information de présentation.
La syntaxe d'une règle CSS
/* Les titres de section de la médiathèque */
h2 {
color: #0f766e;
font-size: 1.75rem;
margin-bottom: 0.5em;
}
h2est le sélecteur : la règle s'applique à tous les<h2>;- entre accolades, le bloc de déclarations ;
- chaque déclaration est une paire
propriété: valeur, terminée par un point-virgule ; - les commentaires s'écrivent entre
/*et*/; il n'y a pas de//en CSS.
Une erreur de syntaxe (un ; oublié, une accolade en trop) n'arrête pas tout le fichier : le navigateur ignore la déclaration fautive, parfois tout le bloc, et continue. C'est pratique, mais l'erreur est silencieuse : l'inspecteur montre une déclaration invalide barrée avec un petit triangle d'avertissement.
Plusieurs sélecteurs peuvent partager une même règle, séparés par des virgules :
h1,
h2,
h3 {
font-family: Georgia, serif;
}
Les sélecteurs de base : balise, classe, identifiant
| Sélecteur | Syntaxe | Cible | Exemple |
|---|---|---|---|
| De type (balise) | p | tous les <p> | p { line-height: 1.6; } |
| De classe | .nom | tous les éléments qui ont class="nom" | .carte { padding: 1rem; } |
| D'identifiant | #nom | l'élément unique qui a id="nom" | #contenu { … } |
| Universel | * | tous les éléments | * { box-sizing: border-box; } |
| Composé | p.intro | les <p> qui ont la classe intro (sans espace) | a.bouton { … } |
Un élément peut porter plusieurs classes, séparées par des espaces : <article class="carte complet">. Les règles de .carte et de .complet s'appliquent toutes les deux, et .carte.complet (sans espace) vise les éléments qui ont les deux classes à la fois.
Les combinateurs
Un combinateur exprime une relation entre deux éléments dans l'arbre du DOM (chapitre 2).
| Combinateur | Syntaxe | Cible |
|---|---|---|
| Descendant (une espace) | nav a | les <a> situés n'importe où dans un <nav> |
| Enfant direct | ul > li | les <li> enfants directs d'un <ul> (pas ceux d'une sous-liste) |
| Frère adjacent | h2 + p | le <p> qui suit immédiatement un <h2> |
| Frères suivants | h2 ~ p | tous les <p> qui suivent un <h2>, dans le même parent |
/* Les liens du menu, et seulement eux */
nav a {
text-decoration: none;
}
/* Le premier niveau du menu, pas les sous-menus */
.menu > li {
display: inline-block;
}
/* Le chapeau : le premier paragraphe après un titre d'article */
article h2 + p {
font-size: 1.15rem;
}
Les sélecteurs d'attribut
| Sélecteur | Cible |
|---|---|
[required] | les éléments qui ont l'attribut required |
[type="email"] | les éléments dont l'attribut type vaut exactement email |
a[href^="https://"] | les liens dont l'adresse commence par https:// (liens externes) |
a[href$=".pdf"] | les liens dont l'adresse se termine par .pdf |
[class*="col-"] | les éléments dont la classe contient col- |
/* Signaler les liens vers un PDF */
a[href$=".pdf"]::after {
content: " (PDF)";
}
Les pseudo-classes
Une pseudo-classe, introduite par un deux-points, vise un élément selon son état ou sa position.
| Pseudo-classe | Cible |
|---|---|
:hover | l'élément survolé par la souris |
:focus | l'élément qui a le focus (clic dans un champ, touche Tab) |
:focus-visible | l'élément qui a le focus quand le navigateur juge utile de le montrer (au clavier, pas après un clic de souris sur un bouton) |
:active | l'élément pendant le clic |
:visited | un lien déjà visité |
:first-child, :last-child | le premier, le dernier enfant de son parent |
:nth-child(2), :nth-child(odd), :nth-child(3n) | le 2e enfant ; les enfants impairs ; un sur trois |
:not(.complet) | les éléments qui n'ont pas la classe complet |
:checked, :disabled, :required | les cases cochées, champs désactivés, champs obligatoires |
:user-invalid | un champ invalide, une fois que l'utilisateur l'a modifié (chapitre 5) |
/* Lignes de tableau zébrées */
tbody tr:nth-child(even) {
background-color: #f1f5f9;
}
/* Un focus clavier toujours visible */
a:focus-visible,
button:focus-visible {
outline: 3px solid #0f766e;
outline-offset: 2px;
}
/* Pas de trait de séparation après le dernier élément du menu */
.menu li:not(:last-child) {
border-right: 1px solid #cbd5e1;
}
Pour les liens, l'ordre des règles compte : écris-les dans l'ordre :link, :visited, :hover, :active (moyen mnémotechnique : LoVe HAte), sinon :visited écrase :hover (chapitre 7).
Les pseudo-éléments
Un pseudo-élément, introduit par deux deux-points, vise une partie d'un élément ou crée un élément virtuel.
| Pseudo-élément | Cible |
|---|---|
::before, ::after | un contenu ajouté au début, à la fin de l'élément (propriété content obligatoire) |
::first-line, ::first-letter | la première ligne, la première lettre (lettrine) |
::placeholder | le texte indicatif d'un champ |
::marker | la puce ou le numéro d'un élément de liste |
::selection | le texte sélectionné par l'utilisateur |
/* Un astérisque après l'étiquette des champs obligatoires */
.obligatoire::after {
content: " *";
color: #b91c1c;
}
/* Des puces de la couleur de la charte */
li::marker {
color: #0f766e;
}
Le contenu ajouté par content est décoratif : il ne se sélectionne pas, et les lecteurs d'écran ne le lisent pas toujours. N'y mets jamais une information essentielle.
Les couleurs en CSS
| Notation | Exemple | Remarque |
|---|---|---|
| Mot-clé | teal, white, transparent | 148 noms, choix limité |
| Hexadécimal | #0f766e, #fff, #0f766e80 | rouge, vert, bleu de 00 à ff ; le 4e couple optionnel est l'opacité |
rgb() | rgb(15 118 110), rgb(15 118 110 / 50%) | trois valeurs de 0 à 255 ; / alpha pour l'opacité |
hsl() | hsl(175 77% 26%) | teinte en degrés (0 rouge, 120 vert, 240 bleu), saturation, luminosité : pratique pour éclaircir une couleur sans changer sa teinte |
oklch() | oklch(52% 0.09 185) | luminosité perçue, intensité, teinte : deux couleurs de même luminosité y paraissent vraiment aussi claires ; reconnue par tous les navigateurs actuels |
currentColor | border-color: currentColor | reprend la couleur du texte de l'élément |
La syntaxe ancienne rgba(15, 118, 110, 0.5), avec des virgules, reste valide ; la syntaxe moderne, avec des espaces et une barre oblique, fonctionne partout aujourd'hui.
color change la couleur du texte, background-color celle du fond. Une charte graphique fixe en général une couleur principale, une ou deux couleurs secondaires et des gris : on les déclare une seule fois dans des variables CSS (chapitre 11).
Les unités : px, %, em, rem, vw et vh
| Unité | Relative à | Usage typique |
|---|---|---|
px | rien : taille fixe (un pixel CSS, pas un pixel physique de l'écran) | bordures, ombres, petits détails |
% | la dimension correspondante du parent | largeurs fluides (width: 50%) |
em | la taille de police de l'élément lui-même (ou du parent, pour font-size) | marges et espacements qui suivent la taille du texte |
rem | la taille de police de la racine <html> (16 px par défaut) | tailles de texte, espacements généraux |
vw, vh | 1 % de la largeur, de la hauteur de la fenêtre | sections plein écran |
dvh | 1 % de la hauteur visible de la fenêtre | plein écran sur mobile, où la barre d'adresse apparaît et disparaît |
ch | la largeur du caractère « 0 » | largeur de lecture (max-width: 65ch) |
fr | une fraction de l'espace libre (Grid uniquement) | colonnes de grille (chapitre 9) |
Le piège de em : il se multiplie en cascade.
html { font-size: 100%; } /* 16 px, ou la taille choisie par l'utilisateur */
.carte { font-size: 1.25em; } /* 1,25 × 16 = 20 px */
.carte p { font-size: 1.25em; }/* 1,25 × 20 = 25 px, et non 20 px */
.carte p { font-size: 1.25rem; }/* avec rem : 1,25 × 16 = 20 px, toujours */
Le texte et les polices
body {
font-family: "Atkinson Hyperlegible", system-ui, sans-serif;
font-size: 1rem;
line-height: 1.6;
color: #1f2937;
}
h1 {
font-size: 2.25rem;
font-weight: 700;
line-height: 1.2;
letter-spacing: -0.01em;
}
.surtitre {
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.08em;
}
| Propriété | Rôle | Valeurs courantes |
|---|---|---|
font-family | la police, avec des polices de secours séparées par des virgules, la dernière étant une famille générique | Georgia, serif ; system-ui, sans-serif ; ui-monospace, monospace |
font-size | la taille | 1rem, 1.25rem |
font-weight | la graisse | 400 (normal), 600 (semi-gras), 700 (gras) |
font-style | l'italique | italic, normal |
line-height | la hauteur de ligne, sans unité de préférence (multiplie la taille du texte) | 1.5 à 1.7 pour le texte courant |
text-align | l'alignement | left, center, right, justify (à éviter : crée des espaces irréguliers, gênants pour les personnes dyslexiques) |
text-decoration | soulignement, barré | none, underline |
text-transform | casse affichée | uppercase, capitalize |
letter-spacing | espacement des lettres | 0.05em |
system-ui utilise la police de l'interface du système (Segoe UI sous Windows, San Francisco sous macOS et iOS, Roboto sous Android) : rapide, lisible, sans aucun téléchargement.
Pour une police particulière, la bonne méthode est de l'héberger toi-même, au format WOFF2, et de la déclarer avec @font-face :
@font-face {
font-family: "Atkinson Hyperlegible";
src: url("../fonts/atkinson-hyperlegible-regular.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
}
font-display: swap affiche d'abord le texte avec la police de secours, puis bascule quand la police est chargée : le texte n'est jamais invisible pendant le chargement.
Ne charge que les graisses que tu utilises vraiment : chaque fichier de police pèse quelques dizaines de kilo-octets.
Les fonds
.bandeau {
background-color: #0f766e;
background-image: url("../images/feuilles.svg");
background-repeat: no-repeat;
background-position: right bottom;
background-size: 200px auto;
}
.hero {
background: linear-gradient(135deg, #0f766e, #134e4a);
color: white;
}
.photo-fond {
background-image: url("../images/facade.jpg");
background-size: cover; /* couvre toute la zone, quitte à rogner */
background-position: center;
}
| Propriété | Valeurs utiles |
|---|---|
background-color | une couleur, qui s'affiche aussi pendant le chargement de l'image |
background-image | url(…), linear-gradient(…), radial-gradient(…) |
background-repeat | no-repeat, repeat-x, repeat (par défaut) |
background-position | center, right bottom, 50% 20% |
background-size | cover (couvre tout), contain (image entière visible), une taille |
Exercices
Exercice 1 sur 4 Que cible ce sélecteur ? Réussi À revoir
Avec ce HTML, liste les éléments visés par chaque sélecteur.
<nav class="menu">
<ul>
<li><a href="index.html">Accueil</a></li>
<li><a href="agenda.html" class="actif">Agenda</a>
<ul>
<li><a href="agenda.html#numerique">Numérique</a></li>
</ul>
</li>
<li><a href="https://www.bnf.fr">BnF</a></li>
</ul>
</nav>
.menu a.menu > ul > lia.actifa[href^="https://"]li:first-child > a.menu > ul > li + li
Voir la réponseMasquer la réponse de l'exercice 1
- Les quatre liens : Accueil, Agenda, Numérique et BnF (descendants à n'importe quelle profondeur).
- Les trois
<li>du premier niveau (Accueil, Agenda, BnF), pas celui du sous-menu. - Le lien Agenda.
- Le lien BnF.
- Les liens Accueil et Numérique : chacun est dans un
<li>qui est le premier enfant de sa liste. - Les
<li>Agenda et BnF du premier niveau : chacun suit immédiatement un autre<li>. Accueil, premier de la liste, n'a pas de frère avant lui. Ce sélecteur sert souvent à placer un séparateur entre les éléments.
Tu avais trouvé ?
Exercice 2 sur 4 Calculer des tailles Réussi À revoir
La taille de police de <html> est celle par défaut, 16 px. Calcule la taille en pixels du texte de chaque élément.
.encadre { font-size: 1.5rem; }
.encadre h3 { font-size: 1.5em; }
.encadre small { font-size: 0.75em; }
.note { font-size: 0.875rem; }
- Un
<p>dans.encadre. - Un
<h3>dans.encadre. - Un
<small>dans un<p>de.encadre. - Un
<p class="note">placé dans.encadre.
Voir la réponseMasquer la réponse de l'exercice 2
- Il hérite de
.encadre: 1,5 × 16 = 24 px. emse rapporte à la taille du parent pourfont-size: 1,5 × 24 = 36 px.- Le
<p>fait 24 px, donc 0,75 × 24 = 18 px. remignore les parents : 0,875 × 16 = 14 px.
Tu avais trouvé ?
Exercice 3 sur 4 Mettre en forme la page d'accueil Réussi À revoir
Écris le CSS qui donne à la page d'accueil de la médiathèque (chapitre 4) :
- une police système sans empattement, en 1rem, avec une hauteur de ligne de 1,6, en gris très foncé
#1f2937; - un
<header>à fond vert#0f766e, dont les liens sont blancs et non soulignés ; - un soulignement des liens du menu au survol et au focus clavier ;
- les titres
<h2>en vert#0f766e, en 1,75rem ; - le lien de la page active du menu en gras.
Voir la réponseMasquer la réponse de l'exercice 3
body {
font-family: system-ui, sans-serif;
font-size: 1rem;
line-height: 1.6;
color: #1f2937;
}
header {
background-color: #0f766e;
}
header a {
color: white;
text-decoration: none;
}
header nav a:hover,
header nav a:focus-visible {
text-decoration: underline;
}
h2 {
color: #0f766e;
font-size: 1.75rem;
}
nav a[aria-current="page"] {
font-weight: 700;
}
Le sélecteur d'attribut [aria-current="page"] évite d'ajouter une classe actif : l'information est déjà dans le HTML. Le blanc sur #0f766e a un contraste de 5,5:1 environ : suffisant pour du texte courant.
Tu avais trouvé ?
Exercice 4 sur 4 Pseudo-classe ou pseudo-élément ? Réussi À revoir
Pour chaque besoin, écris le sélecteur.
- Colorer en rouge la bordure d'un champ invalide, seulement après saisie.
- Ajouter « (PDF) » après tout lien vers un fichier PDF.
- Griser une ligne de tableau sur deux.
- Mettre en gras le premier paragraphe qui suit chaque
<h2>. - Changer la couleur des puces des listes.
Voir la réponseMasquer la réponse de l'exercice 4
input:user-invalid { border-color: #b91c1c; }(pseudo-classe : un état).a[href$=".pdf"]::after { content: " (PDF)"; }(pseudo-élément : un contenu ajouté). L'idéal reste d'écrire « (PDF) » dans le texte du lien, pour qu'il soit lu par tous.tbody tr:nth-child(even)(ouodd) : pseudo-classe de position.h2 + p { font-weight: 700; }: un combinateur, pas une pseudo-classe.li::marker { color: …; }(pseudo-élément : une partie de l'élément).
Tu avais trouvé ?