Créer des éléments virtuels et manipuler le contenu sans modifier le HTML.
Les pseudo-éléments commencent par deux deux-points :: (contrairement aux pseudo-classes qui en ont un seul). Ils créent des éléments « fantômes » qui n'existent pas dans le HTML source.
/* Syntaxe générale */
sélecteur::pseudo-élément {
propriété: valeur;
}
/* Exemple */
p::first-line {
font-weight: 700;
}
Différence pseudo-classe vs pseudo-élément :
| Aspect | Pseudo-classe : |
Pseudo-élément :: |
|---|---|---|
| Symbole | : (un seul) |
:: (deux) |
| Cible | Un état ou une position | Une partie du contenu ou un élément virtuel |
| Existe dans le HTML ? | Oui (l'élément existe déjà) | Non (c'est un élément créé par CSS) |
| Exemples | :hover, :first-child |
::before, ::after, ::first-line |
: pour ::before et ::after par rétrocompatibilité, mais la syntaxe correcte est :: (deux points).
::before et ::after — Les incontournables::before et ::after créent des éléments virtuels qui sont insérés avant / après le contenu réel de l'élément. Ils nécessitent la propriété content pour exister.
/* Sans content, ::before et ::after n'existent PAS */
/* Ajouter une icône avant chaque titre */
h2::before {
content: "→ ";
color: #2563eb;
font-weight: 700;
}
/* Ajouter des guillemets après un bloc de citation */
blockquote::after {
content: """;
font-size: 2rem;
color: #94a3b8;
vertical-align: -0.3em;
margin-left: 0.25rem;
}
/* Créer un badge décoratif */
.badge::before {
content: "★";
margin-right: 0.5rem;
color: #f59e0b;
}
content est obligatoire. Sans elle, ::before et ::after ne sont tout simplement pas rendus par le navigateur.
content/* Texte literal */
element::before {
content: "Note : ";
}
/* Caractère Unicode */
element::before {
content: "\2713"; /* ✓ checkmark */
}
/* Attr HTML (seulement pour ::before/::after) */
element::before {
content: attr(data-label);
}
/* URL d'image */
element::before {
content: url("icon.svg");
}
/* Compteur */
.element::before {
counter-increment: compteur;
content: counter(compteur) ". ";
}
/* Chaîne vide (utile pour les '::after' décoratifs) */
.element::after {
content: "";
}
::first-letter — La première lettre::first-letter cible la première lettre (ou le premier caractère non whitespace) d'un élément bloc. Idéal pour créer un effet « lettrine ».
/* Lettrine decorative */
article > p:first-of-type::first-letter {
float: left;
font-size: 3.5rem;
line-height: 0.8;
font-weight: 800;
color: #2563eb;
margin-right: 0.5rem;
margin-top: 0.1rem;
}
::first-letter ne fonctionne que sur les éléments de type bloc (p, div, h1…), pas sur les éléments en ligne (span, a).
::first-line — La première ligne::first-line cible la première ligne du texte d'un élément bloc. Le nombre de caractères affichés change avec la largeur du conteneur.
p::first-line {
font-weight: 700;
color: #2563eb;
text-transform: uppercase;
letter-spacing: 0.02em;
}
::first-line (pas de margin, padding, etc.).
::selection — Le texte sélectionné::selection cible le texte électionné par l'utilisateur (surlignage bleu par défaut). Permet de personnaliser l'expérience de copier-coller.
/* Personnaliser la sélection */
::selection {
background: #2563eb;
color: white;
}
/* Sélection spécifique dans un élément */
.code-block::selection {
background: #7c3aed;
color: white;
}
::marker — Les puces et numéros::marker cible la puce (•) ou le numéro des éléments de <ol> et <ul>.
/* Personnaliser les puces de liste */
li::marker {
color: #2563eb;
font-size: 1.2em;
}
/* Numéros de liste ordonnée */
ol li::marker {
color: #dc2626;
font-weight: 700;
}
::placeholder — Le texte indicatif::placeholder cible le texte placeholder (texte gris par défaut) des champs de formulaire (<input>, <textarea>).
input::placeholder {
color: #94a3b8;
font-style: italic;
opacity: 0.7;
}
textarea::placeholder {
color: #cbd5e1;
font-size: 0.9rem;
}
::file-selector-button — Le bouton de fichier::file-selector-button cible le bouton du sélecteur de fichier (<input type="file">).
input[type="file"]::file-selector-button {
padding: 0.6rem 1.2rem;
background: #7c3aed;
color: white;
border: none;
border-radius: 6px;
font-weight: 600;
cursor: pointer;
}
input[type="file"]::file-selector-button:hover {
background: #6d28d9;
}
┌─────────────────────────────────────────────────────────┐ │ PSEUDO-ÉLÉMENTS EN SCHÉMA │ ├─────────────────────────────────────────────────────────┤ │ │ │ Élément HTML : <h2 class="titre">Mon titre</h2> │ │ │ │ ┌──────────────────────────────────────────────────┐ │ │ │ ::before "→ " Mon titre ::after " 🔗" │ │ │ │ ↑ ↑ ↑ │ │ │ │ Élément virtuel Contenu réel Élément │ │ │ │ (avant) virtuel │ │ │ │ (après) │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ ::first-letter → La première lettre du paragraphe │ │ ::first-line → La première ligne (responsive) │ │ ::selection → Le texte sélectionné │ │ ::marker → La puce/numéro d'un <li> │ │ ::placeholder → Le texte indicatif d'un input │ │ │ └─────────────────────────────────────────────────────────┘
Schéma des pseudo-éléments et leur positionnement
Démonstration : Éléments décoratifs
/* Icône étoile avant chaque élément */
.icone-item::before {
content: "★";
position: absolute;
left: 0.75rem;
color: #f59e0b;
font-size: 1.1rem;
}
/* Badge compteur après chaque élément */
.compteur-item::after {
content: attr(data-count);
position: absolute;
right: 0.75rem;
background: #2563eb;
color: white;
padding: 0.2rem 0.6rem;
border-radius: 999px;
font-size: 0.8rem;
font-weight: 600;
}
Démonstration : Soulignement animé au survol
/* Lien avec soulignement progressif */
.lien-deco::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: #2563eb;
transition: width 0.3s ease;
}
.lien-deco:hover::after {
width: 100%;
}
Démonstration : Première lettre stylisée
.drop-cap::first-letter {
float: left;
font-size: 3.5rem;
line-height: 0.8;
font-weight: 800;
color: #2563eb;
margin-right: 0.5rem;
margin-top: 0.1rem;
}
Les pseudo-éléments sont des outils puissants du CSS moderne. Ils permettent de créer des éléments virtuels sans modifier le HTML, d'ajouter des décorations, et de personnaliser l'apparence du texte de manière élégante et efficace.
Démonstration : La première ligne en gras
.first-line-style::first-line {
font-weight: 700;
color: #2563eb;
font-size: 1.1em;
text-transform: uppercase;
letter-spacing: 0.02em;
}
La première ligne de ce paragraphe est automatiquement mise en gras, en bleu et en majuscules grâce au pseudo-élément ::first-line. Si tu redimensionnes la fenêtre, le texte change mais la première ligne reste toujours stylée. C'est la magie de ce pseudo-élément — il s'adapte dynamiquement à la largeur du conteneur.
Démonstration : Sélectionne du texte !
.selection-custom::selection {
background: #2563eb;
color: white;
}
Sélectionne ce texte pour voir la sélection personnalisée en bleu avec du texte blanc. Compare avec le texte ci-dessous qui utilise la sélection par défaut du navigateur.
Ce paragraphe utilise la sélection par défaut du navigateur (bleu clair avec texte noir).
Démonstration : Puces violettes
.marker-list li::marker {
color: #7c3aed;
font-size: 1.2em;
}
Démonstration : Placeholders stylisés
.placeholder-input::placeholder {
color: #94a3b8;
font-style: italic;
opacity: 0.7;
}
.placeholder-input:focus {
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37,99,235,0.15);
}
Démonstration : Input fichier stylisé
.file-input::file-selector-button {
padding: 0.6rem 1.2rem;
background: #7c3aed;
color: white;
border: none;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: background 0.2s;
}
.file-input::file-selector-button:hover {
background: #6d28d9;
}
content
/* FAUX — ::before n'existe PAS sans content */
.element::before {
background: red;
width: 20px;
height: 20px;
}
/* CORRECT */
.element::before {
content: "";
background: red;
width: 20px;
height: 20px;
}
/* FAUX — ne fonctionne que sur les éléments bloc */
span::first-letter {
font-size: 2rem;
}
/* CORRECT */
p::first-letter {
font-size: 2rem;
}
/* FAUX — les pseudo-éléments ne peuvent PAS recevoir
d'événements souris ni avoir de tabindex */
.element::before {
content: "Clique";
cursor: pointer;
}
/* Le clic ne fonctionnera PAS sur cet élément virtuel */
/* CORRECT — ajouter un vrai élément HTML pour l'interaction */
.element {
position: relative;
}
.element .deco {
position: absolute;
cursor: pointer;
}
/* FAUX — ::first-line n'accepte que les propriétés de texte */
p::first-line {
margin: 1rem; /* ✗ Pas autorisé */
padding: 0.5rem; /* ✗ Pas autorisé */
border: 1px solid; /* ✗ Pas autorisé */
}
/* CORRECT */
p::first-line {
font-weight: 700;
color: #2563eb;
text-transform: uppercase;
}
content pour ::before et ::after.attr() pour afficher des données du HTML via CSS.::selection avec parcimonie — ne pas en abuser./* ✅ Bonne pratique : icône décorative avec ::before */
.nav-item::before {
content: "→";
margin-right: 0.5rem;
color: inherit;
opacity: 0.5;
}
/* ✅ Bonne pratique : data attribute pour du contenu dynamique */
.badge::after {
content: attr(data-count);
background: #dc2626;
color: white;
padding: 0.1rem 0.4rem;
border-radius: 999px;
font-size: 0.7rem;
font-weight: 700;
margin-left: 0.5rem;
}
/* ✅ Bonne pratique : soulignement animé */
.animated-link {
position: relative;
text-decoration: none;
}
.animated-link::after {
content: "";
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
background: currentColor;
transition: width 0.3s ease;
}
.animated-link:hover::after {
width: 100%;
}
Exercice 1 : ::before et ::after
Ajoute un contenu décoratif à chaque élément <h2> :
::before : le caractère § en bleu, gras::after : le caractère § en bleu, grasSolution :
h2::before,
h2::after {
content: "§";
color: #2563eb;
font-weight: 700;
margin: 0 0.5rem;
}
Exercice 2 : Lettrine
Crée une lettrine pour le premier paragraphe d'un <article> :
::first-letter : taille 4rem, couleur #7c3aed, flotté à gaucheSolution :
article > p:first-of-type::first-letter {
float: left;
font-size: 4rem;
line-height: 0.8;
font-weight: 800;
color: #7c3aed;
margin-right: 0.5rem;
}
Exercice 3 : Badge dynamique
Crée un badge qui affiche le nombre d'items via data-count :
::afterSolution :
.badge {
position: relative;
padding-right: 2rem;
}
.badge::after {
content: attr(data-count);
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
background: #dc2626;
color: white;
padding: 0.2rem 0.5rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 700;
}
Exercice 4 : ::selection personnalisée
Crée une sélection personnalisée pour un bloc de code :
#7c3aedwhiteSolution :
.code-block::selection {
background: #7c3aed;
color: white;
}
Projet : Blog avec décorations CSS
Crée un fichier index.html et style.css avec :
HTML requis :
<article> avec 3 <h2> et 5 <p><ul> avec 4 items<input> avec placeholderdata-label et data-countCSS requis :
::before : icône décorative avant chaque <h2>::after : badge compteur avec attr(data-count)::first-letter : lettrine pour le premier paragraphe::first-line : première ligne en gras et couleur::selection : sélection personnalisée::marker : puces violettes pour la liste::placeholder : placeholder italicQuiz rapide
::before et ::after ?::first-letter fonctionne sur un <span> ? Oui / Non::first-line cible exactement ?::before ?::before et :before ?:: (deux deux-points)content::placeholder::marker::before est la syntaxe officielle, :before est acceptée par rétrocompatibilité