Chapitre 3 : Les unités en CSS (em, rem, vh, vw, ...)
Maîtrise des unités relatives et absolues pour un design adaptatif
Dans le développement web moderne, la taille d'un écran peut varier d'une montre connectée à un écran 4K. Si vous fixez toutes vos dimensions en pixels, votre site sera soit minuscule, soit gigantesque, soit totalement cassé sur certains appareils. C'est là qu'interviennent les unités CSS.
Les Unités Absolues
1. Quoi
Les unités absolues sont des mesures qui ont la même taille, quel que soit l'élément ou l'écran sur lequel elles sont affichées. L'unité absolue la plus commune en web est le pixel (px).
Techniquement, un pixel CSS n'est pas forcément un pixel physique de l'écran (à cause des écrans Retina ou Haute Densité), mais il est traité comme une unité de mesure fixe.
2. Pourquoi
Le pixel est utilisé pour des éléments qui ne doivent jamais changer de taille, comme :
- La bordure d'un bouton (
border: 1px solid black). - L'épaisseur d'un séparateur.
- Parfois, des icônes très petites dont la distorsion serait visible.
3. Comment
A. Syntaxe de base
.box {
width: 300px;
height: 200px;
border: 2px solid red;
}
B. Cas concret
Imaginons un composant de "Badge" de notification. On veut qu'il garde une forme circulaire parfaite et une taille constante, peu importe le texte autour.
.notification-badge {
width: 20px;
height: 20px;
background-color: red;
border-radius: 50%;
font-size: 12px;
display: flex;
align-items: center;
justify-content: center;
color: white;
/* On utilise px ici car le badge doit rester un petit point précis */
}
C. Limitations
L'utilisation massive des pixels est l'ennemi de l'accessibilité. Si un utilisateur change la taille de la police par défaut de son navigateur (pour des raisons de vue), les éléments fixés en px ne s'adapteront pas, rendant le site difficile à lire ou provoquant des chevauchements de texte.
4. Zone de Danger
❌ Erreur commune : Définir toute la typographie d'un site en px.
✅ Bonne pratique : Utiliser les pixels pour les bordures et les détails graphiques millimétrés, mais utiliser des unités relatives pour le texte et les espacements.
Les Unités Relatives basées sur la Police
1. Quoi
Ces unités sont calculées en fonction de la taille de la police (font-size). Les deux unités reines sont le em et le rem.
rem(Root EM) : Se base exclusivement sur la taille de la police de l'élément racine (la balise<html>). Par défaut, dans 99% des navigateurs,1rem = 16px.em: Se base sur la taille de la police de l'élément parent (ou de l'élément lui-même pour certaines propriétés).
2. Pourquoi
L'utilisation du rem permet de créer un site entièrement scalable. Si l'utilisateur change sa préférence de police dans le navigateur à 20px, tout votre site (marges, paddings, textes) s'agrandira proportionnellement sans casser la mise en page.
3. Comment
A. Syntaxe de base
html {
font-size: 16px; /* Base racine */
}
.title {
font-size: 2rem; /* 2 * 16px = 32px */
}
.text {
font-size: 1rem; /* 1 * 16px = 16px */
}
B. Cas concret : Le composant Bouton Adaptatif
L'astuce ici est d'utiliser le rem pour la taille du texte et le em pour le padding. Pourquoi ? Parce que si vous changez la taille du texte du bouton, le padding (en em) s'adaptera automatiquement pour garder les proportions visuelles.
.btn {
/* Taille basée sur la racine pour la cohérence globale */
font-size: 1rem;
/* Padding basé sur la taille du texte du bouton lui-même */
/* Si font-size passe à 2rem, le padding doublera aussi ! */
padding: 0.5em 1em;
border-radius: 0.25rem;
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
}
.btn-large {
font-size: 1.5rem; /* Le padding s'adapte grâce au 'em' */
}
C. Limitations
Le piège majeur du em est l'effet cascade (compounding). Si vous imbriquez des éléments ayant tous une taille en em, la taille finale sera multipliée à chaque niveau.
4. Zone de Danger
❌ Erreur commune : Utiliser em pour les marges globales ou les tailles de police imbriquées.
div(1.2em) > div(1.2em) > div(1.2em) → Le texte devient géant très rapidement.
✅ Bonne pratique : Utilisez rem pour presque tout (typographie, espacements de structure) et em uniquement pour les éléments dont le design doit être proportionnel à leur propre texte (boutons, icônes internes).
Différence entre REM et EM
Les Unités de Viewport
1. Quoi
Les unités de viewport sont basées sur la taille de la fenêtre d'affichage (le navigateur).
vw(Viewport Width) : 1% de la largeur de la fenêtre.vh(Viewport Height) : 1% de la hauteur de la fenêtre.vmin: 1% de la plus petite dimension (largeur ou hauteur).vmax: 1% de la plus grande dimension.
2. Pourquoi
Elles sont indispensables pour créer des mises en page "Full Screen" ou des typographies qui s'adaptent dynamiquement à la largeur de l'écran sans passer par des Media Queries complexes.
3. Comment
A. Syntaxe de base
.hero {
width: 100vw; /* Toute la largeur de l'écran */
height: 100vh; /* Toute la hauteur de l'écran */
}
B. Cas concret : Page d'atterrissage (Landing Page)
On veut une section d'accueil qui occupe exactement tout l'écran, avec un titre dont la taille varie selon la largeur du navigateur.
.hero-section {
height: 100vh; /* L'utilisateur voit exactement un écran avant de scroller */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: linear-gradient(to right, #4facfe 0%, #00f2fe 100%);
}
.hero-title {
/* Typographie fluide : base de 5vw + un minimum de 2rem */
/* Cela évite que le texte soit minuscule sur mobile */
font-size: calc(2rem + 5vw);
text-align: center;
}
C. Limitations
Le 100vw peut être problématique car il inclut souvent la largeur de la barre de défilement (scrollbar). Cela peut provoquer un léger scroll horizontal indésirable sur Windows. Pour éviter cela, on préfère souvent width: 100% pour les conteneurs principaux.
4. Zone de Danger
❌ Erreur commune : Utiliser vh pour des conteneurs de texte longs. Si le contenu dépasse la hauteur de l'écran, il sera coupé ou débordera mal.
✅ Bonne pratique : Utiliser min-height: 100vh au lieu de height: 100vh. Cela garantit que l'élément fait au moins la taille de l'écran, mais peut s'agrandir si le contenu est long.
Les Unités de Pourcentage
1. Quoi
Le pourcentage (%) est une unité relative à la taille de l'élément parent.
2. Pourquoi
C'est la base du design fluide. Elle permet de définir des colonnes ou des grilles qui se redistribuent selon l'espace disponible.
3. Comment
A. Syntaxe de base
.container {
width: 1000px;
}
.column {
width: 50%; /* 500px */
}
B. Cas concret : Mise en page en colonnes
.main-layout {
display: flex;
width: 100%;
}
.sidebar {
width: 25%; /* Prend un quart de l'espace parent */
background-color: #f4f4f4;
}
.content {
width: 75%; /* Prend les trois quarts restants */
}
C. Limitations
Le pourcentage pour la hauteur (height: %) est souvent source de frustration pour les débutants. Pour qu'un enfant ait height: 50%, son parent doit avoir une hauteur définie (en px, rem ou vh). Si le parent a une hauteur automatique (height: auto), le pourcentage de l'enfant sera ignoré.
4. Zone de Danger
❌ Erreur commune : Confondre % et vw.
width: 100%→ 100% de la largeur du parent.width: 100vw→ 100% de la largeur de l'écran, peu importe où se trouve l'élément.
✅ Bonne pratique : Utiliser % pour les structures internes et vw/vh pour les structures de haut niveau (sections, wrappers).
Classification des unités CSS
Questions clés
1. Quelle est la différence fondamentale entre em et rem ?
Découvrir la réponse
Le rem (Root EM) se réfère toujours à la taille de police de l'élément racine <html>, ce qui assure une cohérence globale. Le em se réfère à la taille de police de son parent direct, ce qui peut créer un effet multiplicateur (cascade) si on l'utilise sur plusieurs niveaux d'imbrication.
2. Pourquoi éviter les px pour le texte ?
Découvrir la réponse
Parce que les pixels sont des unités fixes. Si un utilisateur malvoyant augmente la taille de police par défaut de son navigateur (ex: de 16px à 24px), un texte défini en px restera bloqué à sa taille initiale, ignorant le choix de l'utilisateur et brisant l'accessibilité.
3. Quand utiliser vh plutôt que % pour la hauteur ?
Découvrir la réponse
On utilise vh quand on veut que l'élément soit proportionnel à la fenêtre du navigateur, indépendamment de la taille du parent. On utilise % quand on veut que l'élément occupe une portion précise de son conteneur parent.
4. Qu'est-ce que vmin et vmax ?
Découvrir la réponse
vmin choisit la plus petite valeur entre vw et vh. C'est très utile pour s'assurer qu'un élément (comme une image carrée) tienne toujours entièrement dans l'écran, que celui-ci soit en mode portrait ou paysage.
Mise en pratique
Exercice 1 : Reproduction guidée (Niveau Facile)
Créez une page simple avec :
- Une police de base sur
htmlde16px. - Un titre
h1dont la taille est de2.5rem. - Un paragraphe dont la taille est de
1rem. - Une marge externe (
margin) sur le paragraphe de1.5rem.
Découvrir la solution commentée
html {
/* On définit la base. 1rem = 16px */
font-size: 16px;
}
h1 {
/* 2.5 * 16px = 40px */
font-size: 2.5rem;
}
p {
/* 1 * 16px = 16px */
font-size: 1rem;
/* 1.5 * 16px = 24px */
margin-bottom: 1.5rem;
}
Exercice 2 : Adaptation (Niveau Moyen)
Vous avez un bouton avec le style suivant :
.btn {
font-size: 16px;
padding: 8px 16px;
}
Modifiez ce code pour que :
- La taille du texte utilise
rem. - Le padding soit proportionnel à la taille du texte (utilisez
em). - Créez une classe
.btn-smallqui réduit la taille du texte, et vérifiez que le padding s'adapte automatiquement.
Découvrir la solution commentée
.btn {
/* Conversion 16px -> 1rem */
font-size: 1rem;
/* 8px est la moitié de 16px (0.5em), 16px est l'équivalent (1em) */
/* Le padding s'adaptera désormais si on change le font-size */
padding: 0.5em 1em;
background-color: #eee;
border: 1px solid #ccc;
}
.btn-small {
/* En réduisant le texte, le padding (en em) diminuera proportionnellement */
font-size: 0.8rem;
}
Exercice 3 : Conception (Niveau Avancé)
Créez une section "Hero" qui répond aux critères suivants :
- Elle doit occuper exactement toute la hauteur et toute la largeur de l'écran.
- Elle doit avoir un fond coloré.
- Elle doit contenir un titre centré dont la taille s'adapte à la largeur de l'écran (utilisez
calc()avecvwetrem). - Le titre ne doit jamais descendre en dessous de
2remni monter au-dessus de5rem. (Indice : utilisezclamp()).
HTML de départ :
<section class="hero">
<h1 class="hero-title">Bienvenue sur notre site</h1>
</section>
Découvrir la solution commentée
.hero {
/* min-height est préférable à height pour éviter les coupures de contenu */
min-height: 100vh;
width: 100%;
background-color: #2c3e50;
color: white;
display: flex;
justify-content: center;
align-items: center;
}
.hero-title {
text-align: center;
/* clamp(minimum, valeur_préférée, maximum) */
/* Le titre fera 5vw, mais restera entre 2rem et 5rem */
font-size: clamp(2rem, 5vw, 5rem);
margin: 0 2rem; /* Marges de sécurité sur les côtés */
}