SSD NVMe 1 To
Lecture jusqu'à 7 000 Mo/s
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 :
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 ?! » 😅
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).
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 :
| Élément | Dans l'exemple | Rôle |
|---|---|---|
| Sélecteur | h1 | désigne quels éléments HTML sont visés |
| Bloc de déclarations | { … } | regroupe toutes les instructions entre accolades |
| Déclaration | color: #c2410c; | une instruction = une propriété + une valeur |
| Propriété | color | la caractéristique qu'on modifie |
| Valeur | #c2410c | ce qu'on lui donne |
Les règles de ponctuation sont simples mais strictes :
: séparent propriété et valeur ;; termine chaque déclaration ;{ } ouvrent et ferment le bloc.; 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.
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 ».
*/
// 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.
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 sommaireIl existe trois façons de relier du CSS à une page HTML. Toutes fonctionnent, mais elles ne se valent pas du tout.
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.
<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.
.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;
}
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.
| Méthode | Portée | Usage conseillé |
|---|---|---|
En ligne (style="") | une balise | tests rapides, cas très particuliers |
Interne (<style>) | une page | page unique, prototype, ce cours |
Externe (<link>) | tout le site | la norme pour un vrai site |
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.
class="…" ;id.<!-- 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
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.
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;
}
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) */
}
Quelques variantes utiles :
[required] — l'attribut existe, quelle que soit sa valeur ;a[href^="tel:"] — la valeur commence par « tel: » ;a[href$=".pdf"] — la valeur se termine par « .pdf » ;img[alt*="SSD"] — la valeur contient « SSD ».On peut enchaîner des sélecteurs pour décrire un chemin dans l'arbre HTML. Le séparateur choisi change tout :
| Écriture | Nom | Vise… |
|---|---|---|
article p | descendant (espace) | tout p situé quelque part dans un article, à n'importe quelle profondeur |
.fiche > p | enfant direct (>) | les p placés directement dans .fiche, pas plus bas |
h3 + p | frère adjacent (+) | le p qui suit immédiatement un h3 |
h3 ~ p | frè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
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);
}
👉 Survole le bouton, clique dessus, puis essaie d'y arriver avec la touche Tab.
Les pseudo-classes d'état les plus courantes :
:hover — survol à la souris ;:focus / :focus-visible — élément actif au clavier (champ de formulaire, lien) ;:active — pendant le clic ;:visited — lien déjà visité ;:checked, :disabled, :invalid — états des champs de formulaire.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.
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;
}
: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.
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.
::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 😉
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 :
!important, à éviter — voir plus bas) ;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.
Chaque sélecteur reçoit un score à trois chiffres. On compare d'abord la colonne de gauche ; en cas d'égalité, la suivante, etc.
| Sélecteur | id | classes, attributs, pseudo-classes | éléments, pseudo-éléments | Score |
|---|---|---|---|---|
p | 0 | 0 | 1 | 0-0-1 |
article p | 0 | 0 | 2 | 0-0-2 |
.alerte | 0 | 1 | 0 | 0-1-0 |
.carte a:hover | 0 | 2 | 1 | 0-2-1 |
#alerte-urgente | 1 | 0 | 0 | 1-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.
.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 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.
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é).
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.
.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é */
red, white,
tomato…) : lisibles, parfaits pour tester, mais peu
précis pour une charte graphique.00 à ff) dose le
rouge, le vert puis le bleu. #000000 = noir,
#ffffff = blanc. Forme courte possible :
#fff.0 =
invisible, 1 = opaque).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 :
.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 */
}
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.
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 */
inset)text-shadowMê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
Tailles de texte, largeurs, marges : presque tout se mesure en CSS. Il existe deux grandes familles d'unités.
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.
| Unité | Relative à… | Usage typique |
|---|---|---|
% | la taille du parent | largeurs de colonnes, images fluides |
em | la taille de police de l'élément (ou de son parent) | espacements qui suivent la taille du texte |
rem | la taille de police de la racine <html> (16 px par défaut) | tailles de texte, marges globales |
vw / vh | 1 % de la largeur / hauteur de la fenêtre | bannières plein écran, sections « hero » |
ch | la 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 */
👉 Redimensionne ta fenêtre : les barres % et
vw changent de taille, les deux autres non.
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 */
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.
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 */
}
calc(), les espaces autour de + et
- sont obligatoires.
calc(100%-250px) est invalide et donc ignoré.
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.
font-familyOn 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)
"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.
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.
.woff2 et les
héberger toi-même avec @font-face. Limite-toi aussi à
deux polices maximum : chaque fichier ralentit l'affichage.
.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.
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.
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.
.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
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
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.
fontComme 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
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 :
width et height ;
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) */
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 */
}
margin: 0 automargin-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 !
.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é */
Les encarts « Bon à savoir » de ce cours utilisent justement un
border-left coloré : simple et efficace.
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 */
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 */
}
border-box partout :
*, *::before, *::after {
box-sizing: border-box;
}
Prends l'habitude de la mettre en tête de chacun de tes projets.
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 */
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 */




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.
background-imageUne 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 */
}
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;
}
url() est relatif
au fichier .css, pas à la page HTML. Une source
d'erreur classique quand on passe du CSS interne au CSS externe.
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 % */
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;
}
Diagnostic gratuit · Devis détaillé · Morlaix et alentours
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.
block et inlineCe sont les deux comportements par défaut des balises HTML :
div, p,
h1…h6, section, ul…) :
la boîte commence sur une nouvelle ligne et prend toute la
largeur disponible. width, height et toutes
les marges fonctionnent.span, a,
strong, em…) : la boîte s'insère dans
la ligne de texte et ne prend que la place de son contenu.
width et height sont ignorés,
les marges verticales aussi.<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>
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.
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
.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
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.
static, relative, absolutetop/left n'ont aucun effet ;position autre que static)..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; }
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;
}
Batterie neuve, SSD 512 Go, Linux Mint préinstallé.
fixed et stickyh5 {
position: sticky;
top: 0; /* se colle en haut de la zone qui défile */
}
Barrette DDR5 16 Go
Barrette DDR5 32 Go
Kit DDR4 2 × 8 Go
SSD SATA 500 Go
SSD NVMe 1 To
SSD NVMe 2 To
Disque dur 4 To
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.
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: 99999. Fixe-toi une petite
échelle (1 contenu, 10 menu, 100 fenêtre modale…) et tiens-t'y.
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;
}
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.
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.
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 :
display: flex ;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) */
}
↑ sans gap — ↓ avec gap: 0.6rem
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.
flex-directionFlexbox 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; }
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.
justify-content.conteneur { justify-content: flex-start; } /* défaut */
/* autres valeurs : center | flex-end | space-between | space-around | space-evenly */
space-between — premier et dernier collés aux bords, le reste réparti entre eux ;space-around — chaque élément a le même espace de chaque côté (donc des demi-espaces aux bords) ;space-evenly — tous les espaces strictement égaux, bords compris.align-itemsDans 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 */
baseline aligne les éléments sur la ligne de base de
leur texte : utile quand les tailles de police diffèrent.
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 */
}
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; }
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.
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) */
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; }
flex-grow, flex-shrink, flex-basisTrois propriétés se posent sur les éléments pour décider comment ils se partagent la place :
flex-basis — la taille de départ, avant partage
(auto par défaut : la taille du contenu) ;flex-grow — la part d'espace libre que
l'élément récupère (0 par défaut : il ne grandit pas) ;flex-shrink — sa capacité à rétrécir
quand la place manque (1 par défaut : il peut rétrécir)..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 */
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; }
👉 Réduis la largeur de ta fenêtre pour voir les cartes se réorganiser.
<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.
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 | Grid | |
|---|---|---|
| Dimensions | une (ligne ou colonne) | deux (lignes et colonnes) |
| Logique | le contenu dicte la taille | la grille dicte la place |
| Exemples typiques | menu, barre d'outils, boutons, contenu d'une carte | squelette 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.
grid-template-columns.grille {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 3 colonnes égales */
gap: 0.5rem;
}
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.
.grille {
grid-template-columns: 120px 1fr 2fr; /* fixe | 1 part | 2 parts */
}
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;
}
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;
}
👉 Redimensionne ta fenêtre : le nombre de colonnes s'adapte tout seul.
auto-fit, qui étire les éléments quand il y
en a trop peu pour remplir la ligne.)
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 » */
grid-template-areasLa 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; }
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).
On retrouve la logique de Flexbox, avec deux familles de propriétés :
justify-items / align-items — alignent le
contenu dans chaque cellule (horizontalement / verticalement) ;justify-content / align-content — placent
la grille entière dans son conteneur, quand elle est plus
petite que lui..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;
}
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 !
.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.
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.
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">
@mediaUne 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 */
}
}
👉 É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.
Deux stratégies existent :
min-width — comme dans l'exemple ci-dessus ;max-width.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 :
| Condition | Appareils 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 |
auto-fill/minmax()
et les flex-wrap vus plus haut évitent carrément d'en écrire.
/* 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.
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); }
}
👉 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.
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).
-- ;var()./* :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.
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;
}
Même HTML, mêmes règles : seules 4 variables ont changé.
En savoir plus@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.
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.
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);
}
👉 Survole les deux cartes pour comparer.
Les courbes de vitesse (timing functions) les plus utilisées :
ease — démarre vite, ralentit à la fin (défaut, naturel) ;linear — vitesse constante (rotations, barres de chargement) ;ease-in / ease-out / ease-in-out — accélère, freine, ou les deux.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.
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 */
👉 Survole chaque bloc.
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.
@keyframesUne 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;
}
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; }
👉 Pour rejouer l'animation : survole le cadre puis ressors-en (le survol la désactive, la sortie la relance).
@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.
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); }
Gratuit
20 € déductibles
Selon devis
Tu sais désormais :
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.
À bientôt pour la suite. 👋
↑ Retour au sommaire