Centrer en CSS

Formation

En Ligne

Prix sur demande

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Description

  • Typologie

    Formation

  • Méthodologie

    En ligne

Grâce à cette formation vous pourrez acquérir les connaissances nécessaires qui vous permettrons d’ajouter des compétences à votre profil et obtenir de solides aptitude qui vous offriront de nombreuses opportunités professionnelles.

Questions / Réponses

Ajoutez votre question

Nos conseillers et autres utilisateurs pourront vous répondre

À qui souhaitez-vous addresser votre question?

Saisissez vos coordonnées pour recevoir une réponse

Nous ne publierons que votre nom et votre question

Les Avis

Le programme

Introduction du cours

Aaah, centrer des éléments, une question récurrente tant les cas sont nombreux. CSS offre quelques possibilités natives, mais toute la difficulté de l'exercice est de les exploiter comme il faut pour obtenir le rendu souhaité. Je vais ainsi parcourir tous les cas solvables en pur CSS, et tant qu'à faire montrer comment les résoudre.
Finis les <center> ! Finis les align="center" ! Accrochez-vous, c'est parti !

HorizontalementDans le flux

On commence doucement ; le centrage horizontal dans le flux est le plus simple à réaliser puisqu'à chaque cas correspond une propriété CSS. Reste juste à savoir laquelle correspond à chaque cas. En l'occurrence cela dépendra du type d'élément à centrer.

Un élément est dit « dans le flux » si la valeur de sa propriété position est static ou relative et qu'il n'est pas flottant. En l'absence de règles spécifiant le contraire, tout élément fait donc par défaut partie du flux.

Élément bloc

Pour rappel, un élément bloc est soit un élément de type bloc — c'est-à-dire qui possède par défaut la valeur block à sa propriété display —, soit un élément auquel on a attribué display: block;.
Pour centrer un tel élément, c'est très simple, il suffit d'utiliser la propriété margin afin de spécifier sa marge droite et gauche à auto. Pourquoi ? Parce qu'un tel comportement est clairement défini dans la spécification :

Citation : http://www.w3.org/TR/CSS2/visudet.html#blockwidth

If both 'margin-left' and 'margin-right' are 'auto', their used values are equal. This horizontally centers the element with respect to the edges of the containing block.

Si 'margin-left' et 'margin-right' valent 'auto', leurs valeurs effectives sont égales, ce qui centre l'élément dans son bloc conteneur.
On pourra donc soit écrire :

#element { margin-left: auto; margin-right: auto; }

Soit profiter de la notation raccourcie :

#element { margin: auto; }

auquel cas margin-top et margin-bottom vaudront aussi auto, ce qui revient à écrire :

#element { margin: 0 auto; }

Car :

Citation : http://www.w3.org/TR/CSS2/visudet.html#normal-block

If 'margin-top', or 'margin-bottom' are 'auto', their used value is 0.

Si 'margin-top' ou 'margin-bottom' vaut 'auto', leur valeur effective est zéro.
Une dernière précision ; les éléments bloc non remplacés prennent par défaut toute la largeur de leur conteneur. Si vous voulez visualiser le centrage d'un tel élément, il faudra donc lui fixer une largeur inférieure à celle de son conteneur.

Mais c'est quoi un élément...

Tututut je l'ai sentie venir à des kilomètres celle-là :p

Pour faire simple, un élément remplacé est simplement un élément dont le contenu n'est pas considéré par CSS. Par exemple quand vous insérez une balise <img />, son contenu va être remplacé par l'image pointée par son attribut src. Vous pourrez alors styler l'élément, mais n'aurez aucun moyen de cibler son contenu.

Ces éléments ont généralement ce qu'on appelle des dimensions intrinsèques (typiquement les dimensions originales d'une image). Si non, alors :

Citation : http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width

the used value of 'width' becomes 300px. If 300px is too wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.

la valeur effective de 'width' utilisée est 300px. Si 300px est une largeur supérieure à celle du dispositif d'affichage, les agents utilisateur (navigateurs généralement) devraient utiliser à la place la largeur du plus grand rectangle tenant sur l'affichage avec un ratio de 2:1.
D'où la précision ; un élément bloc remplacé n'aura généralement pas besoin d'avoir une largeur explicite pour apparaître centré.

Élément en-ligne

Si un élément n'est pas un bloc, alors il est en-ligne. Cela concerne généralement les valeurs (par défaut ou spécifiées) inline et inline-block de la propriété display, mais également le texte.
Pour centrer un tel élément, il faut cette fois agir sur son conteneur, qui est le plus souvent son plus proche bloc parent. Ainsi il suffit de lui appliquer :

#parent { text-align: center; }

Ce CSS permettra à un élément de centrer tous ses fils en-ligne. J'insiste sur « tous » car la propriété text-align est héritée. De ce fait, tout se passera comme si cette propriété était appliquée à tous les fils de #parent.
Pour rétablir l'alignement normal, il suffira d'utiliser text-align: left; (si vous écrivez de gauche à droite bien sûr) sur le conteneur voulu.
Pour plus d'informations, je vous invite à consulter la spécification du W3C.

Table

Avant de sortir du flux, faisons un petit aparté pour les curieux. Les tableaux HTML ont par défaut la valeur table à leur propriété display, alors bloc ou en-ligne ?
Si vous avez répondu bloc c'est gagné, car :

Citation : http://www.w3.org/TR/CSS2/tables.html#table-display

table [...] specifies that an element defines a block-level table

table [...] spécifie à l'élément de générer une table dans un contexte bloc.
On utilise donc également margin: auto; pour centrer les tableaux… sauf sur IE<7. Pour ces navigateurs, tout se passe comme si la table était dans un contexte en-ligne, auquel cas il faut alors la centrer en spécifiant text-align: center; à son parent.
À titre indicatif un tel comportement peut être retrouvé dans les navigateurs actuels grâce à la valeur inline-table de la propriété display.

Hors du flux

CSS ne permet pas nativement de centrer des éléments hors du flux. Toutefois il existe quelques astuces qui dans certains cas peuvent le permettre.
Un élément est hors du flux s'il est flottant ou fait partie du modèle de positionnement absolu, c'est-à-dire que sa propriété position vaut absolute ou fixed. De tels éléments sont forcément des blocs, vous pourrez donc centrer leur contenu en-ligne comme on vient de le voir.

Flottants

float: center; n'existe pas. Certains trouvent cela logique, certains s'en plaignent, et d'autres s'en foutent, car ils savent centrer des flottants. Seule condition requise ? Avoir deux conteneurs, ce qui est assez facile.
Généralement la question se pose lors de la création d'un menu, une liste de liens. On dispose alors de notre premier conteneur : <ul>. Il suffira donc de l'englober par un <div> pour remplir nos conditions. Comment styler tout ça maintenant ?

<div id="wrapper"> <ul id="menu"> <li><a href="#">Premier lien</a></li> <li><a href="#">Deuxième</a></li> <li><a href="#">Troisième</a></li> </ul> </div>

Nous allons utiliser le positionnement relatif, qui permet de déplacer un élément par rapport à sa position dans le flux normal. Pour ce faire, nous disposons des propriétés top, right, bottom et left, qui acceptent des valeurs en pourcentage. Ainsi :

#element { left: 50%; }

Voudra dire que nous déplaçons notre élément vers la droite d'une distance correspondant à la moitié de celle de son conteneur, ce qui place son extrémité gauche au centre de son conteneur. À partir de là, il suffit de déplacer vers la gauche les fils de cet élément d'une distance égale à la moitié de la somme de leur largeur. Et c'est possible en CSS ! En effet si <ul> est déclaré flottant, sa largeur sera égale à la somme de celle de ses fils. Il suffit alors de le déplacer de 50% vers la droite, et de déplacer chaque <li> de 50% vers la gauche. Le conteneur global servira simplement à éviter que ces décalages ne provoquent un débordement de la zone d'affichage. Si l'on traduit tout en CSS, cela nous donne

#wrapper { /* masque les débordements et englobe le menu */ overflow: hidden; } #menu,#menu li { /* on supprime les éventuels styles par défaut */ margin: 0; padding: 0; list-style: none; /* float permet à l'élément de prendre la largeur de son contenu */ float: left; position: relative; } #menu { /* on décale le menu vers la droite de la moitié de la largeur disponible */ left: 50%; } #menu li { /* on décale chaque item vers la gauche de la moitié de la largeur du menu */ right: 50%; }

Vraiment pas compliqué, vous voyez ?! Le tout est d'y penser bien sûr. ;)
Bon il est temps de terminer la partie horizontale ; une petite dernière et on commencera le plus intéressant !

Positionnement absolu

L'astuce permettant de centrer un tel élément est basée sur le même principe que celle des flottants. La seule différence vient du fait que notre élément ne pourra pas être englobé dans un conteneur, ce qui ajoute seulement une contrainte, mais de taille : vous devez spécifier une largeur à cet élément.
En effet, dans l'exemple précédent nous pouvions déduire la largeur de nos flottants grâce au conteneur, ce qui n'est plus possible ici (puisqu'un élément faisant partie du modèle de positionnement absolu n'impacte pas le flux). Alors faute de pouvoir la déduire, on va la spécifier. Le principe reste ensuite exactement le même, mis à part qu'on ne peut agir que sur l'élément. On va donc le décaler de 50% vers la droite puis utiliser une marge négative pour le décaler de la moitié de sa largeur vers la gauche.

Si on décide de lui attribuer 400px de large, alors on écrira :

#element { position: absolute; left: 50%; width: 400px; margin-left: -200px; }

Le centrage des éléments hors du flux est ici plus présent à titre indicatif ; si vous avez le choix, il est plus sage d'utiliser les méthodes "classiques" pour des éléments dans le flux.

VerticalementLa magie de line-height

line-height, c'est une propriété que vous avez sûrement utilisée, et sans doute sans la comprendre :p
On va donc se rattraper, car cela nous sera utile pour la suite. Le premier réflexe à avoir quand on cherche des infos sur le HTML/CSS, c'est d'aller voir la spécification. Le site du W3C est assez mal référencé alors n'hésitez pas à ajouter W3C devant les termes de votre recherche.

En cherchant w3c line-height, le premier lien nous amène sur une page intitulée Visual formatting model details, dans laquelle on trouve la section Line height calculations: the 'line-height' and 'vertical-align' properties ; jetons-y un coup d'oeil.

...

C'est compliqué n'est-ce pas ? :p
Bon je vais être sympa (pour une fois) ; la partie qui nous intéresse est la suivante :

Citation : http://www.w3.org/TR/CSS2/visudet.html#leading

CSS assumes that every font has font metrics that specify a characteristic height above the baseline and a depth below it. In this section we use A to mean that height (for a given font at a given size) and D the depth. We also define AD = A + D, the distance from the top to the bottom. [...] Note that these are metrics of the font as a whole and need not correspond to the ascender and descender of any individual glyph.

User agent must align the glyphs in a non-replaced inline box to each other by their relevant baselines. Then, for each glyph, determine the A and D. Note that glyphs in a single element may come from different fonts and thus need not all have the same A and D. If the inline box contains no glyphs at all, it is considered to contain a strut (an invisible glyph of zero width) with the A and D of the element's first available font.

Still for each glyph, determine the leading L to add, where L = 'line-height' - AD. Half the leading is added above A and the other half below D, giving the glyph and its leading a total height above the baseline of A' = A + L/2 and a total depth of D' = D + L/2.

En français, cela veut dire que pour chaque élément dans un contexte en-ligne, le navigateur va déterminer sa hauteur par défaut en fonction des caractéristiques de la police utilisée. Cette hauteur sera la somme des hauteurs sur (A) et sous (D) la baseline :

Maintenant que se passe-t'il lorsqu'on spécifie un line-height ?
Eh bien le navigateur va calculer la hauteur supplémentaire à allouer à l'élément en soustrayant A et D au line-height, et va ajouter une moitié du résultat à A et l'autre à D.

Du coup le texte se retrouve centré verticalement par rapport au line-height de son parent, vous voyez où je veux en venir..?!

Centrer une ligne de texte dans un conteneur de hauteur fixe

On sait maintenant qu'en spécifiant un line-height, le contenu en-ligne sera centré dans ce dernier. On pourra l'utiliser soit sur le conteneur, soit sur le contenu en-ligne.
En l'occurrence une ligne de texte dans un bloc génère une boîte en-ligne anonyme et donc impossible à cibler avec CSS.

Pour centrer le texte ci-dessous verticalement dans son paragraphe :

<p>trololol</p>

On aura juste à spécifier au paragraphe une hauteur de ligne égale à sa hauteur, disons 5em :

p { line-height:5em; }

Si pour une raison ou une autre un saut de ligne est rendu, la ligne suivante se positionnera en fonction du

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Centrer en CSS

Prix sur demande