HTML CSS débutant : le cours pas à pas, un mini-projet et 8 exercices corrigés
L’essentiel en une minute
Ce cours HTML CSS débutant part de zéro et va jusqu’à une page publiée : structure, mise en forme, Flexbox, Grid, responsive, accessibilité et validation, puis huit exercices corrigés et un plan de quatre semaines.
HTML et CSS restent un passage obligé. Dans l’enquête 2026 de Stack Overflow, 58,2 % des 14 099 répondants disent avoir beaucoup développé avec HTML/CSS au cours de l’année écoulée, juste derrière JavaScript (62,0 %) et SQL (58,4 %), et devant Python (58,0 %) et TypeScript (43,8 %) (Stack Overflow Developer Survey 2026, consulté le 5 novembre 2026).
Points clés
- HTML décrit le contenu, CSS son apparence. Quelques jours de HTML sémantique d’abord, puis les deux ensemble.
- Deux outils gratuits suffisent : Visual Studio Code et les DevTools du navigateur.
- Flexbox aligne sur un axe, Grid sur deux. Une media query adapte la page aux petits écrans.
:has(), l’imbrication CSS et les container queries sont « Baseline Widely available » selon MDN.- Le mini-projet est passé sans erreur aux validateurs HTML et CSS du W3C le 5 novembre 2026.

HTML et CSS : qui fait quoi
HTML structure le contenu, CSS le met en forme. Le parcours de MDN, la documentation web de Mozilla, les enseigne dans cet ordre : « Structurer le contenu avec HTML », puis « Bases de la mise en forme CSS » (MDN, modules fondamentaux, consulté le 5 novembre 2026).
| HTML | CSS | |
|---|---|---|
| Rôle | Dire ce qu’est chaque contenu : titre, paragraphe, lien, formulaire | Dire à quoi il ressemble : couleurs, tailles, espacements, disposition |
| Unité de base | La balise, par exemple <h1> ou <a> |
La règle : un sélecteur et des déclarations |
| Fichier | index.html |
style.css, relié par <link> |
JavaScript ajoute ensuite le comportement ; c’est la suite logique, détaillée dans notre guide pour apprendre JavaScript.
Les outils : VS Code et les DevTools
Un éditeur de code et un navigateur suffisent. Visual Studio Code est « gratuit pour un usage privé ou commercial », selon sa FAQ, qui précise qu’il est « construit » sur le code open source Code – OSS (licence MIT) mais distribué sous licence Microsoft (notre traduction) (FAQ de VS Code, consultée le 5 novembre 2026). Trois réglages utiles :
- Le raccourci Emmet. Tapez
!puis Tab dans un fichier.htmlvide : VS Code écrit le squelette de la page. - Une extension d’aperçu. Un serveur local recharge la page à chaque sauvegarde ; notre sélection d’extensions VS Code en compare plusieurs.
- Le formatage automatique. « Format On Save » garde une indentation propre.
Les DevTools sont l’autre moitié de l’outillage. Dans Chrome, Ctrl + Maj + C sous Windows et Linux, ou Cmd + Option + C sur Mac, ouvre le panneau Elements en mode inspection ; un clic droit puis « Inspecter » fait la même chose (Chrome for Developers, consulté le 5 novembre 2026). Vous y voyez le HTML réel, les règles appliquées, celles qui sont barrées et le schéma du modèle de boîte.
La structure d’une page HTML
Toute page commence par le même squelette. Voici la version minimale que nous avons fait passer au validateur du W3C :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ma première page</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<nav aria-label="Navigation principale">
<a href="#apropos">À propos</a>
</nav>
</header>
<main>
<section id="apropos">
<h1>Bonjour</h1>
<p>Ma première page en HTML et CSS.</p>
</section>
</main>
<footer>
<p>Contact : [email protected]</p>
</footer>
</body>
</html>
<!DOCTYPE html> active le mode standard, lang="fr" annonce la langue aux lecteurs d’écran, charset évite les accents cassés, et la balise viewport cale la page sur la largeur de l’écran. Sans elle, un mobile peut rendre la page dans une fenêtre virtuelle plus large, 980 pixels dans l’exemple de MDN, puis la réduire : vos media queries pour petit écran ne se déclenchent pas.
Les balises sémantiques décrivent le rôle de chaque zone : <header> (en-tête), <nav> (navigation), <main> (contenu principal, un seul par page), <section> (partie thématique avec titre), <article> (contenu autonome) et <footer> (pied de page). Un <div> ne dit rien de son contenu : gardez-le pour la mise en forme.
Texte, liens, images, listes, tableaux et formulaires
Les titres et le texte. <h1> à <h6> forment un plan, sans sauter de niveau. <p> crée un paragraphe, <strong> marque une importance.
Les liens. <a href="#contact"> pointe vers une ancre de la page, une adresse complète vers une autre page. Le texte du lien doit avoir un sens seul : jamais « cliquez ici ».
Les images. alt décrit l’image pour qui ne la voit pas ; une image décorative reçoit alt="". width et height évitent que la page saute au chargement.
Les listes. <ul> à puces, <ol> ordonnée, chaque élément dans un <li>.
Les tableaux. Pour des données, jamais pour la mise en page. <caption> donne le titre, <th scope="col"> les en-têtes.
Les formulaires. Chaque champ a un <label> relié par for et id. Le bon type (email, tel) affiche le bon clavier sur mobile ; required bloque un envoi vide.
<form action="/inscription" method="post">
<label for="courriel">E-mail (obligatoire)</label>
<input id="courriel" name="courriel" type="email" autocomplete="email" required>
<button type="submit">S'inscrire</button>
</form>
Les bases de CSS : sélecteurs, cascade et spécificité
Une règle CSS associe un sélecteur à des déclarations. Le sélecteur choisit les éléments, chaque déclaration fixe une propriété :
p {
color: #1f2937;
line-height: 1.6;
}
Les sélecteurs de base : la balise (p), la classe (.carte), l’identifiant (#contact), le descendant (nav a) et les pseudo-classes comme :hover. Préférez les classes : elles se réutilisent.
Quand deux règles visent le même élément, la cascade tranche. MDN la résume en trois critères, du moins fort au plus fort : l’ordre dans le code (à égalité, la dernière règle gagne), la spécificité, puis !important (MDN, gestion des conflits, page modifiée le 6 octobre 2026, consultée le 5 novembre 2026).
La spécificité se lit en trois colonnes : identifiants, classes (avec attributs et pseudo-classes), éléments. Les colonnes se comparent de gauche à droite, et un seul identifiant bat n’importe quel nombre de classes, d’après la même page.
| Sélecteur | Identifiants | Classes | Éléments | Score |
|---|---|---|---|---|
a |
0 | 0 | 1 | 0-0-1 |
.menu a:hover |
0 | 2 | 1 | 0-2-1 |
#menu a |
1 | 0 | 1 | 1-0-1 |
Le panneau Styles des DevTools barre les règles perdantes : c’est le moyen le plus rapide de comprendre pourquoi une couleur ne s’applique pas. Évitez !important.
Modèle de boîte, unités, couleurs et polices
Chaque élément est une boîte : contenu, padding (marge intérieure), border, puis margin (marge extérieure). Par défaut, width ne compte que le contenu ; avec box-sizing: border-box, elle inclut padding et bordure, ce qui rend les calculs prévisibles.
Les unités changent le comportement de la page :
| Unité | Relative à | Usage typique |
|---|---|---|
px |
Rien, valeur fixe | Bordures fines |
rem |
Taille de police de la racine (html) |
Tailles de texte, espacements |
% |
Dimension du parent | Largeurs fluides |
vw, vh |
1 % de la largeur, de la hauteur de la fenêtre | Titres fluides, toujours combinés à rem |
Utilisez rem pour le texte : si le lecteur agrandit sa police, la page suit. N’écrivez jamais une taille de texte en vw seul : elle ne grossit pas avec le zoom, alors que le critère WCAG 1.4.4 demande un texte agrandissable jusqu’à 200 %. clamp(1.75rem, 4vw, 2.5rem) combine un minimum en rem, une valeur fluide et un maximum.
Pour les couleurs, l’hexadécimal (#1d4ed8) suffit ; rangez-les dans des variables (--accent dans :root, puis var(--accent)). Pour les polices, font-family: system-ui, sans-serif utilise la police du système, sans téléchargement.
Flexbox et Grid : la mise en page
Flexbox aligne des éléments sur un axe, Grid les place sur deux. Une barre de navigation est un cas typique de Flexbox :
.site-header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
justify-content répartit sur l’axe principal, align-items aligne sur l’axe secondaire, gap fixe l’espacement. flex-wrap: wrap autorise le retour à la ligne.
Une grille de cartes est un cas typique de Grid :
.cartes {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1.5rem;
}
L’unité fr partage l’espace libre, mais une colonne 1fr ne descend pas sous la largeur de son contenu le plus long : écrivez repeat(3, minmax(0, 1fr)) si un mot ou une image trop large déforme la grille. Retenez : Flexbox pour une rangée de liens, Grid pour une galerie ou une page.
Le responsive design avec les media queries
Une page responsive s’adapte à la largeur de l’écran. Partez du mobile : une colonne par défaut, plus de colonnes quand la place le permet.
.cartes {
display: grid;
grid-template-columns: 1fr;
gap: 1.5rem;
}
@media (min-width: 48rem) {
.cartes {
grid-template-columns: repeat(3, 1fr);
}
}
Sous 48rem, soit 768 pixels avec la taille de police par défaut, les cartes s’empilent ; au-delà, elles passent sur trois colonnes. Nous avons vérifié ce comportement sur le mini-projet : une colonne à 375 pixels de large, trois à 1 280 pixels, et aucun défilement horizontal dans les deux cas.
Complétez avec max-width: 100%; height: auto; sur les images : la première déclaration empêche l’image de déborder, la seconde recalcule la hauteur pour garder ses proportions malgré les attributs width et height. Testez ensuite plusieurs largeurs avec le mode appareil des DevTools.
Le CSS moderne et son statut Baseline
Baseline est l’étiquette commune de web.dev et MDN pour savoir si une fonction CSS est utilisable partout. Une fonction est « Newly available » quand elle marche dans tous les navigateurs du socle : Chrome, Edge, Firefox et Safari, sur ordinateur et sur mobile. Elle devient « Widely available » 30 mois plus tard (web.dev, Baseline, consulté le 5 novembre 2026).
Trois fonctions modernes ont ce statut, d’après les bandeaux de MDN relevés le 5 novembre 2026 :
| Fonction | À quoi elle sert | Statut sur MDN | Disponible partout depuis |
|---|---|---|---|
@container |
Adapter un composant à son conteneur | Widely available | Février 2023 |
:has() |
Cibler un élément selon son contenu | Widely available | Décembre 2023 |
Imbrication & |
Imbriquer des règles sans outil | Widely available | Décembre 2023 |

MDN précise pour @container et l’imbrication que certaines parties peuvent avoir un support variable. Le mini-projet utilise l’imbrication pour ranger les styles de la navigation dans l’en-tête :
.site-header {
display: flex;
a {
color: var(--accent);
}
}
Et :has() change la couleur du bouton tant qu’un champ du formulaire est invalide, sans une ligne de JavaScript :
form:has(:invalid) button {
background: #4b5563;
}
Le bouton reste gris tant que le nom est vide ou que l’e-mail est invalide, et devient bleu quand les deux champs obligatoires sont valides : nous l’avons vérifié avec un test Playwright décrit plus bas. Ce gris n’est qu’un indice : le bouton reste cliquable, et c’est la validation native du navigateur qui bloque l’envoi (vérifié : la page ne change pas et le champ passe en invalide). La couleur ne porte pas seule l’information (critère WCAG 1.4.1) : les labels indiquent « (obligatoire) ».
Accessibilité : les bases dès le premier jour
Une page accessible se lit au clavier, au lecteur d’écran et avec une vue faible. La référence est WCAG 2.2, recommandation du W3C depuis le 5 octobre 2023, dont la version en vigueur date du 12 décembre 2024 (historique des publications du W3C et texte de WCAG 2.2, consultés le 5 novembre 2026). Quatre règles de base :
- Le contraste. Le critère 1.4.3 demande un rapport d’au moins 4,5:1 pour le texte normal et 3:1 pour le grand texte, d’après la même norme.
- Les labels. Chaque champ a un
<label>visible et relié, qui signale aussi les champs obligatoires, par exemple « Nom (obligatoire) » (critère 3.3.2). - Le focus visible. Ne supprimez jamais
outlinesans le remplacer : le critère 2.4.7 exige un indicateur de focus visible au clavier, et le 2.4.11, nouveau en 2.2, interdit que l’élément qui a le focus soit entièrement caché par un contenu de la page, comme un bandeau fixe. Le critère 2.5.8 fixe aussi une cible d’au moins 24 x 24 pixels CSS, sauf exceptions. - Les titres et les images. Des titres sans saut de niveau, un
altsur chaque image utile.
Le mini-projet applique la règle suivante, et notre test au clavier confirme un contour bleu de 3 pixels sur le premier lien atteint avec Tab :
a:focus-visible,
input:focus-visible,
textarea:focus-visible,
button:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 2px;
}
Nos calculs avec la formule du W3C pour le mini-projet : texte #1f2937 sur blanc, 14,68:1 ; liens #1d4ed8 sur #f3f4f6, 6,09:1 ; blanc sur le bouton bleu, 6,7:1, et sur le gris, 7,56:1. Notre première version grisait le bouton avec opacity, ce qui pâlissait le texte : une couleur de fond sombre règle le problème.
Le mini-projet, validé par le W3C
Le projet final est une page de présentation de développeur junior : navigation, trois cartes, un tableau et un formulaire. Nous l’avons écrit puis vérifié le 5 novembre 2026 :
- Validateur HTML du W3C (Nu Html Checker 26.11.5) : zéro erreur, zéro avertissement.
- Validateur CSS du W3C (profil CSS3 + SVG) : zéro erreur, imbrication comprise.
- Rendu avec Playwright dans Chrome 156, Edge 156 et Chromium 120, à 1 280 et 375 pixels : trois colonnes puis une, sans défilement horizontal ni erreur de console.
- Test du formulaire, dans les trois mêmes navigateurs : bouton gris (
#4b5563) avec les champs vides puis avec l’e-mail « lea », bleu (#1d4ed8) avec un e-mail valide ; clic sur « Envoyer » avec le nom vidé : la page ne change pas et le champ est invalide. Une pression sur Tab donne au premier lien un contour plein de 3 pixels décalé de 2 pixels.

Le fichier index.html :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Léa Martin, développeuse web junior</title>
<meta name="description" content="Page de présentation de Léa Martin, développeuse web junior.">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="site-header">
<p class="logo">Léa Martin</p>
<nav aria-label="Navigation principale">
<ul>
<li><a href="#projets">Projets</a></li>
<li><a href="#competences">Compétences</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
<main>
<section class="intro">
<h1>Développeuse web junior</h1>
<p>J'apprends HTML et CSS depuis quatre semaines. Voici mes premiers projets.</p>
</section>
<section id="projets">
<h2>Projets</h2>
<div class="cartes">
<article class="carte">
<img src="img/recette.jpg" alt="Aperçu de la page de recette" width="600" height="400">
<h3>Page de recette</h3>
<p>Titres, listes et image avec texte alternatif.</p>
</article>
<article class="carte">
<img src="img/horaires.jpg" alt="Aperçu du tableau d'horaires" width="600" height="400">
<h3>Tableau d'horaires</h3>
<p>Un tableau avec en-têtes et légende.</p>
</article>
<article class="carte">
<img src="img/formulaire.jpg" alt="Aperçu du formulaire d'inscription" width="600" height="400">
<h3>Formulaire d'inscription</h3>
<p>Chaque champ a son label.</p>
</article>
</div>
</section>
<section id="competences">
<h2>Compétences</h2>
<table>
<caption>Ce que je sais faire après un mois</caption>
<thead>
<tr><th scope="col">Domaine</th><th scope="col">Niveau</th></tr>
</thead>
<tbody>
<tr><td>HTML sémantique</td><td>À l'aise</td></tr>
<tr><td>Flexbox et Grid</td><td>En progrès</td></tr>
</tbody>
</table>
</section>
<section id="contact">
<h2>Contact</h2>
<form action="https://example.com/contact" method="post">
<label for="nom">Nom (obligatoire)</label>
<input id="nom" name="nom" type="text" autocomplete="name" required>
<label for="email">E-mail (obligatoire)</label>
<input id="email" name="email" type="email" autocomplete="email" required>
<label for="message">Message</label>
<textarea id="message" name="message" rows="4"></textarea>
<button type="submit">Envoyer</button>
</form>
</section>
</main>
<footer>
<p>© 2026 Léa Martin</p>
</footer>
</body>
</html>
Le fichier style.css :
:root {
--texte: #1f2937;
--fond: #ffffff;
--accent: #1d4ed8;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
font-size: 1rem;
line-height: 1.6;
color: var(--texte);
background: var(--fond);
}
.site-header {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
gap: 1rem;
padding: 1rem 5%;
background: #f3f4f6;
ul {
display: flex;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
}
a {
color: var(--accent);
}
}
.logo {
margin: 0;
font-weight: 700;
}
main {
max-width: 60rem;
margin: 0 auto;
padding: 0 5%;
}
.intro h1 {
font-size: clamp(1.75rem, 4vw, 2.5rem);
}
.cartes {
display: grid;
grid-template-columns: 1fr;
gap: 1.5rem;
}
.carte {
border: 1px solid #d1d5db;
border-radius: 0.5rem;
padding: 1rem;
}
.carte img {
max-width: 100%;
height: auto;
border-radius: 0.25rem;
}
table {
width: 100%;
border-collapse: collapse;
}
th,
td {
border: 1px solid #d1d5db;
padding: 0.5rem;
text-align: left;
}
form {
display: grid;
gap: 0.5rem;
max-width: 30rem;
}
input,
textarea {
font: inherit;
padding: 0.5rem;
border: 1px solid #6b7280;
border-radius: 0.25rem;
}
a:focus-visible,
input:focus-visible,
textarea:focus-visible,
button:focus-visible {
outline: 3px solid var(--accent);
outline-offset: 2px;
}
form:has(:invalid) button {
background: #4b5563;
}
button {
justify-self: start;
padding: 0.5rem 1.25rem;
font: inherit;
color: #ffffff;
background: var(--accent);
border: 0;
border-radius: 0.25rem;
cursor: pointer;
}
footer {
margin-top: 3rem;
padding: 1rem 5%;
text-align: center;
background: #f3f4f6;
}
@media (min-width: 48rem) {
.cartes {
grid-template-columns: repeat(3, 1fr);
}
}
Un détail de cascade à remarquer : la règle form:has(:invalid) button est placée avant button, mais elle gagne quand même. :has() prend la spécificité de son argument le plus spécifique, ici :invalid : la règle vaut 0-1-2 et dépasse button (0-0-1). Pour valider votre propre page, collez-la sur validator.w3.org/nu ; la page de présentation du validateur rappelle que l’outil est un vérificateur, pas une certification.
Publier sa première page
GitHub Pages publie gratuitement un site statique depuis un dépôt public. La documentation de GitHub décrit la marche à suivre : créer un dépôt nommé <votre-identifiant-github>.github.io, y placer index.html à la racine, choisir la branche de publication dans Settings, puis Pages, et attendre la construction, qui peut prendre jusqu’à dix minutes (GitHub Docs, consulté le 5 novembre 2026).
Avec l’offre GitHub Free, le dépôt doit être public, selon la même page : n’y mettez aucune donnée personnelle. Si Git vous est encore étranger, notre guide Git et GitHub pour débutant va de la première commande au premier dépôt en ligne. Une page publiée devient ensuite la première brique d’un portfolio de développeur.
Exercices HTML CSS débutant corrigés
Faites chaque exercice avant de lire la correction. Le 5 novembre 2026, tous les blocs de code de l’article sont passés aux validateurs HTML et CSS du W3C sans erreur, les extraits HTML étant insérés dans une page complète.
Exercice 1 : le squelette
Écrivez une page minimale en français, avec un titre d’onglet « Exercice 1 », la balise viewport et un <h1>.
Correction.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Exercice 1</title>
</head>
<body>
<h1>Ma première page</h1>
</body>
</html>
Oubli classique : lang="fr". Nous avons retiré cet attribut et repassé la page au validateur du W3C : il répond par un avertissement qui conseille de déclarer la langue.
Exercice 2 : une recette
Créez une recette avec un titre, une image, une liste d’ingrédients non ordonnée et des étapes numérotées.
Correction.
<article>
<h2>Crêpes</h2>
<img src="crepes.jpg" alt="Pile de crêpes dorées dans une assiette" width="600" height="400">
<h3>Ingrédients</h3>
<ul>
<li>250 g de farine</li>
<li>4 œufs</li>
<li>50 cl de lait</li>
</ul>
<h3>Étapes</h3>
<ol>
<li>Mélanger la farine et les œufs.</li>
<li>Ajouter le lait petit à petit.</li>
</ol>
</article>
Exercice 3 : un tableau d’horaires
Affichez les horaires d’une bibliothèque sur trois jours, avec une légende et des en-têtes.
Correction.
<table>
<caption>Horaires de la bibliothèque</caption>
<thead>
<tr><th scope="col">Jour</th><th scope="col">Ouverture</th><th scope="col">Fermeture</th></tr>
</thead>
<tbody>
<tr><th scope="row">Lundi</th><td>9 h</td><td>18 h</td></tr>
<tr><th scope="row">Mardi</th><td>9 h</td><td>18 h</td></tr>
<tr><th scope="row">Samedi</th><td>10 h</td><td>13 h</td></tr>
</tbody>
</table>
Exercice 4 : un formulaire accessible
Créez un formulaire avec un nom obligatoire, un e-mail obligatoire et une liste déroulante de sujets.
Correction.
<form action="/contact" method="post">
<label for="nom-ex">Nom (obligatoire)</label>
<input id="nom-ex" name="nom" type="text" required>
<label for="mail-ex">E-mail (obligatoire)</label>
<input id="mail-ex" name="email" type="email" required>
<label for="sujet">Sujet</label>
<select id="sujet" name="sujet">
<option>Question</option>
<option>Devis</option>
</select>
<button type="submit">Envoyer</button>
</form>
Chaque for vise un id unique : le lecteur d’écran annonce ainsi le champ.
Exercice 5 : le modèle de boîte
Une boîte a width: 300px, padding: 20px et border: 2px solid. Quelle largeur occupe-t-elle à l’écran ?
Correction. En content-box (par défaut) : 300 + 2 × 20 + 2 × 2 = 344 pixels. En border-box : 300 pixels, dont 256 de contenu.
Exercice 6 : la spécificité
Le lien <a> est dans <nav id="menu" class="nav">. De quelle couleur est-il ?
#menu a { color: green; }
.nav a { color: red; }
a { color: blue; }
Correction. Vert. #menu a vaut 1-0-1, .nav a 0-1-1 et a 0-0-1. L’ordre du code ne joue qu’à spécificité égale.
Exercice 7 : une navigation en Flexbox
Placez un logo à gauche et trois liens à droite, centrés verticalement.
Correction.
<header class="site-header">
<p class="logo">Léa Martin</p>
<nav aria-label="Navigation principale">
<ul>
<li><a href="#projets">Projets</a></li>
<li><a href="#competences">Compétences</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
</header>
.site-header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.site-header ul {
display: flex;
gap: 1rem;
list-style: none;
margin: 0;
padding: 0;
}
list-style: none retire les puces, margin: 0 et padding: 0 suppriment le retrait par défaut de la liste.
Exercice 8 : une galerie responsive
Affichez six images sur une colonne sur mobile, deux à partir de 40rem et trois à partir de 64rem.
Correction.
.galerie {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 40rem) {
.galerie {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 64rem) {
.galerie {
grid-template-columns: repeat(3, 1fr);
}
}
Un plan d’apprentissage en 4 semaines
Quatre semaines à raison d’une heure par jour suffisent pour publier une première page propre. Ce plan est une proposition de notre part, pas une norme : adaptez-le à votre rythme.
| Semaine | Objectif | Livrable |
|---|---|---|
| 1 | Structure, balises sémantiques, texte, liens, images | Exercices 1 et 2 |
| 2 | Tableaux, formulaires, sélecteurs, cascade | Exercices 3, 4 et 6 |
| 3 | Modèle de boîte, Flexbox, Grid, media queries | Exercices 5, 7 et 8 |
| 4 | Accessibilité, validation, publication | Le mini-projet en ligne |
Écrivez le code vous-même, sans copier-coller. Ensuite, ajoutez JavaScript puis un framework (notre comparatif React vs Vue aide à choisir), ou visez un premier emploi avec notre guide de la reconversion en développeur web.
Les cours gratuits pour continuer
Les quatre ressources ci-dessous sont gratuites au 5 novembre 2026 ; aucune n’a été suivie de bout en bout pour cet article.
| Ressource | Gratuit ? | Langue | Format | Ce qui la distingue |
|---|---|---|---|---|
| MDN, modules fondamentaux | Oui, sans compte | Français et anglais | Textes et exemples | Module accessibilité dédié |
| OpenClassrooms, Créez votre site web avec HTML5 et CSS3 | Oui, « cours en libre accès » | Français | Cours de 15 heures, quiz | Corrigés sur GitHub, selon la page du cours |
| freeCodeCamp | Oui, le site s’annonce « Learn to Code for Free » | Anglais | Non vérifié | Programme non lu (voir plus bas) |
| web.dev, Learn CSS et Learn HTML | Oui, sans compte | Anglais | Modules de cours | Couvre le CSS moderne, dont l’imbrication |
MDN se décrit comme une plateforme « gratuite, de grande qualité et complète » (notre traduction) (MDN, à propos, consulté le 5 novembre 2026). La fiche d’OpenClassrooms indique 15 heures, un niveau facile et une mise à jour du 7 octobre 2026.
Vous cherchez un cours HTML CSS en PDF ? Celui de Pierre Giraud se dit « 100 % gratuit » et propose un PDF, mais affiche un millésime 2020, et nous n’avons trouvé dans son sommaire ni :has() ni les container queries (Pierre Giraud, consulté le 5 novembre 2026). Cet article s’imprime aussi : Imprimer, puis Enregistrer au format PDF.
Ce que nous n’avons pas pu vérifier
Ce cours HTML CSS débutant s’appuie sur des sources publiques et sur un mini-projet exécuté. Restent ces limites :
- Le rendu dans Firefox et Safari. Mini-projet testé seulement dans des navigateurs à moteur Chromium : Chrome 156 et Edge 156 installés sur le poste, et le Chromium 120 fourni avec Playwright 1.40, une version ancienne.
- Le programme de freeCodeCamp. Ses pages se chargent en JavaScript ; seule la mention « Learn to Code for Free » a été lue.
- Le prix éventuel du PDF de Pierre Giraud. Un montant lu le 2 novembre n’a pas été retrouvé le 5 novembre 2026.
- La durée réelle d’apprentissage. Le plan de quatre semaines est une proposition, non une mesure.
- La publication sur GitHub Pages. Non effectuée ; la procédure vient de la documentation de GitHub.
Questions fréquentes
Combien de temps pour apprendre HTML et CSS ?
Quelques semaines de pratique régulière pour les bases. Le cours d’OpenClassrooms annonce 15 heures ; notre plan propose quatre semaines à une heure par jour jusqu’à une page publiée.
Faut-il apprendre HTML avant CSS ?
Oui, de quelques jours de HTML sémantique, puis les deux ensemble. CSS met en forme un HTML existant, et le parcours de MDN suit cet ordre.
HTML et CSS sont-ils des langages de programmation ?
Non. HTML est un langage de balisage et CSS un langage de feuilles de style, sans boucles ni logique de programme. Ils restent la base du web : 58,2 % des répondants de l’enquête Stack Overflow 2026 disent avoir beaucoup développé avec HTML/CSS dans l’année écoulée.
Où trouver un cours HTML CSS gratuit en français ?
MDN, en français et sans compte, et le cours en libre accès d’OpenClassrooms. freeCodeCamp et web.dev Learn sont gratuits aussi, mais en anglais.
À propos de l’auteur
Abdelilah Ourti est ingénieur IA et architecte logiciel. Il conçoit et déploie des applications web et des systèmes d’IA, et publie sur NeurauTech des guides et des comparatifs destinés aux développeurs francophones. Ses autres articles sont réunis sur sa page auteur.
Méthode. Synthèse de la documentation de MDN, web.dev, du W3C, de GitHub et de Chrome for Developers, consultée le 5 novembre 2026. Tests effectués, et seulement ceux-là : les quatre vérifications listées dans la section du mini-projet, plus le passage de tous les blocs de code aux validateurs du W3C, dont une variante sans lang. Les contrastes sont calculés avec la formule du W3C. Citations anglaises traduites par nos soins. Aucun lien affilié, aucune relation commerciale avec les plateformes citées.
Une erreur ou une information périmée ? Écrivez à [email protected] : l’article sera corrigé et la date de mise à jour modifiée.
Dernière mise à jour : 5 novembre 2026.
Image d’en-tête : Jakub Żerdzicki (Unsplash License). Capture du mini-projet et graphiques : NeurauTech.
