Skip to main content

Chapitre 17 : Gestion des marges et paddings logiques : margin-inline et padding-block

Utilisation des propriétés logiques pour le spacing adaptatif au mode d'écriture

L'un des plus grands défis du développement web moderne est l'internationalisation (i18n). Historiquement, nous avons pensé le design en termes de "gauche" et "droite". Cependant, pour un utilisateur dont la langue s'écrit de droite à gauche (RTL) comme l'arabe ou l'hébreu, ou verticalement comme certaines formes d'écriture japonaises, les notions de "gauche" et "droite" ne font plus sens.

C'est ici qu'interviennent les propriétés logiques de spacing. Au lieu de dire au navigateur "ajoute une marge à gauche", nous lui disons "ajoute une marge au début de la ligne d'écriture".

Le Spacing Logique

1. Quoi

Le spacing logique consiste à remplacer les propriétés physiques (basées sur les axes X et Y de l'écran) par des propriétés basées sur le flux du contenu.

On distingue deux axes principaux :

  • L'axe Inline : L'axe suivant lequel le texte s'écoule dans une ligne (horizontalement en français, verticalement dans certains modes).
  • L'axe Block : L'axe suivant lequel les blocs s'empilent (verticalement en français, horizontalement dans certains modes).

Les propriétés concernées sont :

  • margin-inline : Contrôle les marges au début et à la fin de l'axe inline (remplace margin-left et margin-right).
  • margin-block : Contrôle les marges au début et à la fin de l'axe block (remplace margin-top et margin-bottom).
  • padding-inline : Contrôle les paddings au début et à la fin de l'axe inline (remplace padding-left et padding-right).
  • padding-block : Contrôle les paddings au début et à la fin de l'axe block (remplace padding-top et padding-bottom).

2. Pourquoi

L'utilisation des propriétés logiques est cruciale pour l'accessibilité (a11y) et l'internationalisation (i18n) pour plusieurs raisons :

  1. Adaptabilité automatique : Si vous changez l'attribut dir="rtl" sur votre balise <html>, toutes vos marges inline s'inversent automatiquement sans que vous ayez à écrire une seule ligne de CSS supplémentaire.
  2. Réduction du code : Au lieu d'écrire deux propriétés (margin-left et margin-right), vous n'en écrivez qu'une seule (margin-inline).
  3. Cohérence sémantique : Vous décrivez l'intention (espacer le contenu par rapport au flux) plutôt que la position physique.

3. Comment

A. Syntaxe de base

Les propriétés logiques fonctionnent comme des raccourcis (shorthands).

/* Marges horizontales (en mode LTR) */
.card {
margin-inline: 20px; /* Applique 20px à gauche ET à droite */
}

/* Padding vertical (en mode LTR) */
.card {
padding-block: 1rem; /* Applique 1rem en haut ET en bas */
}

B. Cas concret : Un composant de navigation adaptatif

Imaginons un bouton avec une icône. Nous voulons que l'icône ait un espace à sa droite en français, mais à sa gauche en arabe.

/* Style robuste et moderne */
.nav-button {
display: inline-flex;
align-items: center;
padding-block: 0.5rem;
padding-inline: 1rem;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}

.nav-button .icon {
/* On utilise margin-inline-end pour que l'espace
soit toujours "après" l'icône, peu importe le sens de lecture */
margin-inline-end: 0.75rem;
width: 20px;
height: 20px;
}

Dans ce cas :

  • En mode LTR (Français) : margin-inline-end devient margin-right.
  • En mode RTL (Arabe) : margin-inline-end devient margin-left.

C. Limitations

Bien que largement supportées par les navigateurs modernes, les propriétés logiques peuvent poser problème si :

  • Vous devez supporter des navigateurs extrêmement anciens (Internet Explorer).
  • Vous travaillez sur des designs "pixel-perfect" où certains éléments doivent rester physiquement fixes malgré le changement de langue (cas très rares).

4. Zone de Danger

L'erreur commune : Mélanger physique et logique Mélanger margin-left et margin-inline dans le même composant crée des conflits difficiles à déboguer. Si vous passez au mode RTL, le margin-inline s'inversera, mais le margin-left restera à gauche, brisant votre mise en page.

La bonne pratique : Le "All-in" Logique Une fois que vous commencez à utiliser les propriétés logiques dans un projet, convertissez systématiquement toutes vos propriétés de spacing (top, bottom, left, right) en propriétés logiques (block-start, block-end, inline-start, inline-end).

Mapping des propriétés logiques selon le mode d'écriture

Questions clés

1. Quelle est la différence fondamentale entre margin-left et margin-inline-start ?

Découvrir la réponse

margin-left est une propriété physique : elle applique toujours la marge à gauche, peu importe la langue. margin-inline-start est une propriété logique : elle applique la marge au début de la ligne d'écriture (à gauche en LTR, à droite en RTL).

2. Si je veux ajouter un espace en haut et en bas d'un élément, quelle propriété logique dois-je utiliser ?

Découvrir la réponse

Il faut utiliser margin-block (pour les marges extérieures) ou padding-block (pour l'espace intérieur).

3. Est-ce que margin-inline: 10px 20px; est valide ?

Découvrir la réponse

Oui. Comme pour les propriétés physiques, on peut spécifier deux valeurs. La première s'applique au start et la seconde au end.

4. Pourquoi utiliser padding-inline plutôt que padding: 0 10px; ?

Découvrir la réponse

padding: 0 10px; est un raccourci physique qui définit le haut/bas à 0 et la gauche/droite à 10px. Si vous aviez déjà un padding en haut, vous l'écraseriez. padding-inline: 10px; ne modifie que l'axe horizontal, laissant intact le padding vertical.

Mise en pratique

Exercice 1 : Reproduction guidée

Objectif : Créer une carte de profil simple en utilisant uniquement des propriétés logiques.

Consignes :

  • Créez un élément .profile-card.
  • Ajoutez un padding interne de 2rem sur l'axe block et 1.5rem sur l'axe inline.
  • Ajoutez une marge extérieure de 1rem sur tous les côtés en utilisant les propriétés logiques.
Découvrir la solution commentée
.profile-card {
/* Padding : haut/bas = 2rem, gauche/droite = 1.5rem */
padding-block: 2rem;
padding-inline: 1.5rem;

/* Marges : on peut utiliser les deux axes pour couvrir les 4 côtés */
margin-block: 1rem;
margin-inline: 1rem;

border: 1px solid #ccc;
border-radius: 8px;
}

Exercice 2 : Adaptation

Objectif : Convertir un code "physique" en code "logique".

Consignes : Transformez le bloc CSS suivant pour qu'il soit compatible avec le mode RTL sans modification supplémentaire.

.alert {
margin-top: 10px;
margin-bottom: 10px;
padding-left: 20px;
padding-right: 20px;
border-left: 5px solid red;
}

(Note : Pour la bordure, utilisez border-inline-start).

Découvrir la solution commentée
.alert {
/* margin-top et margin-bottom deviennent margin-block */
margin-block: 10px;

/* padding-left et padding-right deviennent padding-inline */
padding-inline: 20px;

/* border-left devient border-inline-start pour s'inverser en RTL */
border-inline-start: 5px solid red;
}

Exercice 3 : Conception

Objectif : Créer un système de "breadcrumbs" (fil d'Ariane) internationalisé.

HTML de départ :

<nav aria-label="Fil d'Ariane">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="#">Accueil</a>
<span class="breadcrumb-separator">/</span>
</li>
<li class="breadcrumb-item">
<a href="#">Produits</a>
<span class="breadcrumb-separator">/</span>
</li>
<li class="breadcrumb-item">
<span>Détails</span>
</li>
</ol>
</nav>

Consignes :

  • Affichez les éléments de la liste horizontalement (chaque .breadcrumb-item en inline-flex).
  • Le séparateur doit avoir un espace de 0.5rem à sa gauche et à sa droite.
  • Utilisez les propriétés logiques pour garantir que l'espacement reste correct si le site passe en Arabe.
Découvrir la solution commentée
.breadcrumb-item {
display: inline-flex;
align-items: center;
}

.breadcrumb-separator {
/* On utilise margin-inline pour espacer le séparateur
de manière symétrique sur l'axe de lecture */
margin-inline: 0.5rem;
color: #666;
}

/*
En LTR : le séparateur aura 0.5rem à gauche et à droite.
En RTL : le séparateur aura toujours 0.5rem à gauche et à droite,
mais l'ordre des éléments sera inversé par le navigateur,
maintenant une cohérence visuelle parfaite.
*/