Lorsque l'on intègre une maquette en CSS, il est fréquent de vouloir centrer le contenu tout en limitant sa largeur pour garantir une bonne lisibilité, notamment sur les grands écrans. C'est là qu'intervient la notion de "conteneur" en CSS. On peut alors se demander quelle solution choisir pour créer ce type d'élément ?
Solution classique : largeur maximale et marges automatiques
Une première approche consiste à définir une largeur maximale pour le conteneur et à utiliser les marges automatiques pour le centrer :
.container {
box-sizing: content-box;
max-width: 700px;
margin-inline: auto;
padding-inline: 1rem;
}
Cette solution fonctionne bien dans la plupart des cas. Sur les écrans plus petits, le padding-inline
assure un espacement minimal avec les bords de l'écran.
Une autre approche consiste à intègrer directement le padding
dans le calcul de la largeur, en utilisant min()
:
.container {
box-sizing: border-box;
max-width: min(700px, calc(100% - 2rem));
margin-inline: auto;
}
Cette solution évite d'ajouter explicitement un padding
ce qui peut être intéréssant si on veut cumuler cette classe avec un autre style qui utilise du padding.
Éléments débordantes
Dans certains designs, on souhaite parfois que certains éléments dépassent du conteneur tout en restant centrés. On peut dans ce cas là utiliser le positionnement relatif.
.container img {
position: relative;
left: 50%;
transform: translateX(-50%);
max-width: 100vw;
}
L'inconvénient de cette approche est que l'élément peut déborder hors de la page et il sera nécessaire d'ajouter overflow-x: hidden
au body
pour évite de voir apparaitre une barre de défilement.
Solution alternative : styliser les enfants
Plutôt que de centrer directement le conteneur, on peut choisir de centrer chacun de ses enfants :
.container > * {
max-width: min(700px, 100% - 2rem);
margin-inline: auto;
display: block;
}
Cette approche permet de gérer beaucoup plus simplement le débordement pour des éléments spécifiques.
.container > figure,
.container > img {
max-width: 100%;
height: auto;
}
.container > iframe {
width: 100%;
height: auto;
aspect-ratio: 16 /9;
max-width: 900px;
}
En revanche cette approche a quelques limitations :
- Les éléments débordants doivent être des enfants directs du conteneur.
- Certains éléments (comme les boutons) ne peuvent pas être des enfants direct du conteneur.
On peut introduire des variables CSS pour rendre le système plus modulaire :
:root {
--container-width: 1100px;
--container-padding: 1rem;
}
.container > * {
box-sizing: border-box;
max-width: min(
var(--container-width),
calc(100% - 2 * var(--container-padding))
);
margin-inline: auto;
}
Cette approche permet d'ajuster facilement la largeur pour créer des variantes.
.container.narrow {
--container-width: 700px;
}