Toute page Web repose sur deux langages complémentaires : HTML dit ce que contient la page (un titre, un paragraphe, un lien, une image), CSS dit à quoi elle doit ressembler (couleurs, polices, disposition). Cinq planches pour voir comment le navigateur lit le HTML, résout les conflits entre règles CSS, calcule la taille des boîtes et leur disposition, puis pour créer vos propres pages.
En 1989, au CERN, Tim Berners-Lee propose un système de documents reliés par des liens : le World Wide Web. Il invente pour cela le langage HTML (HyperText Markup Language), où des balises comme <h1> ou <a> entourent le texte pour en indiquer le rôle ; le premier site est mis en ligne en août 1991. Très vite, les auteurs veulent maîtriser l'apparence, et les navigateurs ajoutent au HTML des balises de mise en forme comme <font>. Pour remettre de l'ordre, Håkon Wium Lie propose en octobre 1994 les feuilles de style en cascade, CSS (Cascading Style Sheets), publiées par le W3C en 1996 : le HTML porte le contenu, le CSS la présentation. La même page peut ainsi changer complètement d'aspect sans toucher à son contenu.
Le navigateur ne lit pas le HTML comme un texte : il le transforme en un arbre d'éléments, le DOM, où chaque balise devient un nœud contenant d'autres nœuds. Pendant des années, chaque navigateur a corrigé à sa manière les erreurs des pages : balises oubliées, mal imbriquées, mal placées. Depuis HTML5, la norme décrit au contraire, pas à pas, comment construire l'arbre à partir de n'importe quel texte, même incorrect : tous les navigateurs obtiennent le même résultat. Choisissez un exemple ou écrivez votre propre HTML, et regardez l'arbre se construire.
<html>, <head> et <body> : le navigateur les ajoute. Il ferme seul les paragraphes et les éléments de liste, ajoute le <tbody> des tableaux, et déplace le texte égaré dans un tableau juste avant celui-ci. Mais il ne devine pas les intentions : un titre jamais fermé avale toute la suite. Le premier HTML de 1991 comptait 18 balises ; la norme actuelle, le HTML Living Standard tenu à jour en continu depuis 2019, en définit plus d'une centaine, dont beaucoup sont sémantiques (<header>, <nav>, <article>) : elles disent ce qu'est un contenu, ce qui aide les moteurs de recherche et les lecteurs d'écran des personnes aveugles.Plusieurs règles CSS peuvent viser le même élément avec des valeurs contradictoires. Le « C » de CSS, la cascade, les départage : d'abord l'importance (une règle marquée !important passe devant), puis la spécificité du sélecteur, un triplet (identifiants, classes, types) comparé chiffre par chiffre, enfin l'ordre d'écriture : à égalité, la dernière règle gagne. Les règles ci-dessous visent le paragraphe d'exemple ; la page calcule le vainqueur selon ces principes, puis compare avec la couleur réellement appliquée par le navigateur.
#id pèse plus que n'importe quel nombre de classes, et une classe plus que n'importe quel nombre de noms de balises : (1, 0, 0) bat (0, 12, 0). L'héritage ne vient qu'en dernier : une couleur donnée au parent passe aux enfants, sauf si une règle, même très faible comme *, vise l'enfant directement. :where() ne compte pour rien, :is() et :not() prennent la spécificité de leur argument le plus fort. Le style écrit dans l'attribut style bat toutes les feuilles, sauf !important. La cascade permet de combiner sans conflit le style par défaut du navigateur, celui du site et les préférences de l'utilisateur (grands caractères, contraste élevé), une idée centrale de la proposition de 1994.Pour CSS, chaque élément est une boîte rectangulaire faite de quatre couches emboîtées : le contenu, la marge intérieure (padding), la bordure (border) et la marge extérieure (margin). La propriété width fixe normalement la largeur du seul contenu ; avec box-sizing: border-box, elle fixe la largeur bordure comprise, ce que faisait déjà Internet Explorer 5 en 1999, au grand dam des auteurs de l'époque. Réglez les couches : la boîte réelle ci-dessous est mesurée par le navigateur.
Deux paragraphes l'un sous l'autre : le premier a une marge basse, le second une marge haute. Quel est l'écart entre eux ?
content-box, la largeur visible vaut width + 2 × padding + 2 × border : ajouter une bordure élargit la boîte, ce qui casse facilement une mise en page. C'est pourquoi la plupart des sites commencent aujourd'hui par * { box-sizing: border-box; }, propriété reconnue par tous les navigateurs depuis le début des années 2010. Autre subtilité héritée de l'imprimerie : entre deux blocs, les marges verticales fusionnent, l'écart vaut la plus grande des deux et non leur somme. Ce n'est plus le cas dans un conteneur flex ou grille.Pendant quinze ans, faute de mieux, on a mis en page avec des tableaux, puis avec des éléments « flottants » prévus pour habiller une image de texte. Le module Flexbox, proposé en 2009 et utilisable partout vers 2015, dispose enfin des éléments sur une ligne en partageant l'espace selon des règles précises : chaque élément part de sa taille de base (flex-basis) ; s'il reste de la place, elle est distribuée au prorata de flex-grow ; s'il en manque, on retire au prorata de flex-shrink multiplié par la base. Le conteneur ci-dessous est un vrai conteneur flex ; la page refait le calcul de la norme et le compare aux positions mesurées.
flex-grow ne partage pas la largeur totale mais seulement l'espace restant : deux éléments de bases différentes et de même flex-grow gardent leur écart de taille. Le rétrécissement est proportionnel à flex-shrink × flex-basis, pour que les grands éléments cèdent davantage. justify-content place ensuite ce qui reste de vide. Pour les mises en page en deux dimensions (lignes et colonnes), CSS Grid, arrivé dans les navigateurs en mars 2017, complète Flexbox ; l'exemple 3 de l'atelier l'utilise. Avec les media queries (2012), qui adaptent le style à la largeur de l'écran, ces outils rendent possible le responsive web design : une même page pour l'ordinateur et le téléphone.Écrivez du HTML et du CSS et voyez le résultat immédiatement, à la manière des éditeurs en ligne. Choisissez un exemple, modifiez-le, puis changez la largeur de l'écran simulé pour voir la page s'adapter. L'atelier vérifie aussi un point d'accessibilité essentiel : le contraste entre chaque texte et son fond, selon les règles internationales WCAG. Un rapport d'au moins 4,5 est demandé pour le texte courant, 3 pour les grands caractères, afin que les personnes malvoyantes puissent lire.
:has() et imbrication des règles (disponibles partout depuis 2023) en font un langage puissant, qui continue d'évoluer : l'initiative Interop 2026 des éditeurs de navigateurs vise par exemple l'ancrage des info-bulles et les transitions entre pages. Le contraste se calcule à partir de la luminance relative L de chaque couleur : rapport = (Lclair + 0,05) / (Lfoncé + 0,05), de 1 (texte invisible) à 21 (noir sur blanc).Toutes les pages Web sont écrites en HTML ; selon W3Techs, 96,1 % des sites dont le format est connu déclaraient HTML5 le 28 octobre 2026. Les gestionnaires de contenu comme WordPress fabriquent ce HTML automatiquement.
Applications Web installables (PWA), logiciels de bureau construits avec Electron, interfaces de télévisions, de voitures ou de bornes : HTML et CSS servent bien au-delà du navigateur.
Les livres numériques au format EPUB sont du HTML mis en forme par CSS ; les courriels riches sont en HTML ; CSS sait aussi mettre en page pour l'impression et produire des PDF.
Un HTML sémantique et un CSS soigné rendent les pages utilisables avec un lecteur d'écran, au clavier ou avec de grands caractères. En France, le référentiel RGAA fixe ces exigences pour les sites publics.
Les arbres de la planche 1 ont été construits par la bibliothèque Python html5lib au moment de la fabrication de la page, et les contrastes de la planche 5 recalculés par Python ; les résultats sont inclus pour contrôle. Les planches 2 à 4 sont contrôlées directement par le moteur de rendu de votre navigateur. Sources des chiffres : W3Techs (octobre 2026), web.dev (Interop 2026).