Cette page a été traduite à partir de l'anglais par la communauté. Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.

View in English Always switch to English

Boîtes flexibles

La boîte flexible est une méthode de mise en page selon un axe principal, permettant de disposer des éléments en incise ou en colonne. Les éléments se dilatent ou se rétractent pour occuper l'espace disponible. Cet article en explique tous les fondamentaux.

Prérequis : Structurer le contenu avec HTML, Bases du style CSS, Fondamentaux du style du texte et des polices, notions de base sur la mise en page CSS.
Objectifs d'apprentissage :
  • Le but du flexible : disposer de façon flexible un ensemble d'éléments blocs ou en incise sur un seul axe.
  • La terminologie Flex : conteneur flexible, élément flexible, axe principal, axe croisé.
  • Comprendre ce que display: flex apporte par défaut.
  • Comment répartir le contenu sur de nouvelles lignes ou colonnes.
  • Dimensionnement et ordre flexibles des éléments flexibles.
  • Justification et alignement du contenu.

Pourquoi Boîte flexible ?

La mise en page CSS flexible permet :

  • De centrer verticalement un bloc de contenu dans son parent ;
  • De faire que tous les enfants d'un conteneur occupent chacun la même quantité de hauteur ou de largeur disponible selon l'espace offert ;
  • De faire que toutes les colonnes dans une disposition multi‑colonnes aient la même hauteur, même si leur quantité de contenu diffère.

Les fonctionnalités d'une boîte flexible peuvent être la solution idéale pour vos besoins de mise en page unidimensionnelle. Découvrons cela ensemble !

Note : L'introduction de Scrimba pour les boîtes flexibles (angl.) Partenaire d'apprentissage MDN propose un guide interactif expliquant à quel point les boîtes flexibles est courant sur le web, pourquoi il est important de l'apprendre, et vous guide à travers un cas d'utilisation typique qui démontre la puissance de la boîte flexible.

Voici un exemple simple

Dans cet article, vous allez suivre une série d'exercices pour vous aider à comprendre le fonctionnement de la boîte flexible. Pour commencer, faites une copie locale du HTML et du CSS. Chargez-les dans un navigateur moderne (comme Firefox ou Chrome) et examinez le code dans votre éditeur. Vous pouvez aussi cliquer sur le bouton « Exécuter » pour l'ouvrir dans l'aire de jeu.

html
<header>
  <h1>Un exemple de flexbox</h1>
</header>
<section>
  <article>
    <h2>Premier article</h2>
    <p>Contenu…</p>
  </article>
  <article>
    <h2>Second article</h2>
    <p>Contenu…</p>
  </article>
  <article>
    <h2>Troisième article</h2>
    <p>Contenu…</p>
  </article>
</section>
css
body {
  font-family: sans-serif;
  margin: 0;
}
header {
  background: purple;
  height: 100px;
}
h1 {
  text-align: center;
  color: white;
  line-height: 100px;
  margin: 0;
}
section {
  zoom: 0.8;
}
article {
  padding: 10px;
  margin: 10px;
  background: aqua;
}
/* Ajoutez votre CSS flexbox ci-dessous */

Qu'avons‑nous ? Un élément <header> avec un en‑tête de haut niveau à l'intérieur, et un élément <section> contenant trois éléments <article>. Nous allons les utiliser pour créer une disposition vraiment classique sur trois colonnes.

Détermination des éléments à disposer en boîtes flexibles

Pour commencer, sélectionnons les éléments devant être présentés sous forme de boîtes flexibles. Pour ce faire, donnons une valeur spéciale à la propriété display du parent de ces éléments à disposer. Dans ce cas, comme cela concerne les éléments <article>, nous affectons la valeur flex à l'élément <section> (qui devient un conteneur flexible) :

css
section {
  display: flex;
}

Voici le résultat :

Cette unique déclaration donne tout ce dont nous avons besoin : incroyable, non ? Nous avons ainsi une disposition en plusieurs colonnes de largeur égale et toutes de même hauteur. Ceci parce que les valeurs par défaut données aux éléments flexibles (les enfants du conteneur flexible) sont configurées pour résoudre des problèmes courants comme celui-ci.

Récapitulons ce qui se passe ici. Ajouter une valeur flex à display pour un élément en fait un conteneur flexible. Le conteneur est affiché comme un contenu de type bloc en ce qui concerne son interaction avec le reste de la page. Quand l'élément devient un conteneur flexible, ses enfants deviennent (et sont disposés comme) des éléments flexibles.

Vous pouvez rendre le conteneur en incise en utilisant une valeur de display externe (par exemple, display: inline flex), ce qui affecte la façon dont le conteneur lui-même est disposé dans la page. La valeur héritée inline-flex affiche également le conteneur en incise. Nous allons nous concentrer sur le comportement du contenu dans ce tutoriel, mais si vous souhaitez voir l'effet d'une disposition en incise par rapport à une disposition en bloc, consultez la comparaison des valeurs sur la page de la propriété display.

Les prochaines sections expliquent plus en détail ce que sont les éléments flexibles et ce qui se passe à l'intérieur d'un élément lorsque vous en faites un conteneur flexible.

Aparté sur le modèle flexible

Lorsque les éléments sont disposés en boîtes flexibles, ils sont disposés le long de deux axes :

Trois éléments flexibles dans une langue de gauche à droite sont disposés côte à côte dans un conteneur flexible. L'axe principal — l'axe du conteneur flexible dans la direction dans laquelle les éléments flexibles sont disposés — est horizontal. Les extrémités de l'axe sont main-start et main-end et se trouvent respectivement à gauche et à droite. L'axe croisé est vertical ; perpendiculaire à l'axe principal. Les extrémités croisée et croisée sont respectivement en haut et en bas. La longueur de l'élément flexible le long de l'axe principal, dans ce cas, la largeur, est appelée la taille principale, et la longueur de l'élément flexible le long de l'axe croisé, dans ce cas, la hauteur, est appelée la taille croisée.

  • L'axe principal est l'axe de la direction dans laquelle sont disposés les éléments flexibles (par exemple, horizontalement sur la page, ou verticalement de haut en bas de la page). Le début et la fin de cet axe sont appelés l'origine principale et la fin principale. La longueur d'un élément flexible le long de l'axe principal est la taille principale.
  • L'axe croisé est l'axe perpendiculaire à l'axe principal, c'est-à-dire à la direction dans laquelle sont disposés les éléments flexibles. Le début et la fin de cet axe sont appelés le début croisé et la fin croisée. La longueur d'un élément flexible le long de l'axe croisé est la taille croisée.
  • L'élément parent dont la propriété est display: flex (<section> dans notre exemple) est appelé le conteneur flexible.
  • Les éléments disposés en tant que boîtes flexibles à l'intérieur du conteneur flexible sont appelés éléments flexibles (les éléments HTML <article> dans notre exemple).

Gardez cette terminologie en tête en lisant les paragraphes suivants. Vous pouvez toujours vous y référer si vous avez un doute sur la signification des termes utilisés.

Colonnes ou lignes ?

Flexbox dispose de la propriété flex-direction pour indiquer la direction de l'axe principal (direction dans laquelle les enfants flexibles sont disposés). Cette propriété est égale par défaut à row : ils sont donc disposés en incise, dans le sens de lecture de la langue par défaut du navigateur (de gauche à droite, dans le cas d'un navigateur français).

Ajoutez la déclaration suivante dans la règle CSS pour l'élément <section> :

css
flex-direction: column;

Cela dispose de nouveau les éléments en colonnes, comme c'était le cas avant l'ajout de la CSS. Avant de poursuivre, enlevez cette déclaration de l'exemple.

Note : Vous pouvez aussi disposer les éléments flexibles dans la direction inverse avec les valeurs row-reverse et column-reverse. Expérimentez ces valeurs aussi !

Enveloppement

Un problème qui survient lorsque vous avez une largeur ou une hauteur fixe dans votre mise en page est que, tôt ou tard, les enfants flexibles vont déborder de leur conteneur, cassant ainsi la mise en page. Dans l'exemple suivant, nous avons 5 éléments HTML <article>, qui ne tiennent pas, car ils ont une min-width de 400px, ce qui provoque une barre de défilement horizontale.

Ici, nous voyons que les enfants débordent effectivement de leur conteneur. Par défaut, le navigateur tente de placer tous les éléments flexibles sur une seule ligne si flex-direction vaut row, ou sur une seule colonne si flex-direction vaut column.

Une façon d'y remédier est d'ajouter la déclaration suivante à votre règle pour <section> :

css
section {
  flex-wrap: wrap;
}

Vous voyez que la disposition est bien meilleure avec cet ajout :

Nous avons maintenant plusieurs lignes. Chaque ligne contient autant d'enfants flexibles qu'il est raisonnable d'y placer. Tout débordement est déplacé sur la ligne suivante.

Mais nous pouvons aller plus loin ici. Pour commencer, essayez de changer la valeur de la propriété CSS flex-direction en row-reverse. Vous voyez alors que vous avez toujours une disposition sur plusieurs lignes, mais qu'elle commence dans l'angle opposé de la fenêtre du navigateur et se déroule à l'envers.

Forme abrégée flex-flow

Notez maintenant qu'il y a une forme abrégée pour flex-direction et flex-wrapflex-flow. Ainsi, par exemple, vous pouvez remplacer :

css
flex-direction: row;
flex-wrap: wrap;

par :

css
flex-flow: row wrap;

Taille modulable des éléments flex

Revenons maintenant à notre premier exemple et voyons comment nous pouvons contrôler la proportion d'espace que chaque élément flexible occupe par rapport aux autres éléments flexibles.

Ajoutez d'abord la règle ci-dessous en fin de la CSS :

css
article {
  flex: 1;
}

Il s'agit d'une valeur de proportion, sans unité, définissant la quantité d'espace disponible que chaque élément flexible prend le long de l'axe principal. Dans ce cas, nous donnons à chaque élément HTML <article> une valeur de 1, ce qui signifie qu'ils prennent tous une portion égale de l'espace libre après le calcul du remplissage et de la marge. Cette valeur représente une proportion, c'est-à-dire que le fait de donner une valeur de 400 000 simultanément à tous les éléments flexibles a exactement le même effet.

Maintenant ajoutons cette règle en dessous de la précédente :

css
article:nth-of-type(3) {
  flex: 2;
}

Maintenant, lorsque vous actualisez, vous voyez que le troisième <article> occupe deux fois plus de largeur disponible que chacun des deux autres — il y a maintenant quatre unités de division disponibles au total (puisque 1 + 1 + 2 = 4). Les deux premiers éléments flexibles en occupent chacun un, soit 1/4 de l'espace disponible pour chacun. Le troisième remplit deux unités, soit 2/4 (la moitié) de l'espace disponible.

Vous pouvez également définir une valeur minimale de taille dans la valeur flex. Modifiez comme suit vos règles article existantes :

css
article {
  flex: 1 100px;
}

article:nth-of-type(3) {
  flex: 2 100px;
}

En gros, cela dit : « Chaque élément flexible reçoit d'abord 200px de l'espace disponible. Ensuite, le reste de l'espace disponible est réparti selon les unités de proportion ». Actualisez et vous devez voir une différence dans la façon dont l'espace est réparti.

Tous les éléments flexibles ont une largeur minimale de 100 pixels — définie avec flex. La valeur de flex pour les deux premiers éléments flexibles est 1 et pour le troisième élément, elle est de 2. Cela divise l'espace restant dans le conteneur flexible en 4 unités de proportion. Une unité est attribuée à chacun des deux premiers éléments flexibles, et 2 unités sont attribuées au troisième élément flexible, ce qui rend ce dernier plus large que les deux autres, qui ont la même largeur.

Le véritable intérêt de Flexbox apparaît dans sa souplesse et sa réactivité — si vous redimensionnez la fenêtre du navigateur ou ajoutez un autre élément <article>, la mise en page continue de fonctionner correctement.

flex : forme abrégée et forme longue

flex est une forme abrégée de propriété qui peut servir à définir trois valeurs différentes :

  • Une valeur de proportion sans unité, vue ci‑dessus. Elle peut être précisée seule avec la forme longue de la propriété flex-grow ;
  • Une deuxième valeur de proportion sans unité, flex-shrink, intervenant quand les éléments flexibles débordent du conteneur. Elle indique la quantité de dépassement à retirer de l'extension de chacun des éléments flexibles pour les empêcher de déborder du conteneur. Il s'agit d'une fonctionnalité avancée de Flexbox — nous n'en parlons plus dans cet article ;
  • Une valeur de taille minimale, vue ci‑dessus. Elle peut aussi être précisée seule avec la forme longue de la propriété flex-basis.

Nous vous déconseillons d'utiliser les propriétés flexibles sous leur forme longue, sans autre alternative possible (par exemple, pour annuler quelque chose déjà défini). Elles représentent du code supplémentaire et peuvent être quelque peu déroutantes.

Alignement horizontal et vertical

Vous pouvez également utiliser les fonctionnalités de Flexbox pour aligner les éléments flexibles le long de l'axe principal ou de l'axe croisé. Explorons cela à l'aide d'un nouvel exemple :

html
<div>
  <button>Sourire</button>
  <button>Rire</button>
  <button>Cligner de l'œil</button>
  <button>Hausser les épaules</button>
  <button>Rougir</button>
</div>
css
body {
  font-family: sans-serif;
  width: 90%;
  max-width: 960px;
  margin: 10px auto;
}
div {
  height: 100px;
  border: 1px solid black;
}
button {
  font-size: 18px;
  line-height: 1.5;
  width: 15%;
}
/* Ajoutez votre CSS de boîte flexible ci-dessous */

Nous allons transformer ceci en une barre de boutons souple et bien présentée. Pour l'instant, vous voyez une barre de menu horizontale avec quelques boutons tassés dans le coin supérieur gauche.

D'abord, faites une copie locale de cet exemple.

Ensuite, ajoutez ce qui suit à la fin de la CSS de l'exemple :

css
div {
  display: flex;
  align-items: center;
  justify-content: space-around;
}

Actualisez la page et vous voyez que les boutons sont maintenant bien centrés, horizontalement et verticalement. Cette transformation a été opérée grâce à deux nouvelles propriétés.

La propriété align-items fixe là où les éléments flexibles sont placés sur l'axe perpendiculaire, dit aussi croisé (cross axis).

  • Par défaut, la valeur est stretch, qui étire tous les éléments flexibles de manière à emplir le conteneur parent le long de l'axe croisé. Si le parent ne possède pas de dimension définie dans la direction de l'axe croisé, alors tous les éléments flexibles ont la dimension du plus étiré des éléments. C'est pour cette raison que, dans notre premier exemple, les colonnes ont toutes la même hauteur par défaut.
  • Avec la valeur center utilisée dans le code ci-dessus, les éléments gardent leur dimension intrinsèque, tout en étant centrés sur l'axe croisé. C'est la raison pour laquelle, dans l'exemple actuel, les boutons sont centrés verticalement.
  • Il y a également des valeurs comme flex-start et flex-end qui alignent respectivement tous les éléments au début ou à la fin de l'axe croisé. Voyez align-items pour tous les détails.

Vous pouvez prendre le pas sur le comportement de align-items pour un élément flexible donné en lui appliquant la propriété align-self. Par exemple, ajoutez ce qui suit aux CSS :

css
button:first-child {
  align-self: flex-end;
}

Observez l'effet produit, puis retirez cette règle une fois que vous avez terminé.

La propriété justify-content contrôle l'emplacement des éléments flexibles sur l'axe principal.

  • La valeur par défaut est normal, qui se comporte comme start : tous les éléments sont placés au début de l'axe principal.
  • Vous pouvez utiliser end ou flex-end pour les placer à la fin.
  • Les valeurs left et right se comportent comme start ou end selon la direction du mode d'écriture.
  • center est aussi une valeur pour justify-content : elle place les éléments flexibles au centre de l'axe principal.
  • La valeur utilisée ci-dessus, space-around, est pratique : elle répartit tous les éléments de façon régulière le long de l'axe principal, en laissant un peu d'espace à chaque extrémité.
  • Il existe une autre valeur, space-between, très similaire à space-around, sauf qu'elle ne laisse aucun espace aux extrémités.

La propriété justify-items est ignorée dans les mises en page de boîte flexible.

N'hésitez pas à jouer avec ces valeurs pour visualiser leur fonctionnement avant de poursuivre.

Ordonner les éléments flexibles

Flexbox dispose aussi d'une fonctionnalité pour modifier l'ordre d'affichage des éléments flexibles, sans en modifier l'ordre dans la source. C'est une chose impossible à réaliser avec les méthodes classiques de mise en page.

Le code pour ce faire est simple — ajoutez la règle CSS suivante dans l'exemple de code de la barre de boutons :

css
button:first-child {
  order: 1;
}

Actualisez, et vous pouvez voir que le bouton « Sourire » a été déplacé en fin de l'axe principal. Voyons en détail comment cela fonctionne :

  • Par défaut, tous les éléments flexibles possèdent une valeur de order égale à 0 ;
  • Les éléments flexibles avec des valeurs order plus élevées apparaissent plus tard dans l'ordre d'affichage que ceux avec des valeurs plus faibles ;
  • Les éléments flexibles avec les mêmes valeurs pour order sont affichés dans l'ordre de la source. Ainsi, si vous avez 4 éléments avec des valeurs order de 2, 1, 1 et 0, leur ordre d'affichage est 4e, 2e, 3e et 1er ;
  • Le troisième élément suit le deuxième, car il a la même valeur pour order et qu'il est placé après dans le code source.

Vous pouvez donner des valeurs négatives à order pour faire en sorte que ces éléments soient affichés avant les éléments d'ordre 0. Par exemple, vous pouvez faire apparaître le bouton « Rougir » en tête de l'axe principal avec la règle suivante :

css
button:last-child {
  order: -1;
}

Lorsqu'il est possible de changer l'ordre à l'aide de order, l'ordre de tabulation reste le même que l'ordre du code. Changer l'ordre des éléments sélectionnables peut avoir un impact négatif sur l'utilisabilité pour vos utilisateur·ice·s de clavier !

Boîtes flexibles imbriquées

Il est possible de créer des mises en page assez complexes avec les boîtes flexibles. Il est tout à fait correct de faire d'un élément flexible un conteneur flexible, afin que ses enfants soient aussi disposés comme des boîtes flexibles.

Le HTML pour cela est vraiment simple. Voici un élément HTML <section> contenant trois éléments HTML <article>. Le troisième élément HTML <article> contient trois éléments HTML <div>, et le premier élément HTML <div> contient cinq éléments HTML <button> :

section - article
          article
          article - div - button
                    div   button
                    div   button
                          button
                          button

Regardez le code utilisé pour cette disposition.

Premièrement, nous déterminons que les enfants de l'élément HTML <section> sont des boîtes flexibles.

css
section {
  display: flex;
}

Ensuite, nous définissons des valeurs flexibles pour les éléments HTML <article> eux‑mêmes. Remarquez en particulier ici la deuxième règle — nous paramétrons le troisième élément HTML <article> pour que ses enfants soient eux-mêmes disposés en tant qu'éléments flexibles, mais cette fois‑ci en colonne.

css
article {
  flex: 1 200px;
}

article:nth-of-type(3) {
  flex: 3 200px;
  display: flex;
  flex-flow: column;
}

Après, nous sélectionnons le premier élément HTML <div> et lui assignons la valeur flex: 1 100px; pour qu'il ait effectivement une hauteur minimale de 100px. Ensuite, nous indiquons que ses enfants (les éléments HTML <button>) doivent être disposés en tant qu'éléments flexibles dans une ligne enveloppante, centrés dans l'espace disponible comme dans l'exemple des boutons vu plus haut.

css
article:nth-of-type(3) div:first-child {
  flex: 1 100px;
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  justify-content: space-around;
}

Enfin, nous définissons un dimensionnement des boutons, et plus précisément nous leur donnons une valeur flexible de 1 auto. L'effet obtenu est très intéressant ; vous l'observez en modifiant la largeur de la fenêtre du navigateur. Les boutons prennent autant d'espace qu'il leur est permis et sont, si possible, disposés sur la même ligne ; sinon ils « descendent » pour créer de nouvelles lignes.

css
button {
  flex: 1 auto;
  margin: 5px;
  font-size: 18px;
  line-height: 1.5;
}

Résumé

Notre visite guidée des bases de Flexbox est maintenant terminée. Espérons que vous en êtes satisfaits, et que vous savez jouer avec ses fonctionnalités tout en progressant dans l'apprentissage. Nous allons examiner ensuite un autre aspect important de la mise en page avec les CSS — les grilles CSS.

Voir aussi