← Retour à l'accueil

Le langage CSS 3

01. Introduction — qu'est-ce que le CSS ?

CSS signifie « feuilles de style en cascade ». Là où le HTML décrit ce qu'il y a dans la page (un titre, un paragraphe, une image), le CSS décrit à quoi ça ressemble : couleur, taille, police, espacements, position à l'écran.

Reprenons l'image de la maison vue dans le cours HTML : le HTML, c'est le gros œuvre (murs, pièces, portes) ; le CSS, c'est la peinture, le carrelage, les meubles et l'éclairage. Même maison, ambiance complètement différente selon la décoration choisie.

Cette séparation des rôles a trois gros avantages :

1.1 Pourquoi « en cascade » ?

Parce que plusieurs règles peuvent viser le même élément : le navigateur applique alors un ordre de priorité précis pour décider laquelle l'emporte, comme une cascade où l'eau descend de bassin en bassin. On décortiquera ce mécanisme au chapitre 05 — c'est LA notion qui évite des heures de « mais pourquoi ma couleur ne s'applique pas ?! » 😅

1.2 CSS 3, et après ?

On parle souvent de CSS 3, mais depuis cette version le langage n'évolue plus par « numéros » : il est découpé en modules (couleurs, Flexbox, Grid, animations…) qui progressent chacun à leur rythme. En pratique, tout ce que tu verras ici fonctionne dans les navigateurs actuels (Firefox, Chrome, Edge, Safari).

Bon à savoir : ton meilleur allié pour apprendre le CSS est déjà installé : les outils de développement du navigateur. Appuie sur F12 (ou clic droit → Inspecter) sur n'importe quel élément de cette page : tu verras toutes les règles CSS qui s'y appliquent, et tu pourras même les modifier en direct pour tester. Rien n'est enregistré : un rechargement de page remet tout en ordre.
↑ Retour au sommaire

02. Anatomie d'une règle CSS

Une feuille de style est une suite de règles. Chaque règle répond à deux questions : « à qui ? » et « quoi ? ».

h1 {
    color: #c2410c;
    font-size: 1.6rem;
}

L'Atelier Informatique du Finistère

Décortiquons-la pièce par pièce :

Vocabulaire d'une règle CSS
ÉlémentDans l'exempleRôle
Sélecteurh1désigne quels éléments HTML sont visés
Bloc de déclarations{ … }regroupe toutes les instructions entre accolades
Déclarationcolor: #c2410c;une instruction = une propriété + une valeur
Propriétécolorla caractéristique qu'on modifie
Valeur#c2410cce qu'on lui donne

Les règles de ponctuation sont simples mais strictes :

Piège classique : oublier un point-virgule. Le navigateur ne t'affiche aucune erreur : il ignore silencieusement la déclaration fautive et souvent la suivante. Si une propriété « ne marche pas », vérifie d'abord la ponctuation de la ligne au-dessus. Par prudence, mets aussi un ; après la dernière déclaration du bloc, même s'il est facultatif : le jour où tu ajouteras une ligne, tu ne l'oublieras pas.

2.1 Les commentaires

En CSS, un commentaire s'écrit entre /* et */. Il peut tenir sur une ligne ou en occuper plusieurs, et le navigateur l'ignore totalement :

/* ===== Palette de l'atelier ===== */
h1 {
    color: #c2410c;   /* cuivre brûlé */
}

/*
   Les cartes de service seront stylées plus bas,
   dans la partie « Composants ».
*/
Bon à savoir : la syntaxe // utilisée dans d'autres langages (comme JavaScript) n'existe pas en CSS. Et attention à ne pas confondre avec le commentaire HTML <!-- --> vu dans le premier cours.

2.2 Mise en forme du code

Les espaces et retours à la ligne n'ont aucune importance pour le navigateur. Les deux écritures suivantes sont strictement équivalentes :

/* Compacte : pratique pour une règle très courte */
.prix { color: #c2410c; font-weight: 700; }

/* Aérée : la norme dès qu'il y a plusieurs déclarations */
.prix {
    color: #c2410c;
    font-weight: 700;
}

Adopte la version aérée, avec une déclaration par ligne et une indentation de 4 espaces : c'est celle que tu retrouveras dans 99 % des projets professionnels.

↑ Retour au sommaire

03. Intégrer du CSS : en ligne, interne, externe

Il existe trois façons de relier du CSS à une page HTML. Toutes fonctionnent, mais elles ne se valent pas du tout.

3.1 En ligne — l'attribut style

On écrit les déclarations directement dans la balise, via l'attribut style (sans sélecteur ni accolades, puisque la cible est la balise elle-même) :

<p style="color: #2e7d32; font-weight: 700;">
    Diagnostic gratuit et sans engagement.
</p>

Diagnostic gratuit et sans engagement.

À éviter (sauf dépannage) : le style en ligne ne concerne qu'une seule balise. Si tu as 30 paragraphes à mettre en vert, il faut copier 30 fois l'attribut… et les modifier 30 fois le jour où tu changes d'avis. Il mélange aussi contenu et présentation, exactement ce que le CSS cherche à éviter. On le réserve aux tests rapides et aux rares cas où une valeur est générée dynamiquement.

3.2 Interne — la balise <style>

Les règles sont regroupées dans une balise <style> placée dans le <head> de la page :

<head>
    <meta charset="UTF-8">
    <title>Nos services</title>
    <style>
        p {
            color: #1f2937;
            line-height: 1.6;
        }
    </style>
</head>

C'est mieux : toutes les règles sont au même endroit et visent tous les éléments concernés de la page. Limite : elles ne valent que pour cette page. C'est le choix de ce cours, pour qu'il reste un fichier unique et autonome.

3.3 Externe — un fichier .css séparé

La méthode professionnelle : les règles vivent dans un fichier à part (par exemple styles/atelier.css), que chaque page appelle avec une balise <link> dans son <head> :

<!-- Dans chaque page HTML du site -->
<link rel="stylesheet" href="styles/atelier.css">
/* Fichier styles/atelier.css — aucune balise HTML ici, que du CSS */
body {
    font-family: system-ui, sans-serif;
    color: #111827;
}

h1 {
    color: #c2410c;
}
Bon à savoir : l'attribut href suit les mêmes règles de chemins relatifs que pour les liens et les images (vu au cours HTML). Si ta page est dans pages/ et ta feuille dans styles/, il faudra écrire "../styles/atelier.css". Si la page s'affiche « toute nue », c'est presque toujours un chemin faux : l'onglet Réseau des outils de développement (F12) affichera alors une erreur 404 sur le fichier .css.
Les trois méthodes en un coup d'œil
MéthodePortéeUsage conseillé
En ligne (style="")une balisetests rapides, cas très particuliers
Interne (<style>)une pagepage unique, prototype, ce cours
Externe (<link>)tout le sitela norme pour un vrai site
↑ Retour au sommaire

04. Les sélecteurs

Le sélecteur est la partie « à qui ? » de la règle. Savoir viser précisément le bon élément, c'est la moitié du travail en CSS. Voici la boîte à outils, du plus simple au plus fin.

4.1 Sélecteur d'élément, de classe et d'identifiant

<!-- HTML -->
<p>Remplacement d'écran : <span class="prix">sur devis</span></p>
<p>Nettoyage complet du PC : <span class="prix">39 €</span></p>
<p id="promo-du-mois">Ce mois-ci : diagnostic gratuit à domicile</p>
/* CSS */
p {                  /* tous les paragraphes      */
    margin: 0.3rem 0;
}
.prix {              /* tout ce qui a class="prix" */
    color: #c2410c;
    font-weight: 700;
}
#promo-du-mois {     /* l'élément id="promo-du-mois" */
    background: #ffedd5;
    padding: 0.3rem 0.6rem;
    border-radius: 4px;
}

Remplacement d'écran : sur devis

Nettoyage complet du PC : 39 €

Ce mois-ci : diagnostic gratuit à domicile

Classe ou id ? en CSS, privilégie presque toujours les classes : elles sont réutilisables et un élément peut en cumuler plusieurs (class="carte carte-vedette"). Les id servent surtout aux ancres de navigation (comme le sommaire de cette page) et à JavaScript. Leur forte priorité (voir chapitre 05) les rend aussi difficiles à surcharger.

4.2 Le sélecteur universel et le groupement

L'étoile * vise tous les éléments. La virgule permet d'appliquer un même bloc à plusieurs sélecteurs d'un coup, sans répéter les déclarations :

* {
    box-sizing: border-box;   /* on verra pourquoi au chapitre 09 */
}

h4, h5 {
    font-family: Georgia, serif;
    color: #1f2937;
}

Montage de PC sur mesure

Choix des composants avec toi

4.3 Le sélecteur d'attribut

Les crochets [ ] visent les éléments selon un de leurs attributs HTML — pratique pour cibler, par exemple, les liens qui s'ouvrent dans un nouvel onglet :

a[target="_blank"] {
    color: #2e7d32;
}
a[target="_blank"]::after {
    content: " ↗";   /* petite flèche ajoutée en CSS (voir 4.7) */
}

Lien interne vers ce chapitre

Le site de l'atelier (nouvel onglet)

Quelques variantes utiles :

4.4 Les combinateurs — descendant, enfant, frère

On peut enchaîner des sélecteurs pour décrire un chemin dans l'arbre HTML. Le séparateur choisi change tout :

ÉcritureNomVise…
article pdescendant (espace)tout p situé quelque part dans un article, à n'importe quelle profondeur
.fiche > penfant direct (>)les p placés directement dans .fiche, pas plus bas
h3 + pfrère adjacent (+)le p qui suit immédiatement un h3
h3 ~ pfrères suivants (~)tous les p qui suivent un h3 au même niveau
<!-- HTML -->
<article>
    <div class="fiche">
        <p>SSD NVMe 1 To</p>
        <div>
            <p>Lecture jusqu'à 7 000 Mo/s</p>
        </div>
    </div>
</article>
<p>Paragraphe hors de l'article</p>
article p {         /* les DEUX paragraphes de l'article */
    color: #c2410c;
}
.fiche > p {        /* seulement le premier (enfant direct) */
    font-weight: 700;
}

SSD NVMe 1 To

Lecture jusqu'à 7 000 Mo/s

Paragraphe hors de l'article

4.5 Les pseudo-classes d'état

Une pseudo-classe s'écrit avec un deux-points et vise un élément dans un état particulier : survolé, cliqué, sélectionné au clavier…

.bouton {
    background: #c2410c;
    color: #ffffff;
    padding: 0.5rem 1rem;
    border-radius: 4px;
}
.bouton:hover {           /* souris au-dessus          */
    background: #9a3412;
}
.bouton:focus-visible {   /* atteint avec la touche Tab */
    outline: 3px solid #fdba74;
}
.bouton:active {          /* au moment du clic         */
    transform: translateY(1px);
}
Demander un devis détaillé

👉 Survole le bouton, clique dessus, puis essaie d'y arriver avec la touche Tab.

Les pseudo-classes d'état les plus courantes :

Accessibilité : ne supprime jamais le contour de focus (outline: none) sans le remplacer par autre chose de bien visible. Les personnes qui naviguent au clavier en ont besoin pour savoir où elles se trouvent.

4.6 Les pseudo-classes de position

Une autre famille vise un élément selon sa place parmi ses frères. Idéal pour alterner les couleurs d'une liste sans toucher au HTML :

.tarifs li:nth-child(odd) {   /* 1er, 3e, 5e… (even = pairs) */
    background: #f3f4f6;
}
.tarifs li:first-child {
    font-weight: 700;
}
.tarifs li:last-child {
    font-style: italic;
}
Bon à savoir : :nth-child() accepte aussi une formule : 3n (tous les 3), 3n+1 (le 1er, 4e, 7e…), ou un simple numéro : :nth-child(2). Et :not() inverse une sélection : li:not(:last-child) vise tous les éléments sauf le dernier.

4.7 Les pseudo-éléments

Un pseudo-élément s'écrit avec deux deux-points et vise une partie d'un élément, ou crée un contenu décoratif qui n'existe pas dans le HTML :

.citation::before { content: "« "; color: #c2410c; }
.citation::after  { content: " »"; color: #c2410c; }

.lettrine::first-letter {   /* la toute première lettre */
    float: left;
    font-size: 2.6em;
    color: #c2410c;
}
.lettrine::selection {      /* le texte surligné à la souris */
    background: #fdba74;
}

PC réparé en deux jours, explications claires, je recommande !

Bienvenue à l'atelier. Ici, chaque machine est examinée avec soin : on cherche la vraie cause de la panne avant de proposer quoi que ce soit. Sélectionne ce texte à la souris pour voir la couleur de surlignage personnalisée.

Bon à savoir : ::before et ::after exigent la propriété content, même vide (content: ""), sinon ils n'apparaissent pas. Ils sont parfaits pour la décoration… mais un vrai contenu (un prix, une info importante) doit rester dans le HTML : les lecteurs d'écran et les moteurs de recherche ne lisent pas toujours le texte généré en CSS. L'étiquette « Rendu » des cadres de cette page est d'ailleurs faite avec un ::before 😉
↑ Retour au sommaire

05. Cascade, héritage et spécificité

Quand plusieurs règles se disputent la même propriété d'un même élément, le navigateur tranche avec trois critères, examinés dans cet ordre :

  1. l'importance (!important, à éviter — voir plus bas) ;
  2. la spécificité du sélecteur (le plus précis gagne) ;
  3. l'ordre d'apparition (à égalité, la dernière règle écrite gagne).

5.1 L'ordre d'apparition

p { color: #1f2937; }   /* charbon...                       */
p { color: #c2410c; }   /* ...écrasé par cuivre, écrit après */

Même sélecteur, même poids : c'est la dernière règle qui gagne.

5.2 La spécificité — le « poids » d'un sélecteur

Chaque sélecteur reçoit un score à trois chiffres. On compare d'abord la colonne de gauche ; en cas d'égalité, la suivante, etc.

Calcul de la spécificité (id, classe, élément)
Sélecteuridclasses, attributs, pseudo-classeséléments, pseudo-élémentsScore
p0010-0-1
article p0020-0-2
.alerte0100-1-0
.carte a:hover0210-2-1
#alerte-urgente1001-0-0
attribut style=""bat tous les sélecteurs« 1-0-0-0 »
p               { color: #1f2937; }   /* 0-0-1 */
.alerte         { color: #c2410c; }   /* 0-1-0 */
#alerte-urgente { color: #b71c1c; }   /* 1-0-0 */

Paragraphe simple : charbon.

Avec la classe alerte : la classe l'emporte sur l'élément.

Avec classe ET id : l'id l'emporte sur tout le reste.

Astuce de pro : garde des spécificités basses et homogènes — idéalement une seule classe par sélecteur (.carte-titre plutôt que #services .carte div h3). Une feuille construite ainsi se surcharge facilement et reste prévisible. Les outils de développement (F12) affichent les règles perdantes barrées : c'est le moyen le plus rapide de comprendre qui gagne et pourquoi.
À éviter : color: red !important; force une déclaration à passer devant tout le monde. C'est tentant quand « ça ne marche pas »… mais pour l'écraser plus tard, il faudra un autre !important, puis un autre — une escalade qui rend vite la feuille ingérable. Cherche plutôt la règle qui gagne (avec F12) et ajuste ton sélecteur.

5.3 L'héritage

Certaines propriétés se transmettent automatiquement des parents aux enfants : c'est le cas de presque toutes les propriétés de texte (color, font-family, font-size, line-height…). Les propriétés de boîte (border, padding, margin, background…) ne s'héritent pas.

.encart {
    color: #2e7d32;          /* hérité par les enfants     */
    font-family: Georgia, serif; /* hérité aussi               */
    border: 2px solid #2e7d32; /* NON hérité : un seul cadre */
}

Ce paragraphe est vert et en Georgia sans aucune règle à son nom :

il hérite de son parent. Mais lui n'a pas de cadre propre.

C'est grâce à l'héritage qu'une seule règle sur body suffit à fixer la police de toute une page. Pour forcer ou couper l'héritage, trois mots-clés existent : inherit (prendre la valeur du parent), initial (revenir à la valeur par défaut du CSS) et unset (l'un ou l'autre selon la propriété).

↑ Retour au sommaire

06. Les couleurs et les ombres

La couleur est souvent la première chose qu'on a envie de changer — et c'est aussi ce qui fait l'identité d'un site. L'atelier AI29 a par exemple choisi un duo charbon (#1f2937) et cuivre brûlé (#c2410c) : on va s'en servir tout au long du chapitre.

6.1 Les cinq façons d'écrire une couleur

.nom  { background: darkslategray; }             /* mot-clé (148 noms disponibles)  */
.hex  { background: #c2410c; }                   /* hexadécimal : #RRVVBB           */
.rgb  { background: rgb(31, 41, 55); }             /* rouge, vert, bleu de 0 à 255    */
.rgba { background: rgba(194, 65, 12, 0.55); }     /* + transparence de 0 à 1         */
.hsl  { background: hsl(21, 88%, 40%); }          /* teinte, saturation, luminosité  */
darkslategray
#c2410c
rgb(31, 41, 55)
rgba(…, 0.55)
hsl(21, 88%, 40%)
Bon à savoir : l'opacité d'un rgba() ne concerne que la couleur. La propriété opacity: 0.5, elle, rend transparent tout l'élément, texte et enfants compris. Ci-dessous, le même cuivre à 55 % posé sur un damier :
rgba(194, 65, 12, 0.55) — on voit le damier à travers
Où trouver de bonnes couleurs ? les outils de développement (F12) intègrent une pipette : clique sur le petit carré coloré à côté d'une valeur pour ouvrir un nuancier. Pour construire une palette harmonieuse, des générateurs gratuits comme Coolors ou Adobe Color sont très pratiques. Et surtout : vérifie le contraste entre le texte et le fond (outil « Contrast checker » en ligne) — un gris clair sur blanc est illisible pour beaucoup de monde.

6.2 Les propriétés de couleur

.encart-devis {
    color: #1f2937;                 /* couleur du texte          */
    background-color: #fff7ed;      /* couleur de fond           */
    border: 3px solid #c2410c;      /* cadre (épaisseur, style, couleur) */
    outline: 3px dashed #1f2937;    /* contour extérieur         */
    outline-offset: 5px;            /* écart entre cadre et contour */
}
Devis détaillé : temps, pièces, main d'œuvre et garanties chiffrés noir sur blanc. 20 € déductibles de la facture si tu valides l'intervention.

border et outline se ressemblent, avec une différence de taille : la bordure prend de la place dans la mise en page, le contour non (il est dessiné par-dessus, sans rien pousser). C'est pour cela que l'outline est utilisé pour le focus clavier : il apparaît sans faire « sauter » la page.

6.3 Les ombres de boîte — box-shadow

Syntaxe : box-shadow: décalage-x décalage-y flou étalement couleur. Seuls les deux décalages sont obligatoires.

.ombre-douce   { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12); }
.ombre-franche { box-shadow: 6px 6px 0 #1f2937; }        /* flou à 0 : ombre nette */
.ombre-interne { box-shadow: inset 0 0 0 3px #c2410c,     /* plusieurs ombres :   */
                             inset 0 4px 12px rgba(0,0,0,0.15); }  /* séparées par virgule */
Ombre douce
(la plus élégante)
Ombre franche
(style « rétro »)
Ombre interne
(inset)

6.4 Les ombres de texte — text-shadow

Même logique, sans étalement ni inset :

.titre-relief {
    color: #c2410c;
    text-shadow: 2px 2px 0 #1f2937;
}
.titre-neon {
    color: #ffffff;
    text-shadow: 0 0 6px #fb923c, 0 0 16px #c2410c;
}

PC Gamer RTX

Atelier ouvert

Avec modération : une ombre de texte nuit vite à la lisibilité. Réserve-la aux grands titres, jamais aux paragraphes.
↑ Retour au sommaire

07. Les unités de mesure

Tailles de texte, largeurs, marges : presque tout se mesure en CSS. Il existe deux grandes familles d'unités.

7.1 Les unités absolues

Le pixel (px) est l'unité de référence à l'écran : 16px fait toujours 16 pixels, quel que soit le contexte. Les unités du monde réel (cm, mm, pt) existent aussi, mais ne servent vraiment que pour les feuilles de style d'impression.

7.2 Les unités relatives

Les unités relatives indispensables
UnitéRelative à…Usage typique
%la taille du parentlargeurs de colonnes, images fluides
emla taille de police de l'élément (ou de son parent)espacements qui suivent la taille du texte
remla taille de police de la racine <html> (16 px par défaut)tailles de texte, marges globales
vw / vh1 % de la largeur / hauteur de la fenêtrebannières plein écran, sections « hero »
chla largeur du caractère « 0 »limiter la longueur des lignes de texte
.px  { width: 200px; }   /* fixe, quoi qu'il arrive          */
.pct { width: 60%; }     /* 60 % de la largeur du cadre      */
.rem { width: 15rem; }   /* 15 × 16 px = 240 px par défaut   */
.vw  { width: 30vw; }    /* 30 % de la largeur de la fenêtre */
200px
60%
15rem
30vw

👉 Redimensionne ta fenêtre : les barres % et vw changent de taille, les deux autres non.

7.3 em ou rem ? L'effet boule de neige

Le em se calcule à partir du parent… qui peut lui-même être en em. Les tailles se multiplient alors en cascade, ce qui surprend souvent :

.parent       { font-size: 20px; }
.enfant       { font-size: 0.75em; }   /* 0.75 × 20 = 15 px    */
.petit-enfant { font-size: 0.75em; }   /* 0.75 × 15 = 11,25 px */
.avec-rem     { font-size: 0.75rem; }  /* 0.75 × 16 = 12 px, toujours */
Parent : 20 px
Enfant en 0.75em : 15 px
Petit-enfant en 0.75em : 11,25 px — ça rétrécit !
Arrière-petit-enfant en 0.75rem : 12 px, insensible aux parents
Règle pratique : utilise rem pour les tailles de texte et les grands espacements, em pour les petits espacements internes qui doivent grandir avec le texte (le padding d'un bouton, par exemple), % pour les largeurs, et px pour les détails fins (épaisseur de bordure, ombre). Bonus accessibilité : si une personne agrandit la police par défaut de son navigateur, tout ce qui est en rem suit automatiquement.

7.4 Calculer avec calc()

La fonction calc() permet de mélanger les unités :

.colonne-principale {
    width: calc(100% - 250px);   /* tout l'espace, moins une barre latérale */
}
Piège : dans calc(), les espaces autour de + et - sont obligatoires. calc(100%-250px) est invalide et donc ignoré.
↑ Retour au sommaire

08. La typographie

Sur un site, on lit avant tout du texte. Une typographie soignée (bonne police, bonne taille, bon interlignage) fait plus pour l'image d'un site pro que n'importe quel effet visuel.

8.1 La police — font-family

On donne une liste de polices par ordre de préférence, séparées par des virgules. Le navigateur prend la première disponible sur l'appareil, et on termine toujours par une famille générique de secours :

.serif   { font-family: Georgia, "Times New Roman", serif; }
.sans    { font-family: "Helvetica Neue", Arial, sans-serif; }
.mono    { font-family: ui-monospace, "Courier New", monospace; }
.cursive { font-family: "Comic Sans MS", "Segoe Script", cursive; }

serif — avec empattements, ambiance classique

sans-serif — sans empattements, net et moderne

monospace — chaque lettre a la même largeur

cursive — manuscrite (à éviter pour un site pro)

Bon à savoir : les noms de police contenant des espaces se mettent entre guillemets ("Times New Roman"), pas les familles génériques (serif, sans-serif, monospace). Le rendu ci-dessus peut varier selon ton système : sous Linux, Georgia ou Comic Sans ne sont pas forcément installées, et c'est justement la police de secours qui prend le relais. La « pile système » system-ui, sans-serif utilisée par cette page affiche la police native de chaque appareil : rapide et toujours lisible.

8.2 Les polices web

Pour utiliser une police précise, même si elle n'est pas installée chez le visiteur, on la fournit avec le site grâce à la règle @font-face. Exemple avec la police Inter, celle de la vitrine ai29.tech :

/* 1. On déclare la police et l'emplacement de son fichier */
@font-face {
    font-family: "Inter";
    src: url("../polices/inter-variable.woff2") format("woff2");
    font-weight: 100 900;     /* police « variable » : toutes les graisses */
    font-display: swap;     /* texte visible pendant le chargement     */
}

/* 2. On l'utilise comme n'importe quelle police */
body {
    font-family: "Inter", system-ui, sans-serif;
}

Des catalogues comme Google Fonts proposent des centaines de polices libres. Ils fournissent soit un lien à coller dans le <head>, soit les fichiers à télécharger.

RGPD et performance : charger une police directement depuis les serveurs de Google transmet l'adresse IP du visiteur à un tiers — un tribunal allemand a déjà sanctionné un site pour cela. Pour un site professionnel, préfère télécharger les fichiers .woff2 et les héberger toi-même avec @font-face. Limite-toi aussi à deux polices maximum : chaque fichier ralentit l'affichage.

8.3 Taille, graisse et style

.leger   { font-weight: 300; }
.normal  { font-weight: 400; }   /* = normal */
.gras    { font-weight: 700; }   /* = bold   */
.noir    { font-weight: 900; }
.italique { font-style: italic; }
.intro   { font-size: 1.25rem; }

300 — Réparation de portable

400 — Réparation de portable

700 — Réparation de portable

900 — Réparation de portable

italic — Réparation de portable

1.25rem — Réparation de portable

Les graisses vont de 100 (très fin) à 900 (très épais), par centaines. Elles ne s'affichent toutes que si la police les propose : avec une police qui n'a que « normal » et « gras », le navigateur arrondit à la plus proche.

8.4 L'interlignage — line-height

.serre { line-height: 1.1; }
.aere  { line-height: 1.8; }

1.1 — Les lignes se touchent presque : l'œil a du mal à retrouver le début de la ligne suivante.

1.8 — Le texte respire : idéal pour de longs paragraphes d'explications.

Astuce de pro : écris line-height sans unité (1.6 plutôt que 1.6em ou 26px) : la valeur reste alors proportionnelle à la taille du texte de chaque enfant. Entre 1.5 et 1.7 pour du texte courant, autour de 1.2 pour les titres. Et pour le confort de lecture, limite la largeur des paragraphes à environ max-width: 70ch.

8.5 Alignement, décoration, casse et espacement

.gauche  { text-align: left; }      /* par défaut en français */
.centre  { text-align: center; }
.droite  { text-align: right; }
.justifie { text-align: justify; }

left — Atelier à Morlaix

center — Atelier à Morlaix

right — Atelier à Morlaix

justify — Les lignes sont étirées pour toucher les deux bords, ce qui crée parfois de grands trous entre les mots sur un écran étroit : à manier avec précaution.

.barre    { text-decoration: line-through; }
.dessus   { text-decoration: overline; }
.sans-soulignement { text-decoration: none; }   /* utile pour les liens-boutons */
.vague {
    text-decoration: underline wavy #c2410c;    /* type, style et couleur */
    text-underline-offset: 4px;
}

Ancien prix : 89 € → 69 €

overline — trait au-dessus

Un lien sans soulignement

Soulignement ondulé couleur cuivre

.majuscules { text-transform: uppercase; }
.minuscules { text-transform: lowercase; }
.capitales  { text-transform: capitalize; }   /* Chaque Mot Avec Majuscule */
.surtitre {
    text-transform: uppercase;
    letter-spacing: 0.15em;   /* espace entre les lettres */
}

montage de pc sur mesure

MONTAGE DE PC SUR MESURE

montage de pc sur mesure

Nos services

Bon à savoir : text-transform ne change que l'affichage. Dans le HTML, écris le texte normalement (« Nos services ») et laisse le CSS le passer en capitales : les lecteurs d'écran ne liront pas le mot lettre par lettre, et changer de style restera l'affaire d'une ligne.

8.6 Le raccourci font

Comme beaucoup de propriétés, les réglages de police peuvent se regrouper en une seule déclaration — dans l'ordre style, graisse, taille/interligne, famille :

.accroche {
    font: italic 600 1.1rem/1.5 Georgia, serif;
}
↑ Retour au sommaire

09. Le modèle de boîte

Voici LA notion fondatrice de la mise en page : pour le navigateur, chaque élément est un rectangle. Un titre, un paragraphe, une image, un lien : tout est boîte. Et chaque boîte est composée de quatre couches, comme un oignon :

margin (marge extérieure)
border (bordure)
padding (marge intérieure)
contenu (width × height)
  1. content — le contenu lui-même (texte, image), dimensionné par width et height ;
  2. padding — l'espace intérieur entre le contenu et la bordure (il prend la couleur de fond) ;
  3. border — le cadre ;
  4. margin — l'espace extérieur qui repousse les boîtes voisines (toujours transparent).

9.1 Les marges et le padding

margin et padding s'écrivent de la même façon. On peut viser un côté précis, ou utiliser le raccourci qui tourne dans le sens des aiguilles d'une montre en partant du haut :

.a { padding: 20px; }                 /* les 4 côtés                    */
.b { padding: 10px 20px; }            /* haut+bas | gauche+droite       */
.c { padding: 10px 20px 30px; }       /* haut | gauche+droite | bas     */
.d { padding: 10px 20px 30px 40px; }  /* haut | droite | bas | gauche   */
.e { margin-top: 2rem; }              /* un seul côté (top, right, bottom, left) */
Moyen mnémotechnique : pour les 4 valeurs, pense à « TRouBLe » : Top, Right, Bottom, Left.

Une marge à auto à gauche et à droite centre horizontalement une boîte qui a une largeur définie :

.bloc-centre {
    width: 60%;
    margin: 0 auto;   /* 0 en haut/bas, auto à gauche/droite */
}
Je suis centré grâce à margin: 0 auto
Piège : la fusion des marges. quand deux blocs se suivent verticalement, leurs marges haut et bas ne s'additionnent pas : seule la plus grande est conservée. Un margin-bottom: 20px suivi d'un margin-top: 30px donne un écart de 30 px, pas 50. C'est normal, ce n'est pas un bug !

9.2 Les bordures

.cadre { border: 3px solid #1f2937; }   /* épaisseur | style | couleur */
/* Styles possibles : solid, dashed, dotted, double, groove, ridge, none… */
.liseret { border-left: 6px solid #c2410c; }   /* un seul côté */
solid
dashed
dotted
double
border-left

Les encarts « Bon à savoir » de ce cours utilisent justement un border-left coloré : simple et efficace.

9.3 Les coins arrondis — border-radius

.leger  { border-radius: 6px; }
.pilule { border-radius: 999px; }          /* bouts entièrement ronds          */
.rond   { border-radius: 50%; }            /* cercle si la boîte est carrée    */
.goutte { border-radius: 0 50% 50% 50%; }  /* un coin par valeur, sens horaire */
6px
999px
50%
goutte

9.4 box-sizing — la règle qui change la vie

Par défaut, width ne concerne que le contenu : padding et bordure s'ajoutent par-dessus. Une boîte de width: 260px avec 20 px de padding et 4 px de bordure mesure donc en réalité 260 + 2×20 + 2×4 = 308 px. Pas pratique du tout pour aligner des colonnes !

.carte {
    width: 260px;
    padding: 20px;
    border: 4px solid #c2410c;
}
.carte.border-box {
    box-sizing: border-box;   /* width inclut désormais padding et bordure */
}
content-box (défaut) : je mesure 308 px
border-box : je mesure bien 260 px
Astuce de pro : quasiment tous les sites modernes commencent leur feuille de style par cette règle, qui applique border-box partout :
*, *::before, *::after {
    box-sizing: border-box;
}
Prends l'habitude de la mettre en tête de chacun de tes projets.

9.5 Le contenu : dimensions et débordement

En plus de width et height, on dispose de bornes : min-width, max-width, min-height, max-height. La plus utile est sans doute max-width, qui laisse un élément rétrécir sur petit écran sans jamais dépasser une taille confortable sur grand écran (cette page utilise max-width: 820px).

Quand le contenu est plus grand que sa boîte, la propriété overflow décide quoi faire :

.boite { width: 220px; height: 70px; }
/* overflow: visible (défaut) → le texte déborde de la boîte */
.boite-defilante { overflow: auto; }   /* barre de défilement si besoin */
/* overflow: hidden → le surplus est coupé, invisible */
visible : la description de ce PC est trop longue pour la boîte et le texte en sort par le bas, par-dessus la suite.
auto : la description de ce PC est trop longue pour la boîte, une barre de défilement apparaît pour lire la suite.
↑ Retour au sommaire

10. Images et arrière-plans

10.1 Recadrer une image — object-fit

Quand on impose une largeur et une hauteur à une image dont les proportions sont différentes, elle est déformée. La propriété object-fit règle le problème. Ici, une image carrée placée dans des cadres rectangulaires :

img {
    width: 100%;
    height: 90px;
}
.fill    { object-fit: fill; }      /* défaut : étirée, déformée          */
.contain { object-fit: contain; }   /* entière, avec des bandes vides     */
.cover   { object-fit: cover; }     /* remplit tout, quitte à rogner      */
.none    { object-fit: none; }      /* taille d'origine, centrée, rognée  */
Logo CSS déformé
fill
Logo CSS entier
contain
Logo CSS recadré
cover
Logo CSS taille réelle
none
Bon à savoir : cover est la valeur star pour les vignettes de produits (toutes de la même taille, peu importe la photo d'origine). Combine-la avec object-position: top pour choisir quelle partie de l'image garder. Et la règle de base des images fluides : img { max-width: 100%; height: auto; } — l'image ne dépasse jamais de son conteneur.

10.2 L'image de fond — background-image

Une image décorative n'a pas sa place dans le HTML : on la met en fond avec le CSS. Plusieurs propriétés permettent de la régler :

.banniere {
    background-image: url("../images/icon_css.png");
    background-size: 90px;                   /* ou cover / contain       */
    background-repeat: no-repeat;            /* par défaut : repeat      */
    background-position: right 1rem center;  /* à droite, centrée en hauteur */
    background-color: #fff7ed;              /* couleur sous l'image     */
}

Formation CSS à l'atelier

L'icône à droite est une image de fond : elle n'existe pas dans le HTML.

Sans no-repeat, l'image est répétée comme un carrelage :

.motif {
    background-image: url("../images/icon_css.png");
    background-size: 36px;
    height: 90px;
}
Attention aux chemins : dans une feuille externe, le chemin de url() est relatif au fichier .css, pas à la page HTML. Une source d'erreur classique quand on passe du CSS interne au CSS externe.

10.3 Les dégradés

Un dégradé est une image générée par le navigateur : il s'utilise donc avec background ou background-image, sans aucun fichier à télécharger.

.lineaire { background: linear-gradient(135deg, #1f2937, #c2410c); }
.radial   { background: radial-gradient(circle at 30% 30%, #fb923c, #9a3412); }
.conique  { background: conic-gradient(#c2410c 0 70%, #1f2937 0); }  /* camembert à 70 % */
linear-gradient
radial-gradient
70 %

10.4 Superposer plusieurs fonds

background accepte plusieurs couches séparées par des virgules — la première est au-dessus. Une technique très utilisée : poser un dégradé semi-transparent sur une photo pour que le texte blanc reste lisible.

.hero {
    background:
        linear-gradient(rgba(15, 23, 42, 0.75), rgba(15, 23, 42, 0.75)),
        url("../images/icon_css.png") center / 160px repeat;
    color: #ffffff;
}

Ton PC rame ? On regarde ça ensemble.

Diagnostic gratuit · Devis détaillé · Morlaix et alentours

↑ Retour au sommaire

11. La propriété display

Toutes les boîtes ne se comportent pas pareil. La propriété display fixe le type de boîte, et donc la façon dont elle se range par rapport à ses voisines.

11.1 block et inline

Ce sont les deux comportements par défaut des balises HTML :

<div>Bloc 1</div>
<div>Bloc 2</div>
<p>Du texte avec <span>un span</span> et <span>un autre</span> au fil de la ligne.</p>
Bloc 1 — je prends toute la largeur
Bloc 2 — et je passe à la ligne

Du texte avec un span et un autre au fil de la ligne.

Le CSS peut inverser ces comportements : un lien display: block devient cliquable sur toute sa largeur (pratique pour un menu), un li en inline se range sur la ligne.

11.2 inline-block — le meilleur des deux

L'élément reste dans le flux du texte (comme inline) mais accepte largeur, hauteur et marges (comme block). C'est le type des boutons, par exemple.

span {
    display: inline-block;
    width: 110px;          /* enfin pris en compte ! */
    text-align: center;
}

Étiquettes : SSD RAM Carte mère Alimentation

11.3 Faire disparaître un élément

.cache     { display: none; }         /* retiré : ne prend plus aucune place   */
.invisible { visibility: hidden; }    /* invisible, mais garde sa place (trou) */

display: none → A B C

visibility: hidden → A B C

Bon à savoir : display a deux autres valeurs majeures, flex et grid, qui transforment une boîte en conteneur de mise en page. Elles ont chacune leur chapitre (13 et 14) tant elles sont importantes.
↑ Retour au sommaire

12. Positionnement et float

Par défaut, les boîtes s'empilent dans l'ordre du HTML : c'est le flux normal. La propriété position permet d'en sortir pour placer un élément précisément, avec les propriétés top, right, bottom et left.

12.1 static, relative, absolute

.zone     { position: relative; height: 170px; }   /* référence de l'absolute */
.relative { position: relative; top: 10px; left: 40px; }
.absolute { position: absolute; bottom: 10px; right: 10px; }
static
relative
absolute

Le duo parent relative + enfant absolute est un grand classique, par exemple pour poser une pastille sur le coin d'une carte produit :

.carte-produit {
    position: relative;     /* devient la référence */
}
.ruban {
    position: absolute;
    top: -10px;              /* valeurs négatives : déborde du coin */
    right: -10px;
}
Reconditionné

Portable 15" — Core i5, 16 Go

Batterie neuve, SSD 512 Go, Linux Mint préinstallé.

12.2 fixed et sticky

h5 {
    position: sticky;
    top: 0;          /* se colle en haut de la zone qui défile */
}
Composants — mémoire

Barrette DDR5 16 Go

Barrette DDR5 32 Go

Kit DDR4 2 × 8 Go

Composants — stockage

SSD SATA 500 Go

SSD NVMe 1 To

SSD NVMe 2 To

Disque dur 4 To

Composants — refroidissement

Ventirad tour

Watercooling 240 mm

Pâte thermique

👉 Fais défiler la liste : chaque titre reste collé en haut jusqu'à ce que le suivant le pousse.

12.3 L'empilement — z-index

Quand des éléments positionnés se chevauchent, z-index décide qui passe devant : le plus grand nombre gagne. Il ne fonctionne que sur les éléments positionnés (autres que static) et les enfants de flex/grid.

.gris    { z-index: 1; }
.cuivre  { z-index: 3; }   /* au-dessus de tout le monde */
.charbon { z-index: 2; }
z-index: 1
z-index: 3
z-index: 2
Astuce de pro : évite la course aux z-index: 99999. Fixe-toi une petite échelle (1 contenu, 10 menu, 100 fenêtre modale…) et tiens-t'y.

12.4 float — l'ancêtre de la mise en page

float pousse un élément à gauche ou à droite et laisse le texte s'enrouler autour, comme dans un magazine. Avant Flexbox et Grid, on l'utilisait (en le détournant) pour construire des colonnes entières. Aujourd'hui, il ne sert plus qu'à son usage d'origine : habiller une image avec du texte.

.article img {
    float: left;
    width: 70px;
    margin: 0 0.9rem 0.4rem 0;   /* un peu d'air côté texte */
}
.article::after {   /* « clearfix » : le parent   */
    content: "";        /* englobe bien l'image       */
    display: block;
    clear: both;
}
Logo CSS

Le texte s'enroule autour de l'image flottante. Au fil des lignes, il occupe l'espace libre à droite puis, une fois l'image dépassée, reprend toute la largeur du cadre. Ce comportement est idéal pour un article de blog ou une fiche conseil : « Comment choisir son SSD », « Pourquoi passer sous Linux », etc.

À éviter : construire une mise en page en colonnes avec float. Tu tomberas sur de vieux tutoriels qui le font : c'est fragile et dépassé. Pour placer des blocs côte à côte, la réponse moderne s'appelle Flexbox ou Grid — justement les deux chapitres suivants.
↑ Retour au sommaire

13. Flexbox — la mise en page sur un axe

Flexbox (« boîte flexible ») sert à aligner et répartir des éléments sur une ligne ou une colonne. Barre de navigation, rangée de boutons, carte avec son pied collé en bas, centrage vertical… c'est l'outil du quotidien du développeur front-end.

Tout repose sur deux rôles :

13.1 Le conteneur et gap

<div class="conteneur">
    <div>Diagnostic</div>
    <div>Devis</div>
    <div>Réparation</div>
</div>
.conteneur {
    display: flex;
    gap: 0.6rem;    /* espace entre les éléments (pas sur les bords) */
}
Diagnostic
Devis
Réparation

↑ sans gap — ↓ avec gap: 0.6rem

Diagnostic
Devis
Réparation

Une seule ligne de CSS, et les trois div (qui sont des blocs, donc normalement empilés) se retrouvent côte à côte. 🎉 La variante inline-flex fait la même chose, mais le conteneur lui-même se comporte comme un élément en ligne au lieu de prendre toute la largeur.

13.2 Les axes et flex-direction

Flexbox raisonne sur deux axes perpendiculaires :

flex-direction choisit l'axe principal : row (défaut, de gauche à droite), row-reverse, column (de haut en bas) ou column-reverse.

.colonne { flex-direction: column; }
.inverse { flex-direction: row-reverse; }
1. Diagnostic
2. Devis
3. Réparation
1. Diagnostic
2. Devis
3. Réparation
Le point clé à retenir : justify-content agit toujours sur l'axe principal, align-items sur l'axe secondaire. Si tu passes en column, les axes pivotent : justify-content devient vertical. C'est LA source de confusion n° 1 avec Flexbox.

13.3 Répartir sur l'axe principal — justify-content

.conteneur { justify-content: flex-start; }   /* défaut */
/* autres valeurs : center | flex-end | space-between | space-around | space-evenly */
start
A
B
center
A
B
end
A
B
between
A
B
around
A
B
evenly
A
B

13.4 Aligner sur l'axe secondaire — align-items

Dans un conteneur plus haut que ses éléments (ici 110 px), le premier élément étant plus grand que les autres :

.conteneur { height: 110px; align-items: stretch; }   /* défaut : étirés */
/* autres valeurs : flex-start | center | flex-end | baseline */
stretch
A
B
flex-start
A
B
center
A
B
flex-end
A
B
baseline
A
B

baseline aligne les éléments sur la ligne de base de leur texte : utile quand les tailles de police diffèrent.

13.5 Le centrage parfait

Longtemps casse-tête légendaire du CSS, centrer un élément horizontalement et verticalement tient désormais en trois lignes :

.centrage {
    display: flex;
    justify-content: center;   /* axe principal  */
    align-items: center;       /* axe secondaire */
}
Pile au centre 🎯

13.6 Un élément à part — align-self et order

align-self se pose sur un élément pour qu'il ignore l'align-items du parent. order change sa position d'affichage sans toucher au HTML (défaut : 0, les plus grands vont à la fin).

.conteneur     { height: 110px; align-items: flex-start; }
.le-troisieme { align-self: flex-end; }
A
B
C (align-self)
D
Accessibilité : order ne change que l'affichage. La touche Tab et les lecteurs d'écran suivent toujours l'ordre du HTML. Si l'ordre a du sens, change-le dans le HTML plutôt qu'en CSS.

13.7 Passer à la ligne — flex-wrap et align-content

Par défaut, Flexbox tasse tous les éléments sur une seule ligne, quitte à les écraser. Avec flex-wrap: wrap, ils passent à la ligne quand la place manque :

.conteneur {
    display: flex;
    flex-wrap: wrap;
}
.conteneur > div { flex: 0 0 140px; }   /* chaque élément fait 140 px (voir 13.8) */
Écran
Clavier
Souris
Webcam
Casque
Enceintes
Tapis

Une fois qu'il y a plusieurs lignes, align-content règle l'espacement des lignes entre elles (mêmes valeurs que justify-content). Comparaison dans un conteneur de 180 px :

.lignes-en-haut  { align-content: flex-start; }
.lignes-reparties { align-content: space-between; }
1
2
3
4
5
1
2
3
4
5

13.8 La flexibilité des tailles — flex-grow, flex-shrink, flex-basis

Trois propriétés se posent sur les éléments pour décider comment ils se partagent la place :

.a { flex-grow: 1; }   /* 1 part de l'espace libre  */
.b { flex-grow: 2; }   /* 2 parts : grandit 2× plus */
.c { flex-grow: 0; }   /* ne grandit pas            */
grow 1
grow 2
grow 0

En pratique, on utilise surtout le raccourci flex: grow shrink basis. Le réglage le plus utile de tous : des cartes qui font au moins 150 px, se partagent l'espace et passent à la ligne d'elles-mêmes — sans aucune media query :

.cartes { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.cartes > div { flex: 1 1 150px; }
Vente
Montage
Réparation
Maintenance

👉 Réduis la largeur de ta fenêtre pour voir les cartes se réorganiser.

13.9 Mini-exercice : le menu de l'atelier

🛠️ À toi de jouer : reproduis cette barre de navigation dans un fichier vierge, uniquement avec ce que tu viens d'apprendre. Contraintes : le logo à gauche, les liens et le bouton poussés à droite, tout centré verticalement, et passage à la ligne propre sur petit écran.
Voir une solution
<nav class="menu">
    <span class="logo">AI<span>29</span></span>
    <a href="#services">Services</a>
    <a href="#tarifs">Tarifs</a>
    <a href="#contact">Contact</a>
    <a class="bouton" href="#rdv">Prendre rendez-vous</a>
</nav>
.menu {
    display: flex;
    align-items: center;      /* centrage vertical            */
    flex-wrap: wrap;          /* passage à la ligne si besoin */
    gap: 1.2rem;
    background: #1f2937;
    padding: 0.7rem 1rem;
}
.menu .logo {
    margin-right: auto;      /* l'astuce : la marge auto avale tout l'espace libre */
    color: #ffffff;
    font-weight: 800;
}
.menu .logo span { color: #fb923c; }
.menu a          { color: #e5e7eb; text-decoration: none; }
.menu a:hover    { color: #fb923c; }

L'astuce à retenir : dans un conteneur flex, une marge auto absorbe tout l'espace disponible de son côté. margin-right: auto sur le logo repousse donc tout le reste vers la droite.

↑ Retour au sommaire

14. Grid — la mise en page en grille

Si Flexbox range des éléments sur un axe, CSS Grid travaille sur deux axes à la fois : des lignes et des colonnes. C'est l'outil idéal pour la structure globale d'une page (en-tête, menu latéral, contenu, pied) ou pour une galerie de cartes parfaitement alignées.

Flexbox ou Grid ?
FlexboxGrid
Dimensionsune (ligne ou colonne)deux (lignes et colonnes)
Logiquele contenu dicte la taillela grille dicte la place
Exemples typiquesmenu, barre d'outils, boutons, contenu d'une cartesquelette de page, galerie, tableau de bord, planning

Ce n'est pas l'un ou l'autre : un site moderne utilise généralement Grid pour la structure générale et Flexbox à l'intérieur des composants.

14.1 Première grille — grid-template-columns

.grille {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;   /* 3 colonnes égales */
    gap: 0.5rem;
}
1
2
3
4
5
6
7

L'unité fr (fraction) est propre à Grid : elle partage l'espace restant. Les éléments se placent ensuite tout seuls, case par case, de gauche à droite puis ligne par ligne. Le 7e élément démarre une nouvelle ligne automatiquement.

14.2 Mélanger les tailles

.grille {
    grid-template-columns: 120px 1fr 2fr;   /* fixe | 1 part | 2 parts */
}
120px
1fr
2fr

grid-template-rows fonctionne de la même façon pour les lignes :

.grille {
    grid-template-columns: repeat(2, 1fr);   /* = 1fr 1fr */
    grid-template-rows: 50px 90px;
}
ligne 1 : 50px
ligne 1
ligne 2 : 90px
ligne 2

14.3 repeat(), minmax() et la grille automatique

repeat(4, 1fr) évite d'écrire quatre fois la même valeur. minmax(130px, 1fr) définit une taille minimale et maximale. Combinés au mot-clé auto-fill, ils donnent la formule magique de la galerie responsive sans media query :

.galerie {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 0.5rem;
}
Processeur
Carte mère
RAM
SSD
Carte graphique
Alimentation
Boîtier
Ventirad

👉 Redimensionne ta fenêtre : le nombre de colonnes s'adapte tout seul.

Traduction en français : « crée autant de colonnes que possible, chacune faisant au minimum 130 px, et partagez-vous équitablement ce qui reste ». Une seule ligne de CSS qui remplace des dizaines de lignes de media queries. 💪 (Variante : auto-fit, qui étire les éléments quand il y en a trop peu pour remplir la ligne.)

14.4 Placer un élément précisément

Une grille est découpée par des lignes numérotées : une grille de 4 colonnes possède 5 lignes verticales (de 1 à 5, ou -1 pour « la dernière »). On place un élément en indiquant entre quelles lignes il s'étend :

.grille { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 55px; }

.a { grid-column: 1 / 3; grid-row: 1 / 3; }   /* 2 colonnes × 2 lignes   */
.b { grid-column: 3 / -1; }                  /* de la ligne 3 jusqu'au bout */
.c { grid-column: span 2; }                /* « occupe 2 colonnes »   */
A (2×2)
B (3 / -1)
C (span 2)
4
5
6
7

14.5 Les zones nommées — grid-template-areas

La fonctionnalité la plus lisible de Grid : on dessine la mise en page avec des mots, puis on affecte chaque élément à sa zone.

.page {
    display: grid;
    grid-template-columns: 160px 1fr;
    grid-template-rows: auto 1fr auto;
    grid-template-areas:
        "entete  entete"
        "lateral contenu"
        "pied    pied";
}
header { grid-area: entete; }
aside  { grid-area: lateral; }
main   { grid-area: contenu; }
footer { grid-area: pied; }
header — L'Atelier Informatique du Finistère
aside — menu
main — contenu de la page
footer — mentions légales

Tu reconnais les balises sémantiques du cours HTML ? Grid et HTML 5 vont très bien ensemble. Et pour réorganiser la page sur mobile, il suffira de redessiner les zones dans une media query (chapitre suivant).

14.6 Aligner dans la grille

On retrouve la logique de Flexbox, avec deux familles de propriétés :

.grille {
    grid-template-columns: repeat(3, 90px);   /* grille plus étroite que son conteneur */
    grid-auto-rows: 60px;
    justify-content: center;   /* la grille au centre du conteneur */
    justify-items: center;     /* chaque élément au centre de sa case */
    align-items: center;
}
A
B
C
D
E
F
Le raccourci à connaître : place-items: center regroupe align-items et justify-items. Ainsi, display: grid; place-items: center; est la façon la plus courte de centrer un élément dans une boîte — encore plus court qu'avec Flexbox !

14.7 Mini-exercice : le planning de l'atelier

🛠️ À toi de jouer : construis le planning hebdomadaire ci-dessous. Une colonne étroite pour les heures, cinq colonnes égales pour les jours, et des rendez-vous qui s'étalent sur plusieurs créneaux. Indice : regarde bien la section 14.4.
Lun
Mar
Mer
Jeu
Ven
9 h
10 h
11 h
14 h
Diagnostic portable
Montage PC gamer
Intervention à domicile — Saint-Pol-de-Léon
Diagnostic + devis
Voir une solution
.planning {
    display: grid;
    grid-template-columns: 70px repeat(5, 1fr);   /* heures + 5 jours */
    grid-auto-rows: minmax(38px, auto);           /* lignes créées à la volée */
    gap: 3px;
}
/* Ligne 1 = en-têtes des jours ; colonne 1 = heures */
.lundi-9h-11h    { grid-column: 2;     grid-row: 2 / 4; }
.mercredi-matin  { grid-column: 4;     grid-row: 2 / 5; }
.mar-mer-14h     { grid-column: 3 / 5; grid-row: 5; }
.vendredi-10h    { grid-column: 6;     grid-row: 3 / 5; }

Les cases vides n'ont pas besoin d'exister dans le HTML : Grid réserve la place tout seul. Les heures, elles, sont calées dans la colonne 1 (grid-column: 1) avec chacune sa grid-row.

↑ Retour au sommaire

15. Responsive et media queries

Aujourd'hui, plus de la moitié des visites d'un site se font sur téléphone. Un site responsive (« adaptatif ») s'ajuste à toutes les tailles d'écran : une colonne sur mobile, deux sur tablette, trois sur grand écran… sans dupliquer le contenu.

15.1 Le prérequis : la balise viewport

Sans elle, les téléphones affichent la page comme sur un écran d'ordinateur de 980 px de large, puis la rétrécissent : tout devient minuscule. Elle doit figurer dans le <head> de chaque page (tu l'as déjà croisée dans le squelette HTML) :

<meta name="viewport" content="width=device-width, initial-scale=1.0">

15.2 La règle @media

Une media query est un bloc de règles qui ne s'applique que si une condition est remplie — le plus souvent, une largeur d'écran :

/* Toujours appliqué */
.services {
    display: grid;
    grid-template-columns: 1fr;            /* 1 colonne */
}

/* Seulement si la fenêtre fait au moins 600 px de large */
@media (min-width: 600px) {
    .services {
        grid-template-columns: repeat(2, 1fr);  /* 2 colonnes */
    }
}

/* Et au moins 900 px */
@media (min-width: 900px) {
    .services {
        grid-template-columns: repeat(3, 1fr);  /* 3 colonnes */
    }
}
🛒 Vente de matériel
🔧 Montage sur mesure
🩺 Réparation
🧹 Maintenance
🐧 Passage à Linux
🏠 Intervention à domicile

👉 Élargis puis rétrécis ta fenêtre (ou ouvre cette page sur ton téléphone) : la pastille et le nombre de colonnes changent en direct. Dans les outils de développement, le bouton Vue adaptative (Ctrl+Maj+M dans Firefox) simule n'importe quel écran.

Une media query ne crée pas de nouvelles règles « à côté » : elle vient surcharger les règles précédentes, selon la cascade du chapitre 05. C'est pour cela que l'ordre compte : les media queries se placent après les règles de base.

15.3 Mobile first

Deux stratégies existent :

Pourquoi mobile first ? la version mobile est la plus simple (souvent une colonne, tout empilé) : partir de là donne un code plus court. Et ça force à se concentrer sur l'essentiel — sur un petit écran, il n'y a pas la place pour le superflu. C'est la stratégie de la vitrine ai29.tech.

15.4 Les points de rupture

Les largeurs choisies (600 px, 900 px…) s'appellent des points de rupture (breakpoints). Il n'existe pas de valeurs officielles ; ces repères sont courants :

Points de rupture usuels (indicatifs)
ConditionAppareils visés
(aucune — style de base)téléphones (≈ 360 à 430 px)
(min-width: 640px)grands téléphones à l'horizontale, petites tablettes
(min-width: 768px)tablettes
(min-width: 1024px)tablettes à l'horizontale, petits portables
(min-width: 1280px)ordinateurs de bureau
Astuce de pro : ne cherche pas à viser des modèles d'appareils précis. Élargis doucement ta fenêtre et ajoute un point de rupture là où ta mise en page commence à « casser ». C'est le contenu qui décide, pas l'iPhone du moment. Et souvent, les grilles auto-fill/minmax() et les flex-wrap vus plus haut évitent carrément d'en écrire.

15.5 D'autres conditions utiles

/* Feuille spéciale impression : on masque le menu, texte en noir */
@media print {
    nav, .bouton { display: none; }
    body { color: #000000; }
}

/* Le visiteur a réglé son système en mode sombre */
@media (prefers-color-scheme: dark) { /* … */ }

/* Le visiteur a demandé moins d'animations (voir chapitre 17) */
@media (prefers-reduced-motion: reduce) { /* … */ }

/* Plusieurs conditions combinées */
@media (min-width: 600px) and (orientation: landscape) { /* … */ }

Essaie l'aperçu avant impression de cette page (Ctrl+P) : sans feuille print dédiée, le navigateur fait ce qu'il peut. Avec, on obtient un document propre — pratique pour une fiche tarif ou un devis consultable en ligne.

15.6 Pour aller plus loin : les container queries

Une media query regarde la fenêtre. Mais un même composant (une carte, par exemple) peut se retrouver dans une colonne étroite ou dans une zone large sur la même page. Les container queries, récentes et désormais bien prises en charge, permettent à un composant de s'adapter à la largeur de son conteneur :

.zone {
    container-type: inline-size;   /* « surveille ma largeur » */
}
@container (min-width: 450px) {
    .cartes { grid-template-columns: repeat(3, 1fr); }
}
Diagnostic gratuit
Devis détaillé
Intervention

👉 Attrape le coin inférieur droit du cadre cuivre et rétrécis-le : les cartes passent en colonne sans que la fenêtre change de taille.

↑ Retour au sommaire

16. Les variables CSS bonus

Dans ce cours, le cuivre #c2410c apparaît des dizaines de fois. Le jour où on veut l'ajuster, il faut tout retrouver… sauf si on utilise des variables (de leur vrai nom : propriétés personnalisées).

16.1 Déclarer et utiliser une variable

/* :root = l'élément racine <html> : variables disponibles partout */
:root {
    --couleur-charbon: #1f2937;
    --couleur-cuivre: #c2410c;
    --arrondi: 8px;
}

h1 {
    color: var(--couleur-cuivre);
}
.bouton {
    background: var(--couleur-cuivre);
    border-radius: var(--arrondi);
}
.encart {
    border: 2px solid var(--couleur-cuivre, orange);  /* 2e valeur = secours */
}

Changer --couleur-cuivre à un seul endroit met à jour instantanément tout le site. C'est exactement ainsi qu'on gère une charte graphique : la palette Charbon/Cuivre d'AI29 tient en quelques lignes en tête de feuille.

16.2 Des variables qui suivent la cascade

Contrairement aux variables d'autres outils, les variables CSS héritent et peuvent être redéfinies localement. Il suffit donc de changer les valeurs sur un parent pour transformer tout un composant — par exemple, un thème sombre :

.carte {
    --couleur-fond: #ffffff;
    --couleur-texte: #1f2937;
    --couleur-accent: #c2410c;
    --arrondi: 8px;

    background: var(--couleur-fond);
    color: var(--couleur-texte);
    border: 2px solid var(--couleur-accent);
    border-radius: var(--arrondi);
}

/* Le thème sombre ne redéfinit QUE les variables : tout le reste suit */
.carte.theme-sombre {
    --couleur-fond: #0f172a;
    --couleur-texte: #e5e7eb;
    --couleur-accent: #fb923c;
    --arrondi: 0;
}

Forfait maintenance annuelle

Nettoyage, mises à jour, vérification des sauvegardes.

En savoir plus

Forfait maintenance annuelle

Même HTML, mêmes règles : seules 4 variables ont changé.

En savoir plus
Bon à savoir : combinées à @media (prefers-color-scheme: dark) du chapitre précédent, les variables permettent de proposer un mode sombre automatique en redéfinissant simplement la palette dans la media query. Et comme elles sont lisibles et modifiables par JavaScript, elles serviront de pont entre les deux langages dans le prochain cours.
↑ Retour au sommaire

17. Transitions et animations bonus

Un peu de mouvement rend une interface plus agréable et plus compréhensible : un bouton qui réagit, une carte qui se soulève au survol, un voyant qui clignote. Le CSS sait faire tout cela sans une seule ligne de JavaScript.

17.1 Les transitions — adoucir un changement

Sans transition, un changement d'état (au :hover par exemple) est instantané. La propriété transition l'étale dans le temps. Elle se pose sur l'état normal de l'élément :

.carte {
    transition: transform 0.25s ease,
                box-shadow 0.25s ease;   /* quoi | durée | courbe */
}
.carte:hover {
    transform: translateY(-6px);
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
}
Sans transition : saccadé   Avec transition : fluide ✨

👉 Survole les deux cartes pour comparer.

Les courbes de vitesse (timing functions) les plus utilisées :

À éviter : transition: all. C'est pratique, mais le navigateur surveille alors toutes les propriétés, et des changements imprévus se retrouvent animés. Liste explicitement celles qui t'intéressent. Et reste court : entre 0,15 s et 0,3 s pour un survol — au-delà, l'interface paraît molle.

17.2 Les transformations — transform

transform déplace, tourne, agrandit ou déforme un élément sans perturber la mise en page autour de lui. Associée à une transition, c'est la base de la plupart des effets :

.translate:hover { transform: translateX(20px); }  /* déplacer  */
.rotate:hover    { transform: rotate(15deg); }     /* tourner   */
.scale:hover     { transform: scale(1.25); }      /* agrandir  */
.skew:hover      { transform: skewX(-12deg); }    /* incliner  */
translate
rotate
scale
skew

👉 Survole chaque bloc.

Astuce de pro : pour animer, privilégie transform et opacity. Le navigateur les calcule sur la carte graphique, sans recalculer la mise en page : l'animation reste fluide même sur un vieux téléphone. Animer width, top ou margin est beaucoup plus coûteux.

17.3 Les animations — @keyframes

Une transition va d'un état A à un état B, en réaction à un événement. Une animation peut enchaîner plusieurs étapes, se répéter à l'infini et démarrer toute seule. On la décrit en deux temps :

/* 1. On décrit les étapes clés, en pourcentage de la durée */
@keyframes clignote {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.25; }
}
@keyframes tourne {
    to { transform: rotate(360deg); }   /* « from » et « to » = 0% et 100% */
}

/* 2. On l'applique : nom | durée | courbe | répétitions */
.voyant {
    animation: clignote 1.6s ease-in-out infinite;
}
.chargement {
    border: 4px solid #fed7aa;
    border-top-color: #c2410c;   /* un seul côté coloré… */
    border-radius: 50%;          /* …sur un cercle       */
    animation: tourne 0.9s linear infinite;
}
Atelier ouvert — on répond au téléphone

Une animation peut aussi ne jouer qu'une fois, par exemple pour faire apparaître des éléments en cascade avec un léger décalage (animation-delay) :

@keyframes apparition {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
}
.etape              { animation: apparition 0.8s ease-out both; }
.etape:nth-child(2) { animation-delay: 0.2s; }
.etape:nth-child(3) { animation-delay: 0.4s; }
1. Diagnostic gratuit
2. Devis détaillé
3. Intervention

👉 Pour rejouer l'animation : survole le cadre puis ressors-en (le survol la désactive, la sortie la relance).

Accessibilité : certaines personnes (vertiges, migraines, troubles de l'attention) sont gênées par le mouvement à l'écran et l'ont signalé dans les réglages de leur système. Respecte ce choix en coupant les animations non essentielles :
@media (prefers-reduced-motion: reduce) {
    .voyant, .chargement, .etape { animation: none; }
}
C'est ce que fait cette page : si ton système est réglé ainsi, les rendus ci-dessus restent immobiles.
↑ Retour au sommaire

Et maintenant ?

Bravo, tu as parcouru tout le cours ! 🎉 Pour mesurer tes progrès, voici un composant qui mobilise presque tout le cours : variables (ch. 16), grille automatique (ch. 14), Flexbox en colonne (ch. 13), modèle de boîte et arrondis (ch. 09), typographie (ch. 08), couleurs et ombres (ch. 06), pseudo-classe :hover et transition (ch. 04 et 17).

.offres {
    --charbon: #1f2937;
    --cuivre: #c2410c;
    --cuivre-pale: #ffedd5;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
}
.offres article {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.2rem;
    border: 1px solid #e5e7eb;
    border-top: 4px solid var(--cuivre);
    border-radius: 10px;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.offres article:hover {
    transform: translateY(-4px);
    box-shadow: 0 10px 22px rgba(0, 0, 0, 0.12);
}
.offres ul { flex-grow: 1; }   /* pousse les boutons en bas : tous alignés */
.offres .tarif { font-size: 1.6rem; font-weight: 800; color: var(--cuivre); }
Étape 1

Diagnostic

Gratuit

  • On identifie la panne
  • Explications claires
  • Aucun engagement
Prendre rendez-vous
Étape 2

Devis détaillé

20 € déductibles

  • Temps, pièces et main d'œuvre chiffrés
  • Garanties précisées
  • Intégralement déduits de la facture si tu valides
Demander un devis
Étape 3

Intervention

Selon devis

  • À l'atelier ou à domicile
  • Aucune surprise sur la facture
Nous contacter

Tu sais désormais :

🛠️ Le défi final : reprends la page que tu as construite à la fin du cours HTML (une page « à propos », un CV, une fiche produit…) et habille-la avec une feuille de style externe. Objectifs : une palette en variables, un menu en Flexbox, une grille de contenu en Grid, et un affichage impeccable sur ton téléphone. Inspecte ton travail avec F12 à chaque étape.

La suite logique est JavaScript : le langage qui rend les pages interactives. Ouvrir un menu sur mobile, valider un formulaire avant envoi, basculer entre thème clair et thème sombre en modifiant… une variable CSS. Le HTML structure, le CSS habille, le JavaScript donne vie.

Conseil pratique : le CSS s'apprend en tâtonnant. Ouvre les outils de développement sur tes sites préférés, désactive une règle, change une valeur, observe. Chaque « tiens, pourquoi ça fait ça ? » est une leçon. Et garde ce cours sous le coude comme aide-mémoire : il est fait pour ça.

À bientôt pour la suite. 👋

↑ Retour au sommaire