Chapitre 4
Chapitre 04 — CSS : Cascading Style Sheets
Chapitre 04 — CSS : Cascading Style Sheets
Chapitre 04 — CSS : Cours Complet
1. Histoire et Évolution de CSS
1.1 CSS1 (1996)
CSS Level 1 (Håkon Wium Lie, Bert Bos) introduit les concepts fondamentaux :
- Sélecteurs de type, classe, ID
- Propriétés de texte (font, color, letter-spacing)
- Marges, paddings, bordures
- Floats (pour l'enroulement du texte)
1.2 CSS2 (1998)
CSS 2.0 ajoute le positionnement, les z-index, les media types, et les tables. CSS 2.1 (2011) corrige les bugs et devient le standard stable le plus longtemps utilisé.
1.3 CSS3 et l'Ère Modulaire
À partir de 2005, le W3C divise CSS en modules indépendants avec leurs propres niveaux de maturité. CSS3 n'est pas une version monolithique — c'est un ensemble de modules :
Diagramme en cours de génération...
2. Cascade, Spécificité, Héritage
2.1 La Cascade
La cascade est l'algorithme qui détermine quelle règle CSS s'applique quand plusieurs ciblent le même élément. Par ordre de priorité :
- User Agent (styles navigateur par défaut)
- User (styles utilisateur, ex: accessibilité)
- Author (vos styles !)
- Importance (
!important— à éviter)
2.2 Spécificité : Le Calcul
La spécificité se calcule comme un poids à 4 valeurs (A-B-C-D) :
Diagramme en cours de génération...
| Sélecteur | A (inline) | B (IDs) | C (classes, pseudo) | D (éléments) |
|---|---|---|---|---|
style="" | 1 | 0 | 0 | 0 |
#header | 0 | 1 | 0 | 0 |
.nav | 0 | 0 | 1 | 0 |
a:hover | 0 | 0 | 1 | 1 |
ul li | 0 | 0 | 0 | 2 |
/* Spécificité : 0-0-1-0 */
.highlight { color: yellow; }
/* Spécificité : 0-0-0-1 */
p { color: blue; }
/* Spécificité : 0-1-0-1 (GAGNE) */
#intro p { color: red; }
/* Spécificité : 0-0-1-1 (perd face à l'ID) */
.highlight p { color: green; }
Règle d'or : Ne jamais utiliser !important dans les feuilles de style applicatives. Réservez-le pour les overrides d'accessibilité ou de thème.
2.3 Héritage
Toutes les propriétés ne s'héritent pas :
/* Propriétés qui HERITENT */
color, font-*, line-height, text-align, visibility, cursor
/* Propriétés qui N'HÉRITENT PAS */
margin, padding, border, background, width, height, display, position
/* Forcer l'héritage */
enfant {
color: inherit;
all: inherit; /* Tout hériter (déconseillé) */
}
3. Box Model
3.1 content-box vs border-box
Diagramme en cours de génération...
/* content-box : width = CONTENU uniquement */
.box-content {
box-sizing: content-box;
width: 300px; /* Le contenu fait 300px */
padding: 20px; /* Largeur totale : 300 + 20*2 = 340px */
border: 2px solid black; /* Largeur totale : 340 + 2*2 = 344px */
}
/* border-box : width = CONTENU + PADDING + BORDER */
.box-border {
box-sizing: border-box;
width: 300px; /* Tout tient dans 300px */
padding: 20px; /* Contenu effectif : 300 - 40 - 4 = 256px */
border: 2px solid black;
}
Bonnes pratiques : Appliquer border-box globalement :
*, *::before, *::after {
box-sizing: border-box;
}
4. Layouts Modernes
4.1 Normal Flow → Float → Flexbox → Grid
Diagramme en cours de génération...
4.2 Flexbox en Détail
Flexbox est un modèle de layout unidimensionnel (ligne OU colonne).
Diagramme en cours de génération...
.container {
display: flex;
flex-direction: row; /* row | column | row-reverse | column-reverse */
flex-wrap: wrap; /* nowrap | wrap | wrap-reverse */
justify-content: center; /* Axe principal */
align-items: stretch; /* Axe cross */
gap: 1rem; /* Espacement (moderne, remplace margin) */
}
.item {
flex: 1 1 300px; /* grow shrink basis */
/* équivaut à :
flex-grow: 1;
flex-shrink: 1;
flex-basis: 300px;
*/
align-self: center; /* Override align-items */
order: 2; /* Ordre visuel (attention accessibilité !) */
}
Propriétés clés de flex :
- flex-grow : capacité à grandir (0 = ne grandit pas)
- flex-shrink : capacité à rétrécir (0 = ne rétrécit pas)
- flex-basis : taille de base avant distribution
4.3 CSS Grid en Détail
Grid est un modèle bidimensionnel (lignes ET colonnes).
.grid-container {
display: grid;
grid-template-columns: 1fr 2fr 1fr; /* 3 colonnes */
grid-template-rows: auto 1fr auto; /* 3 lignes */
gap: 1rem;
grid-template-areas:
"header header header"
"sidebar content aside"
"footer footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }
Unités Grid :
fr: fraction de l'espace disponibleminmax(200px, 1fr): minimum 200px, puis fractionauto-fill/auto-fit: remplissage automatiquemin-content/max-content: taille intrinsèque
/* Grille responsive sans media queries */
.grid-auto {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 1rem;
}
4.4 Comparaison Flexbox vs Grid
| Critère | Flexbox | Grid |
|---|---|---|
| Dimension | 1D (ligne OU colonne) | 2D (lignes ET colonnes) |
| Cas d'usage | Navigation, centrage, rangées | Pages complètes, galeries, dashboards |
| Ordre source | order peut réordonner | Placement explicite |
| Gap | gap supporté | gap supporté |
| Contrôle | Distribution d'espace | Placement de cellules |
| Responsive | flex-wrap | auto-fill + minmax |
Règle empirique : Flexbox pour les composants, Grid pour les layouts de page.
5. Responsive Design
5.1 Media Queries
/* Mobile-first : base pour mobile, puis breakpoints */
.card { display: flex; flex-direction: column; }
/* ≥ 768px : tablette */
@media (min-width: 768px) {
.card { flex-direction: row; }
}
/* ≥ 1024px : desktop */
@media (min-width: 1024px) {
.card { display: grid; grid-template-columns: 1fr 2fr; }
}
/* Media queries avancées */
@media (prefers-color-scheme: dark) { /* Dark mode */ }
@media (prefers-reduced-motion: reduce) { /* Accessibilité */ }
@media (hover: hover) { /* Souris disponible */ }
@media (pointer: coarse) { /* Tactile */ }
5.2 Container Queries
Les container queries (2022+) permettent de réagir à la taille du conteneur parent, pas du viewport :
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card { flex-direction: row; }
}
@container card (min-width: 600px) {
.card { display: grid; grid-template-columns: 1fr 2fr; }
}
5.3 clamp(), min(), max()
/* Taille fluide qui clamp entre 16px et 32px */
font-size: clamp(1rem, 2.5vw, 2rem);
/* Largeur : minimum 320px, idéalement 80%, maximum 1200px */
width: min(80%, 1200px);
/* Hauteur minimale */
min-height: max(400px, 50vh);
/* Typographie responsive : la "formule magique" */
font-size: clamp(1rem, 0.5rem + 2vw, 2rem);
6. CSS Custom Properties vs Préprocesseurs
6.1 Les CSS Custom Properties (Variables)
:root {
--color-primary: #3498db;
--spacing-unit: 0.5rem;
--font-base: 'Inter', system-ui, sans-serif;
}
.button {
--btn-bg: var(--color-primary);
background: var(--btn-bg, blue); /* blue = fallback */
padding: calc(var(--spacing-unit) * 2);
font-family: var(--font-base);
}
6.2 Variables CSS vs SCSS
| Critère | CSS Custom Properties | Variables SCSS |
|---|---|---|
| Portée | DOM (héritage, cascade) | Compilation statique |
| Runtime | Dynamique (changement live) | Statique (compilé) |
| Media Queries | Oui (cascade) | Non |
| JavaScript | Accessible via style.setProperty | Non accessible |
| Dark Mode | Parfait | Impossible sans duplication |
| Calculs | calc() | Intégré au langage |
Quand utiliser quoi ?
- CSS Custom Properties : thèmes, design tokens, animations dynamiques
- SCSS : mixins, boucles, nesting (bientôt remplacé par CSS Nesting)
7. Design Tokens
/* tokens.css */
:root {
/* Couleurs */
--color-brand-primary: #6C5CE7;
--color-brand-secondary: #00B894;
--color-neutral-100: #F8F9FA;
--color-neutral-900: #212529;
/* Typographie */
--font-family-base: 'Inter', system-ui, sans-serif;
--font-family-heading: 'Inter', sans-serif;
--font-size-xs: 0.75rem;
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.25rem;
--font-size-xl: 1.5rem;
--font-weight-normal: 400;
--font-weight-bold: 700;
/* Espacement */
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-4: 1rem;
--space-8: 2rem;
/* Bordures */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 16px;
/* Ombres */
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
--shadow-md: 0 4px 6px rgba(0,0,0,0.1);
--shadow-lg: 0 10px 15px rgba(0,0,0,0.1);
}
8. Animations
8.1 Transitions
.button {
background: var(--color-primary);
transform: scale(1);
transition:
background 0.3s ease,
transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.button:hover {
background: var(--color-primary-dark);
transform: scale(1.05);
}
8.2 @keyframes et Animations
@keyframes fade-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.animated {
animation: fade-in 0.5s ease-out forwards;
}
.spinner {
animation: spin 1s linear infinite;
}
8.3 Performance : will-change
/* Indiquer au navigateur ce qui va bouger */
.animated-element {
will-change: transform, opacity;
/* ⚠️ N'appliquer que sur l'élément qui s'anime */
/* ⚠️ Retirer après l'animation si possible (via JS) */
}
Le navigateur peut promouvoir l'élément dans un compositing layer dédié, évitant des repaints coûteux. Les propriétés "bon marché" pour les animations :
transform(translate, scale, rotate)opacityfilter(dans certains cas)
9. CSS Layers (@layer)
Les CSS Layers (2022) permettent de contrôler la cascade par couche :
/* Définition de l'ordre des couches */
@layer reset, base, components, utilities, overrides;
/* Règles dans chaque couche */
@layer reset {
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
}
}
@layer base {
body { font-family: system-ui; line-height: 1.5; }
}
@layer components {
.card { padding: 1rem; background: white; }
}
@layer utilities {
.mt-4 { margin-top: 1rem; }
}
/* Override avec une couche anonyme */
@layer {
.emergency-banner { background: red !important; }
}
Avantages : Plus besoin de lutter contre la spécificité. L'ordre des couches prime sur la spécificité.
10. :has() Selector et Nouvelles Fonctionnalités
10.1 Le Selector :has()
Surnommé "le parent selector", :has() permet de cibler un élément en fonction de ses descendants :
/* Style un article qui contient une image */
article:has(img) { grid-column: span 2; }
/* Style un label qui contient un input invalide */
label:has(:invalid) { color: red; }
/* Style un parent qui a au moins 3 enfants */
.parent:has(> *:nth-child(3)) { border: 2px solid; }
/* Condition : détection de scroll horizontal */
body:has(.horizontal-scroll) { overflow-x: hidden; }
10.2 CSS Nesting (2023-2024)
/* CSS Nesting natif */
.card {
padding: 1rem;
& .title {
font-size: 1.25rem;
}
& .body {
color: gray;
}
&:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
@media (width >= 768px) {
& { padding: 2rem; }
}
}
11. Méthodologies CSS
11.1 BEM (Block Element Modifier)
/* Block */
.card { }
/* Element */
.card__title { }
.card__body { }
/* Modifier */
.card--featured { }
.card__title--large { }
/* HTML */
<article class="card card--featured">
<h2 class="card__title card__title--large">Titre</h2>
<p class="card__body">Contenu</p>
</article>
11.2 ITCSS (Inverted Triangle CSS)
Diagramme en cours de génération...
11.3 Utility-First (Tailwind)
<article class="max-w-sm mx-auto bg-white rounded-xl shadow-md overflow-hidden md:max-w-2xl">
<div class="md:flex">
<div class="md:shrink-0">
<img class="h-48 w-full object-cover md:h-full md:w-48" src="..." alt="">
</div>
<div class="p-8">
<div class="uppercase tracking-wide text-sm text-indigo-500 font-semibold">Category</div>
<a href="#" class="block mt-1 text-lg leading-tight font-medium text-black hover:underline">Title</a>
<p class="mt-2 text-gray-500">Description</p>
</div>
</div>
</article>
Avantages : Rapidité, pas de nommage, bundle plus petit (purge), cohérence. Inconvénients : HTML bavard, courbe d'apprentissage, pas idéal pour sites complexes.
12. Dark Mode
:root {
--bg: #ffffff;
--text: #1a1a1a;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #1a1a1a;
--text: #ffffff;
}
}
body {
background: var(--bg);
color: var(--text);
}
/* Nouvelle fonction light-dark() (2024+) */
body {
background: light-dark(white, #1a1a1a);
color: light-dark(#1a1a1a, white);
}
13. Performance CSS
13.1 Containment
/* Isoler un composant pour limiter les recalculs */
.widget {
contain: layout style paint;
/* content = layout style paint (tout) */
content-visibility: auto; /* Lazy rendering hors viewport */
}
13.2 Paint Areas
Minimiser les zones de repaint :
- Préférer
transformetopacitypour les animations - Utiliser
will-changeavec parcimonie - Éviter les sélecteurs complexes (
.container > ul > li > a) - Éviter les repaints globaux
13.3 Checklist Performance
-
content-visibility: autosur les sections hors écran -
contain: layout style paintsur les composants isolés - Animations sur
transformetopacityuniquement -
will-changeretiré après animation -
@layerpour ordonner la cascade - Pas de
!importantdans le code applicatif -
clamp()pour typographie responsive - Container queries pour composants réutilisables
14. Erreurs des Juniors
/* ❌ Spécificité excessive */
#header .nav ul li a { color: blue; }
/* ✅ Minimaliste */
.nav a { color: blue; }
/* ❌ !important partout */
.button { background: blue !important; }
/* ✅ Couches ou cascade normale */
@layer components {
.button { background: blue; }
}
/* ❌ Dimensions absolues */
.container { width: 1200px; }
/* ✅ Fluides */
.container { width: min(90%, 1200px); }
/* ❌ Pas de fallback pour les variables */
.button { background: var(--primary); }
/* ✅ Fallback explicite */
.button { background: var(--primary, #3498db); }
/* ❌ Animation sur propriétés coûteuses */
.element { animation: slide 1s; }
@keyframes slide {
from { left: 0; top: 0; } /* left/top = layout trigger */
to { left: 100px; top: 50px; }
}
/* ✅ Transform uniquement */
@keyframes slide {
from { transform: translate(0, 0); }
to { transform: translate(100px, 50px); }
}
Résumé
Le CSS moderne est un langage puissant avec des outils sophistiqués. Les ingénieurs front-end doivent maîtriser :
- Cascade et spécificité (la règle d'or de CSS)
- Box Model (border-box global)
- Flexbox pour les composants 1D, Grid pour les layouts 2D
- Responsive design avec container queries + clamp()
- CSS Custom Properties pour les thèmes et tokens
- @layer pour structurer la cascade
- Animations sur transform/opacity
- Méthodologie (BEM, ITCSS, ou Utility-first selon le projet)