La Cascade

Un peu de tout sur CSS, HTML, SVG et JS,traduit du web anglophone
Rechercher

CSS Flexbox et l'alignement, guide complet

par Rachel Andrew, 9 décembre 2018, css, flexbox, article original paru le 13 août 2018 dans Smashing Magazine

Dans cet article, nous examinons les propriétés d'alignement de Flexbox tout en découvrant quelques règles de base qui nous aideront à nous rappeler comment elles fonctionnent sur les axes principal et transversal


Dans le premier article de cette série, j'ai expliqué ce qui se passait lorsqu'on déclare display: flex sur un élément. Ici, nous allons examiner les propriétés d'alignement et la façon dont elles fonctionnent dans Flexbox. Si align et justify vous ont donné des migraines par le passé, j'espère que cet article rendra les choses plus claires !

Une histoire de l'alignement Flexbox

Depuis le début de CSS Layout, l'alignement correct des éléments sur les deux axes a toujours semblé le problème le plus ardu en matière de conception de sites Web. La capacité d'aligner correctement des éléments et des groupes d'éléments a donc été, pour beaucoup d'entre nous, l'apport le plus excitant de Flexbox. L'alignement est devenu aussi simple que deux lignes de CSS :

Les propriétés d'alignement que vous considérez peut-être comme des propriétés Flexbox sont maintenant entièrement définies dans la spécification d'alignement de boîte (Box Alignment). Cette spécification détaille le fonctionnement de l'alignement dans les divers contextes de layout. Cela signifie que nous pouvons utiliser les mêmes propriétés d'alignement dans CSS Grid que celles utilisées dans Flexbox – et à l'avenir dans d'autres contextes de layout. Par conséquent, toute nouvelle capacité d'alignement pour Flexbox sera décrite en détail dans la spécification Box Alignment et non dans un futur niveau de Flexbox.

Les Propriétés

Beaucoup de gens me disent qu’ils ont du mal à se rappeler s’ils doivent utiliser des propriétés qui commencent par align- ou celles qui commencent par justify- dans Flexbox. Ce qu'il faut retenir :

  • justify- effectue l'alignement de l'axe principal. Alignement dans la même direction que votre flex-direction
  • align- effectue un alignement transversal. Alignement dans la direction perpendiculaire à votre flex-direction.

Il est vraiment utile ici de penser en termes d’axe principal et d’axe transversal plutôt que d’horizontale et de verticale.

Alignement sur l'axe principal avec justify-content

Commençons par l'alignement de l'axe principal. Sur cet axe, nous alignons à l'aide de la propriété justify-content. Cette propriété considère l'ensemble de nos éléments flexibles comme un groupe et contrôle la répartition de l'espace entre les éléments.

La valeur initiale de justify-content est flex-start. C’est pourquoi, lorsque vous déclarez display: flex, tous les items flexibles sont alignés à partir du début de la ligne flex. Si vous avez une flex-direction de row et que vous parlez une langue écrite de gauche à droite comme l'anglais, les éléments commenceront à gauche.

Les items s'alignent depuis le point de départ

Remarquez que la propriété justify-content ne peut faire quelque chose que s'il y a un espace disponible à distribuer. Par conséquent, si vos items flexibles occupent toute la place sur l'axe principal, l'utilisation de justify-content ne changera rien.

Il n'y a pas d'espace à partager

Si nous donnons à justify-content la valeur flex-end, alors tous les items sont déplacés vers la fin de la ligne. L'espace disponible, s'il y en a, est maintenant placé en début de ligne.

Les items s'alignent sur le point d'arrivée

Nous pouvons faire d'autres choses avec cet espace. Nous pourrions souhaiter qu’il soit distribué entre nos items flexibles, en utilisant justify-content: space-between. Dans ce cas, le premier et le dernier élément seront alignés avec les extrémités du conteneur et tout l’espace sera partagé de manière égale entre les éléments.

L'espace libre est réparti entre les items

Nous pouvons demander que l’espace soit réparti autour de nos éléments flexibles, en utilisant justify-content: space-around. Dans ce cas, l'espace disponible est partagé et placé de chaque côté de l'élément.

Les items ont de l'espace de chaque côté

Une valeur plus récente de justify-content peut être trouvée dans la spécification Box Alignment. Elle n'apparaît pas dans la spécification Flexbox. Cette valeur est space-evenly. Dans ce cas, les éléments seront répartis de manière uniforme dans le conteneur et l'espace supplémentaire sera partagé entre les éléments et de chaque côté.

Les éléments sont uniformément répartis

Vous pouvez jouer avec toutes ces valeurs dans la démo :

Ces valeurs fonctionnent de la même manière si votre flex-direction est column. Il est possible toutefois que la colonne n'offre pas autant d'espace disponible, à moins d'ajouter une hauteur ou une dimension de bloc au conteneur flex comme dans la démo suivante :

Alignement sur l'axe transversal avec align-content

Si vous avez ajouté flex-wrap: wrap à votre conteneur flex et que vous avez plusieurs lignes flex, vous pouvez utiliser align-content pour aligner vos lignes flex sur l'axe transversal. Toutefois, il vous faudra disposer d'un espace supplémentaire sur l'axe transversal. Dans la démonstration ci-dessous, mon axe transversal fonctionne dans la direction bloc comme une colonne et j'ai défini la hauteur du conteneur flex à 60vh. C'est plus que l'espace nécessaire pour afficher mes items flex, j'ai donc de la place verticalement dans le conteneur.

Je peux ensuite utiliser align-content avec les valeurs ci-dessous :

Si ma flex-direction était column alors align-content fonctionnerait comme dans l'exemple suivant :

Tout comme précédemment avec justify-content, nous traitons les lignes comme un groupe et nous distribuons l'espace disponible.

Le raccourci place-content

Dans la spécification Box Alignment, on trouve le raccourci place-content. Avec cette propriété, vous pouvez définir en même temps justify-content et align-content. La première valeur est pour align-content, la seconde pour justify-content :

.container {
    place-content: space-between stretch;
}

équivaut à :

.container {
    align-content: space-between;
    justify-content: stretch;
}

Si par contre vous ne définissez qu'une seule valeur, align-content et justify-content prennent cette valeur :

.container {
    place-content: space-between;
}

équivaut à :

.container {
    align-content: space-between;
    justify-content: space-between;
}

Alignement sur l'axe transversal avec align-items

Nous savons maintenant que nous pouvons aligner notre ensemble d'items flex ou nos lignes flex comme un groupe. Cependant, nous pourrions souhaiter aligner nos éléments d’une autre manière : aligner les éléments les uns par rapport aux autres sur l’axe transversal. Votre conteneur flex a une hauteur. Cette hauteur peut être définie par la hauteur de l'élément le plus grand, comme dans cette image.

La hauteur du conteneur est définie par celle du 3e élément

Mais on pourrait aussi la définir en ajoutant une hauteur au conteneur flex :

La hauteur du conteneur est définie comme une dimension du conteneur

La raison pour laquelle les éléments flexibles semblent s’étirer jusqu’à atteindre la taille de l’élément le plus grand est que la valeur initiale d’align-items est stretch. Les items s'étirent sur l'axe transversal pour prendre la taille du conteneur flexible dans cette direction.

Notez qu'en ce qui concerne align-items, si vous avez un conteneur flex multi-lignes, chaque ligne se comporte comme un nouveau conteneur Flex. L'item le plus grand de cette ligne définirait la taille de tous les items de cette ligne.

En plus de la valeur initiale de stretch, vous pouvez attribuer à align-items la valeur de flex-start. Dans ce cas, les items s'alignent au début du conteneur et ne s'étirent plus en hauteur.

Les items sont alignés au départ de l'axe transversal

La valeur flex-end les déplace à la fin de l'axe transversal :

Les items sont alignés à la fin de l'axe transversal

Si vous utilisez la valeur center, les items sont centrés les uns par rapport aux autres :

Les items sont centrés sur l'axe transversal

Enfin, nous pouvons aligner les items sur la ligne de base, permettant ainsi de s'assurer que le texte est aligné, ce qui ne serait pas nécessairement le cas si l'alignement se faisait sur le contenu.

Les items sont centrés sur la ligne de base

Vous pouvez jouer avec toutes ces valeurs dans la démo :

Alignement individuel avec align-self

La propriété align-items vous permet de définir l'alignement de tous les éléments en même temps. En réalité, cela permet de définir toutes les valeurs align-self sur les éléments flex individuels de manière groupée. Vous pouvez également utiliser la propriété align-self sur tout élément flex individuel pour l'aligner à l'intérieur de la ligne flex et par rapport aux autres éléments flex.

Dans l'exemple suivant, j'ai utilisé align-items sur le conteneur pour définir l'alignement du groupe sur center, mais j'ai également utilisé align-self sur le premier et le dernier éléments pour modifier leur valeur d'alignement (vérifiez en cliquant sur CSS).

Pourquoi n'y a-t-il pas de justify-self ?

Une question souvent posée est de savoir pourquoi il n'est pas possible d'aligner un élément ou un groupe d'éléments sur l'axe principal. Pourquoi n'y a-t-il pas de propriété -self pour l'alignement sur l'axe principal dans Flexbox ? Si vous considérez justify-content et align-content comme étant une façon de distribuer l'espace, la raison pour laquelle ils ne sont pas auto-alignés devient plus évidente. Nous traitons les éléments flexibles en tant que groupe et distribuons l'espace disponible d'une manière ou d'une autre - au début ou à la fin du groupe, ou entre les éléments.

Il pourrait également être utile de réfléchir à la manière dont justify-content et align-content fonctionnent dans CSS Grid Layout. Dans Grid, ces propriétés sont utilisées pour répartir l'espace disponible dans le conteneur de grille entre les pistes (tracks) de la grille. Une fois encore, nous prenons les pistes en tant que groupe et ces propriétés nous permettent de répartir l'éventuel espace supplémentaire entre elles. Comme nous agissons sur un groupe, à la fois dans Grid et dans Flexbox, nous ne pouvons pas cibler un élément seul et faire quelque chose de différent avec celui-ci. Cependant, il existe un moyen de réaliser le type de présentation auquel vous pensez lorsque vous souhaitez une propriété -self sur l'axe principal, et ce moyen c'est l'utilisation de marges automatiques.

Utiliser les marges automatiques sur l'axe principal

Si vous avez déjà centré un bloc dans CSS (par exemple le wrapper du contenu de votre page principale, en définissant une marge auto à gauche et à droite), vous avez déjà une expérience du comportement des marges automatiques. Une marge réglée sur auto essayera de devenir aussi grande que possible dans la direction dans laquelle elle a été définie. Lorsque les marges sont utilisées pour centrer un bloc, nous définissons les positions gauche et droite sur auto, chacune essaye de prendre le plus de place possible et pousse notre bloc au centre.

Les marges automatiques fonctionnent très bien dans Flexbox pour aligner des éléments uniques ou des groupes d’éléments sur l’axe principal. Dans l'exemple qui suit, je réalise un design pattern très courant. J'ai une barre de navigation utilisant Flexbox, les éléments sont affichés sur une ligne et utilisent la valeur initiale de justify-content: start. J'aimerais que le dernier élément soit affiché séparément des autres, à la fin de la ligne flex – en supposant qu'il y ait suffisamment d'espace sur la ligne pour le faire.

Je cible cet item et je lui donne une marge gauche auto. Cela a pour effet que la marge essaie d'obtenir le plus d'espace possible à gauche de l'élément, ce qui entraîne le déplacement de l'élément complètement à droite.

Si vous utilisez les marges automatiques sur l'axe principal, justify-content n'aura plus d'effet puisque les marges automatiques auront pris tout l'espace qui aurait pu être utilisé par justify-content.

Alignement de repli

Chaque méthode d’alignement détaille un alignement de repli (fallback), c’est à dire ce qui se produira si l’alignement que vous avez demandé ne peut pas être réalisé. Par exemple, si vous n'avez qu'un seul élément dans un conteneur flexible et demandez justify-content: space-between, que devrait-il se passer ? La réponse est que l'alignement de repli flex-start est utilisé et que votre item individuel s'alignera au début du conteneur flex. Dans le cas de justify-content: space-around, un alignement de repli centerest utilisé.

Dans la spécification actuelle, vous ne pouvez pas modifier l'alignement de repli. Si vous préférez que le repli de space-between soit center plutôt que flex-start, il n'y a pas moyen de le faire. Cependant, une note dans la spécification indique que les niveaux futurs devraient le permettre.

Alignement safe et unsafe

Un ajout plus récent à la spécification Box Alignment est le concept d'alignement sécurisé / non sécurisé à l'aide des mots clés safe et unsafe.

Dans le code suivant, le dernier élément est trop large pour le conteneur et, avec un alignement non sécurisé et le conteneur flexible sur le côté gauche de la page, l'élément est coupé : le débordement se situe en dehors des limites de la page.

.container {
    display: flex;
    flex-direction: column;
    width: 100px;
    align-items: unsafe center;
}

.item:last-child {
    width: 200px;
}
Un alignement non sécurisé vous donnera l'alignement que vous souhaitez mais vous pouvez y perdre des données

Un alignement sécurisé évite la perte de données, en déplaçant le débordement vers l'autre côté.

.container {
    display: flex;
    flex-direction: column;
    width: 100px;
    align-items: safe center;
}

.item:last-child {
    width: 200px;
}
Un alignement sécurisé essaie d'éviter la perte de données

Ces mots-clés ont un support navigateur encore limité mais ils sont une bonne illustration du contrôle supplémentaire apporté à Flexbox via la spécification Box Alignment.

Récapitulation

Les propriétés d'alignement ont commencé sous forme de liste dans Flexbox, mais elles ont maintenant leur propre spécification et s'appliquent à d'autres contextes de layout. Quelques points-clés vous aideront à vous rappeler comment les utiliser dans Flexbox:

  • justify- l'axe principal et align- l'axe transversal;
  • Pour utiliser align-content et justify-content, vous avez besoin d'espace disponible.
  • Les propriétés align-content et justify-content traitent les éléments en tant que groupe, en partageant de l'espace. Par conséquent, vous ne pouvez pas cibler un élément individuel et il n’existe donc pas d’alignement de type -self pour ces propriétés;
  • Si vous souhaitez aligner un élément ou diviser un groupe sur l'axe principal, utilisez les marges automatiques pour le faire.
  • La propriété align-items définit toutes les valeurs align-self en tant que groupe. Utilisez align-self sur le flex enfant pour définir la valeur d'un élément individuel.

Autres ressources externes

Articles de Rachel Andrew traduits dans La Cascade

Voir la page de Rachel Andrew et la liste de ses articles dans La Cascade.
Article original paru le 13 août 2018 dans Smashing Magazine
Traduit avec l'aimable autorisation de Smashing Magazine et de Rachel Andrew.
Copyright Smashing Magazine © 2018