Ce que vous saurez faire à la fin
- Construire un site web propre avec HTML5 sémantique et CSS moderne (Grid, Flexbox, variables)
- Produire un design responsive sans framework en écrivant 40 % de code en moins qu’avant 2020
- Utiliser les nouvelles fonctions CSS :
:has(),container queries,@layer - Optimiser les Core Web Vitals de base (LCP, CLS) sans outil externe
- Livrer une landing page complète en 4 heures
Prérequis
- VS Code ou Cursor avec extensions « Live Server » et « Prettier »
- Chrome ou Firefox récent (pour DevTools responsive)
- Un navigateur récent (HTML et CSS moderne nécessitent Chrome 105+, Safari 16+)
Étape 1 — Squelette HTML5 sémantique
Fini les <div> partout. Utilisez les balises qui ont du sens pour Google et les lecteurs d’écran.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Votre titre SEO | Marque</title>
<meta name="description" content="155 caractères qui vendent">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header> <nav>...</nav> </header>
<main>
<section class="hero">...</section>
<article>...</article>
</main>
<footer>...</footer>
</body>
</html>
Étape 2 — CSS moderne avec variables et @layer
:root {
--color-primary: #1a5490;
--color-accent: #f39c12;
--radius: 8px;
--space-sm: 0.5rem;
--space-md: 1rem;
--space-lg: 2rem;
--font-sans: 'Inter', system-ui, sans-serif;
}
@layer reset, base, components, utilities;
@layer reset {
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
}
@layer base {
body {
font-family: var(--font-sans);
line-height: 1.6;
color: #222;
}
}
Étape 3 — Grid pour layouts complexes
.grid-products {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: var(--space-md);
}
/* Le auto-fill gère automatiquement le responsive, plus besoin de media queries classiques */
Étape 4 — Flexbox pour les petits composants
.card {
display: flex;
flex-direction: column;
gap: var(--space-sm);
padding: var(--space-md);
}
.card-actions {
display: flex;
justify-content: space-between;
margin-top: auto;
}
Étape 5 — Le sélecteur :has() change tout
Sélectionner un parent selon son enfant, impossible avant 2023.
/* Si une carte contient un badge "Nouveau", surlignez-la */
.card:has(.badge-new) {
border: 2px solid var(--color-accent);
background: #fff8e1;
}
/* Si un formulaire a un champ en erreur, bordure rouge sur le form */
form:has(:invalid) { border-color: red; }
Étape 6 — Container queries
Responsive basé sur le conteneur, pas la fenêtre. Indispensable pour composants réutilisables.
.sidebar { container-type: inline-size; container-name: side; }
@container side (min-width: 400px) {
.widget { display: grid; grid-template-columns: 1fr 2fr; }
}
Étape 7 — Images responsives et Core Web Vitals
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero.webp" type="image/webp">
<img src="hero.jpg" alt="Description" width="1200" height="600" loading="lazy" fetchpriority="high">
</picture>
Points clés : toujours width et height (évite le CLS), loading="lazy" pour les images sous la ligne de flottaison, fetchpriority="high" pour le LCP hero.
Étape 8 — Typographie fluide sans media queries
h1 { font-size: clamp(1.75rem, 1rem + 3vw, 3rem); }
p { font-size: clamp(0.95rem, 0.85rem + 0.5vw, 1.125rem); }
Étape 9 — Animations accessibles
.button { transition: transform 0.2s ease; }
.button:hover { transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}
Erreurs à bannir
- Pixel partout : utilisez
rempour la typo,empour les marges locales - Oublier alt : image sans alt = inaccessible + pénalité Google
- Font-family générique seule : toujours un fallback système
- Trop de !important : signe d’un CSS mal structuré ; utilisez @layer
Prochaines étapes
- Migrer vers Tailwind CSS v4 si le projet dépasse 5 000 lignes de CSS
- Mesurer vos Core Web Vitals avec PageSpeed Insights
- Apprendre les View Transitions API pour animations inter-pages sans framework