The CSS Podcast - 010: Flexbox
Un modèle de conception qui peut être délicat dans le responsive design est une barre latérale qui est alignée avec certains contenus. Lorsque l'espace de la fenêtre d'affichage est suffisant, ce modèle fonctionne parfaitement, mais lorsque l'espace est réduit, cette mise en page rigide peut poser problème.
Flexbox est un modèle de mise en page conçu pour les contenus unidimensionnels. Il excelle à prendre un ensemble d'éléments de différentes tailles et à renvoyer la meilleure mise en page pour ces éléments.
Il s'agit du modèle de mise en page idéal pour ce modèle de barre latérale. Flexbox permet non seulement de disposer la barre latérale et le contenu de façon intégrée, mais aussi lorsqu'il ne reste pas assez d'espace disponible, la barre latérale s'affiche sur une nouvelle ligne. Au lieu de définir des dimensions rigides que le navigateur doit suivre, vous pouvez indiquer des limites flexibles afin d'indiquer comment le contenu pourrait s'afficher avec Flexbox.
À quoi sert une mise en page flexible ?
Les mises en page Flex présentent les fonctionnalités suivantes, que vous pourrez découvrir dans ce guide.
- Elles peuvent s'afficher sous forme de ligne ou de colonne.
- Elles respectent le mode d'écriture du document.
- Elles sont une seule ligne par défaut, mais vous pouvez demander à encapsuler sur plusieurs lignes.
- Les éléments de la mise en page peuvent être réorganisés visuellement, indépendamment de leur ordre dans le DOM.
- L'espace peut être distribué à l'intérieur des éléments, de sorte qu'ils deviennent plus grands ou plus petits en fonction de l'espace disponible dans leur parent.
- L'espace peut être réparti autour des éléments et des lignes flexibles dans une mise en page encapsulée à l'aide des propriétés d'alignement de boîte.
- Les éléments eux-mêmes peuvent être alignés sur l'axe transversal.
Axe principal et axe transversal
Pour comprendre Flexbox, il est essentiel de comprendre le concept d'axe principal et d'axe transversal.
L'axe principal est celui défini par votre propriété flex-direction
.
Si c'est row
, votre axe principal se trouve le long de la ligne. S'il est column
, votre axe principal se trouve le long de la colonne.
Les éléments Flex se déplacent en groupe sur l'axe principal. N'oubliez pas que nous avons un tas de choses et que nous essayons de trouver la meilleure mise en page pour elles en groupe.
L'axe transversal s'étend dans l'autre sens par rapport à l'axe principal. Par conséquent, si flex-direction
est défini sur row
, l'axe transversal court le long de la colonne.
Vous pouvez effectuer deux actions sur l'axe transversal.
Vous pouvez déplacer les éléments individuellement ou en groupe afin qu'ils s'alignent les uns sur les autres et sur le conteneur flex. De plus, si vous avez enroulé des lignes flex, vous pouvez les traiter comme un groupe pour contrôler l'espace qui leur est attribué.
Vous verrez comment tout cela fonctionne dans la pratique tout au long de ce guide. Pour l'instant, gardez à l'esprit que l'axe principal suit votre flex-direction
.
Créer un conteneur flex
Voyons comment flexbox se comporte en prenant un groupe d'éléments de différentes tailles et en utilisant flexbox pour les mettre en page.
<div class="container" id="container">
<div>One</div>
<div>Item two</div>
<div>The item we will refer to as three</div>
</div>
Pour utiliser Flexbox, vous devez déclarer que vous souhaitez utiliser un contexte de mise en forme flex et non une mise en page en ligne et en bloc standard.
Pour ce faire, remplacez la valeur de la propriété display
par flex
.
.container {
display: flex;
}
Comme vous l'avez appris dans le guide de mise en page, cela vous donne une zone au niveau du bloc, avec des enfants d'éléments flex. Les éléments flex commencent immédiatement à présenter un comportement de flexbox, en utilisant leurs valeurs initiales.
Les valeurs initiales signifient que :
- Les éléments s'affichent sur une ligne.
- Elles ne s'enroulent pas.
- Elles ne se développent pas pour remplir le conteneur.
- Elles s'alignent au début du conteneur.
Contrôler l'orientation des éléments
Même si vous n'avez pas encore ajouté de propriété flex-direction
, les éléments s'affichent sous forme de ligne, car la valeur initiale de flex-direction
est row
.
Si vous souhaitez une ligne, vous n'avez pas besoin d'ajouter la propriété.
Pour modifier la direction, ajoutez la propriété et l'une des quatre valeurs suivantes :
row
: les éléments sont disposés en ligne.- Avec
row-reverse:
, les éléments sont disposés sur une ligne à partir de l'extrémité du conteneur flexible. column
: les éléments sont disposés en colonne.column-reverse
: les éléments sont disposés en colonne à partir de la fin du conteneur Flex.
Vous pouvez essayer toutes les valeurs à l'aide de notre groupe d'articles dans la démonstration ci-dessous.
Inverser le flux d'éléments et l'accessibilité
Vous devez faire preuve de prudence lorsque vous utilisez des propriétés qui réorganisent l'affichage visuel de manière différente de l'ordre dans le document HTML, car cela peut avoir un impact négatif sur l'accessibilité.
Les valeurs row-reverse
et column-reverse
en sont un bon exemple.
La réorganisation ne se produit que pour l'ordre visuel, pas pour l'ordre logique.
Il est important de comprendre cela, car c'est l'ordre logique que suivra un lecteur d'écran pour lire le contenu et que toute personne qui navigue à l'aide du clavier suivra.
La vidéo suivante montre comment, dans une mise en page en lignes inversées, la navigation par tabulation entre les liens est interrompue, car la navigation au clavier suit le DOM et non l'affichage visuel.
Tout élément pouvant modifier l'ordre des éléments dans une grille ou une flexbox peut entraîner ce problème. Par conséquent, toute réorganisation doit inclure des tests approfondis pour vérifier qu'elle ne rendra pas l'utilisation de votre site difficile pour certaines personnes.
Pour en savoir plus, consultez cette page :
Modes et orientation d'écriture
Par défaut, les éléments Flex sont disposés sur une ligne. Une ligne s'affiche dans le sens de la lecture des phrases dans votre mode d'écriture et le sens du script. Cela signifie que si vous travaillez en arabe, avec un script de droite à gauche (RTL), les éléments seront alignés à droite. L'ordre de tabulation commencerait également à droite, car c'est ainsi que les phrases sont lues en arabe.
Si vous utilisez un mode d'écriture vertical, comme certaines polices japonaises, une ligne s'affiche verticalement, de haut en bas.
Essayez de modifier le flex-direction
dans cette démonstration qui utilise un mode d'écriture vertical.
Par conséquent, le comportement par défaut des éléments Flex est lié au mode d'écriture du document. La plupart des tutoriels sont rédigés en anglais ou dans une autre langue s'écrivant de gauche à droite. Il serait ainsi facile de supposer que les éléments Flex sont alignés à gauche et s'exécutent horizontalement.
Avec l'axe principal et l'axe transversal, ainsi que le mode d'écriture à prendre en compte, il peut être plus facile de comprendre que nous parlons de début et de fin plutôt que de haut, de bas, de gauche et de droite dans flexbox. Chaque axe a un début et une fin. Le début de l'axe principal est appelé main-start. Nos éléments Flex s'alignent donc initialement à partir de "main-start". La fin de cet axe est main-end. Le début de l'axe transversal est cross-start et l'extrémité cross-end.
Encapsuler des éléments flex
La valeur initiale de la propriété flex-wrap
est nowrap
.
Cela signifie que si l'espace dans le conteneur est insuffisant, les éléments déborderont.
Les éléments affichés à l'aide des valeurs initiales seront réduits au maximum, jusqu'à la taille min-content
avant le débordement.
Pour que les éléments soient mis en ligne, ajoutez flex-wrap: wrap
au conteneur flex.
.container {
display: flex;
flex-wrap: wrap;
}
Lorsqu'un conteneur flex est encapsulé, il crée plusieurs lignes flex. En termes de distribution de l'espace, chaque ligne agit comme un nouveau conteneur flex. Par conséquent, si vous encapsulez des lignes, il n'est pas possible d'aligner un élément de la ligne 2 avec un élément situé au-dessus dans la ligne 1. C'est ce que l'on entend par "flexbox unidimensionnel". Vous pouvez contrôler l'alignement sur une seule des axes, une ligne ou une colonne, et non les deux à la fois comme vous pouvez le faire dans une grille.
Raccourci flex-flow
Vous pouvez définir les propriétés flex-direction
et flex-wrap
à l'aide de l'abréviation flex-flow
.
Par exemple, pour définir flex-direction
sur column
et permettre le retour à la ligne des éléments :
.container {
display: flex;
flex-flow: column wrap;
}
Contrôler l'espace dans les éléments Flex
En supposant que notre conteneur dispose de plus d'espace que nécessaire pour afficher les éléments, ceux-ci sont alignés au début et ne s'agrandissent pas pour occuper l'espace.
Ils cessent de croître à la taille maximale de leur contenu.
En effet, la valeur initiale des propriétés flex-
est la suivante:
flex-grow: 0
: les éléments ne se développent pas.flex-shrink: 1
: les éléments peuvent être réduits à une taille inférieure à leurflex-basis
.flex-basis: auto
: la taille de base des éléments estauto
.
Cela peut être représenté par une valeur de mot clé flex: initial
.
La propriété abrégée flex
ou les valeurs longues de flex-grow
, flex-shrink
et flex-basis
sont appliquées aux enfants du conteneur flex.
Pour que les éléments se développent, tout en permettant aux éléments volumineux d'avoir plus d'espace que les petits, utilisez flex:auto
.
Vous pouvez essayer cela à l'aide de la démonstration ci-dessus.
Cela définit les propriétés sur:
flex-grow: 1
: les éléments peuvent être plus grands que leurflex-basis
.flex-shrink: 1
: les éléments peuvent être réduits à une taille inférieure à leurflex-basis
.flex-basis: auto
: la taille de base des éléments estauto
.
L'utilisation de flex: auto
signifie que les éléments se retrouvent des tailles différentes, car l'espace partagé entre les éléments est partagé après que chaque élément a été défini en tant que taille maximale du contenu.
Un article volumineux gagnera donc plus d'espace.
Pour forcer tous les éléments à avoir une taille cohérente et ignorer la taille du contenu, remplacez flex:auto
par flex: 1
dans la démonstration.
Cette opération se décompose comme suit :
flex-grow: 1
: les éléments peuvent être plus grands que leurflex-basis
.flex-shrink: 1
: les éléments peuvent être réduits à une taille inférieure à leurflex-basis
.flex-basis: 0
: la taille de base des éléments est0
.
L'utilisation de flex: 1
indique que tous les éléments ont une taille nulle. Par conséquent, tout l'espace du conteneur Flex peut être distribué.
Étant donné que tous les éléments ont un facteur flex-grow
de 1
, ils se développent tous de manière égale et l'espace est partagé de manière égale.
Permettre une croissance des éléments à des rythmes différents
Il n'est pas nécessaire de définir un facteur flex-grow
de 1
pour tous les éléments.
Vous pouvez définir différents facteurs flex-grow
pour vos articles modulables.
Dans la démonstration ci-dessous, le premier élément comporte flex: 1
, le deuxième flex: 2
et le troisième flex: 3
.
À mesure que ces éléments passent de 0
, l'espace disponible dans le conteneur Flex est divisé en six.
Une partie est attribuée au premier élément, deux au deuxième et trois au troisième.
Vous pouvez faire la même chose à partir d'un flex-basis
de auto
, mais vous devrez spécifier les trois valeurs.
La première valeur étant flex-grow
, la deuxième flex-shrink
et la troisième flex-basis
.
.item1 {
flex: 1 1 auto;
}
.item2 {
flex: 2 1 auto;
}
Ce cas d'utilisation est moins courant, car une flex-basis
de auto
permet au navigateur de déterminer la répartition de l'espace.
Toutefois, si vous souhaitez que l'algorithme fasse croître un élément un peu plus que ce qu'il décide, cela peut être utile.
Réorganisation d'articles flexibles
Vous pouvez réorganiser les éléments de votre conteneur flex à l'aide de la propriété order
.
Cette propriété permet d'organiser les éléments en groupes ordonnés.
Les éléments sont disposés dans la direction dictée par flex-direction
, les valeurs les plus basses en premier.
Si plusieurs éléments ont la même valeur, ils s'affichent ensemble.
L'exemple ci-dessous illustre ce tri.
Vérifier vos connaissances
Tester vos connaissances sur Flexbox
La valeur flex-direction
par défaut est
row
column
Par défaut, un conteneur Flex encapsule les enfants.
flex-wrap: wrap
avec display: flex
pour encapsuler les enfantsUn élément enfant flex semble écrasé. Quelle propriété flex permet de l'atténuer ?
flex-grow
flex-shrink
flex-basis
Présentation de l'alignement Flexbox
Flexbox a apporté un ensemble de propriétés permettant d'aligner les éléments et de répartir l'espace entre eux. Ces propriétés étaient si utiles qu'elles ont depuis été déplacées vers leur propre spécification. Vous les trouverez également dans la mise en page en grille. Découvrez ici comment ils fonctionnent lorsque vous utilisez Flexbox.
L'ensemble des établissements peut être placé dans deux groupes. Propriétés de distribution de l'espace et propriétés d'alignement. Les propriétés qui distribuent l'espace sont les suivantes :
justify-content
: distribution de l'espace sur l'axe principal.align-content
: distribution de l'espace sur l'axe transversal.place-content
: raccourci permettant de définir les deux propriétés ci-dessus.
Propriétés utilisées pour l'alignement dans Flexbox :
align-self
: aligne un seul élément sur l'axe transversal.align-items
: aligne tous les éléments en tant que groupe sur l'axe transversal.
Si vous travaillez sur l'axe principal, les propriétés commencent par justify-
.
Sur l'axe transversal, ils commencent par align-
.
Répartition de l'espace sur l'axe principal
Avec le code HTML utilisé précédemment, les éléments Flex disposés en ligne, il y a de l'espace sur l'axe principal.
Les articles ne sont pas assez grands pour remplir complètement le conteneur flexible.
Les éléments sont alignés au début du conteneur flexible, car la valeur initiale de justify-content
est flex-start
.
Les éléments sont alignés au début, et les espaces supplémentaires se trouvent à la fin.
Ajoutez la propriété justify-content
au conteneur flexible et attribuez-lui la valeur flex-end
. Les éléments sont alignés à la fin du conteneur et l'espace libre est placé au début.
.container {
display: flex;
justify-content: flex-end;
}
Vous pouvez également répartir l'espace entre les éléments à l'aide de justify-content: space-between
.
Essayez certaines des valeurs de la démonstration et consultez la documentation MDN pour obtenir l'ensemble complet des valeurs possibles.
Avec flex-direction: column
Si vous avez remplacé votre flex-direction
par column
, justify-content
fonctionnera sur la colonne.
Pour disposer d'espace supplémentaire dans votre conteneur lorsque vous travaillez en tant que colonne, vous devez attribuer à votre conteneur un height
ou un block-size
.
Sinon, vous n'aurez pas d'espace libre à distribuer.
Essayez les différentes valeurs, cette fois avec une mise en page en colonnes flexbox.
Répartir l'espace entre les lignes flexibles
Avec un conteneur flex enveloppé, vous pouvez avoir de l'espace à distribuer sur l'axe transversal.
Dans ce cas, vous pouvez utiliser la propriété align-content
avec les mêmes valeurs que justify-content
.
Contrairement à justify-content
, qui aligne les éléments sur flex-start
par défaut, la valeur initiale de align-content
est stretch
.
Ajoutez la propriété align-content
au conteneur flex pour modifier ce comportement par défaut.
.container {
align-content: center;
}
Essayez-le dans la démonstration.
L'exemple comporte des lignes de retour à la ligne d'éléments Flex, et le conteneur comporte un block-size
afin de disposer d'espace supplémentaire.
Le raccourci place-content
Pour définir à la fois justify-content
et align-content
, vous pouvez utiliser place-content
avec une ou deux valeurs.
Une seule valeur sera utilisée pour les deux axes. Si vous spécifiez les deux, la première est utilisée pour align-content
et la seconde pour justify-content
.
.container {
place-content: space-between;
/* sets both to space-between */
}
.container {
place-content: center flex-end;
/* wrapped lines on the cross axis are centered,
on the main axis items are aligned to the end of the flex container */
}
Aligner des éléments sur l'axe transversal
Sur l'axe transversal, vous pouvez également aligner vos éléments dans la ligne flex à l'aide de align-items
et align-self
.
L'espace disponible pour cet alignement dépend de la hauteur du conteneur Flex ou de la ligne Flex dans le cas d'un ensemble d'éléments en ligne.
La valeur initiale de align-self
est stretch
. C'est pourquoi les éléments flex d'une ligne s'étendent jusqu'à la hauteur de l'élément le plus haut par défaut.
Pour modifier cela, ajoutez la propriété align-self
à l'un de vos éléments flex.
.container {
display: flex;
}
.item1 {
align-self: flex-start;
}
Utilisez l'une des valeurs suivantes pour aligner l'élément :
flex-start
flex-end
center
stretch
baseline
Consultez la liste complète des valeurs sur MDN.
La démonstration suivante comporte une seule ligne d'éléments flexibles avec flex-direction: row
.
Le dernier élément définit la hauteur du conteneur flex.
Le premier élément possède la propriété align-self
avec une valeur de flex-start
.
Essayez de modifier la valeur de cette propriété pour voir comment elle se déplace dans son espace sur l'axe transversal.
La propriété align-self
s'applique à des éléments individuels.
La propriété align-items
peut être appliquée au conteneur flex pour définir toutes les propriétés align-self
individuelles en tant que groupe.
.container {
display: flex;
align-items: flex-start;
}
Dans cette démonstration suivante, essayez de modifier la valeur de align-items
pour aligner tous les éléments de l'axe transversal en tant que groupe.
Pourquoi n'y a-t-il pas de justification dans Flexbox ?
Les éléments Flex agissent comme un groupe sur l'axe principal. Il n'est donc pas possible de séparer un élément individuel de ce groupe.
Dans la mise en page en grille, les propriétés justify-self
et justify-items
fonctionnent sur l'axe en ligne pour aligner les éléments sur cet axe dans leur zone de grille.
En raison de la façon dont les mises en page flex traitent les éléments en tant que groupe, ces propriétés ne sont pas implémentées dans un contexte flex.
Sachez que Flexbox fonctionne très bien avec les marges automatiques.
Si vous avez besoin de séparer un élément d'un groupe ou de séparer le groupe en deux groupes, vous pouvez appliquer une marge pour ce faire.
Dans l'exemple ci-dessous, la marge de gauche du dernier élément est de auto
.
La marge automatique absorbe tout l'espace dans la direction où elle est appliquée.
Cela signifie qu'il déplace l'élément vers la droite, ce qui divise les groupes.
Centrer un élément verticalement et horizontalement
Les propriétés d'alignement peuvent être utilisées pour centrer un élément dans une autre zone.
La propriété justify-content
aligne l'élément sur l'axe principal, qui est la ligne. Propriété align-items
sur l'axe transversal.
.container {
width: 400px;
height: 300px;
display: flex;
justify-content: center;
align-items: center;
}
Testez vos connaissances
Tester vos connaissances sur Flexbox
.container { display: flex; direction: ltr; }
Pour aligner verticalement avec Flexbox, utilisez
.container { display: flex; direction: ltr; }
Pour aligner horizontalement avec Flexbox, utilisez
.container { display: flex; direction: ltr; }
Par défaut, les éléments Flex sont alignés sur stretch
. Si vous souhaitez utiliser la taille de contenu pour les éléments enfants, lequel des styles suivants utiliseriez-vous ?
justify-content: flex-start
align-content: start
content
aligne les lignes flex, et non l'alignement des éléments enfants.height: auto
align-items: flex-start
Ressources
- La page MDN CSS Flexible Box Layout comprend une série de guides détaillés avec des exemples.
- Guide d'astuces pour le Flexbox dans le CSS
- Que se passe-t-il lorsque vous créez un conteneur Flexbox ?
- Tout ce que vous devez savoir sur l'alignement dans Flexbox
- Quelle est la taille de cette boîte flexible ?
- Cas d'utilisation de Flexbox
- Inspecter et déboguer les mises en page CSS Flexbox dans les outils pour les développeurs Chrome