Que se passe-t-il quand on crée un Flexbox flex container?
Lorsque les gens trouvent Flexbox difficile ou déroutant, c'est souvent parce qu'ils essaient de l'utiliser comme Grid layout.
PETIT RÉSUMÉ: dans un monde idéal, CSS Grid et Flexbox seraient arrivés ensemble, déjà parfaits pour constituer à eux deux un système de layout pour le Web. Mais au lieu de cela, nous avons d’abord eu Flexbox et, comme il était bien meilleur que floats pour créer des dispositions de type grille, nous nous sommes retrouvés avec beaucoup de systèmes de grille basés sur Flexbox. En fait, lorsque les gens trouvent Flexbox difficile ou déroutant, c'est souvent parce qu'ils essaient de l'utiliser comme Grid layout.
Dans cette courte série d’articles, je vais passer un peu de temps à décomposer en détail Flexbox, comme je l’ai fait dans le passé avec Grid. Nous verrons ce pour quoi Flexbox a été conçu, ce qu'il fait vraiment bien et ce pourquoi il ne serait pas le meilleur choix de méthode de layout. Dans cet article, nous examinerons en détail ce qui se passe réellement lorsque vous ajoutez display: flex
à votre feuille de style.
Un conteneur Flex, s'il vous plaît!
Pour utiliser Flexbox, vous avez besoin d’un élément qui sera le conteneur flex. Dans votre CSS, vous utilisez display: flex
:
Prenons un peu de temps pour réfléchir à ce que display: flex
signifie vraiment. Dans le module CSS Display niveau 3, chaque valeur d'affichage est décrite comme une combinaison de deux choses : un modèle d'affichage interne et un modèle d'affichage externe. Lorsque nous ajoutons display: flex
, nous définissons en réalité display: block flex
. Le type d'affichage externe de notre conteneur flex est block
; il agit comme un élément de niveau bloc dans un flux normal. Le type d'affichage interne est flex
, ce qui aura pour effet que les éléments situés à l'intérieur de notre conteneur participeront au layout flex.
C’est une chose à laquelle vous n’auriez peut-être jamais vraiment pensé mais que vous comprenez probablement de toute façon : Le conteneur flex se comporte lui-même comme n'importe quel autre bloc de votre page. Si vous avez un paragraphe suivi d'un conteneur flex, les deux se comportent comme les éléments de niveau bloc auxquels sommes habitués.
Nous pouvons également définir notre conteneur avec une valeur de inline-flex
, ce qui revient à utiliser display: inline flex
, c’est-à-dire un conteneur flex qui agit comme un élément de niveau inline
, avec des enfants participant au layout flex. Les enfants de notre conteneur inline flex se comportent de la même manière que les enfants de notre conteneur block flex. La différence réside dans la manière dont le conteneur lui-même se comporte dans la mise en page générale.
Il est très utile de raisonner à partir de ce concept d'éléments ayant d'une part un type d'affichage externe, définissant la manière dont ils se comportent en tant que boîte, et d'autre part un type d'affichage interne dictant le comportement de leurs enfants. Vous pouvez appliquer cette approche à n’importe quelle boîte CSS. Comment agit cet élément? Comment agissent les enfants de cet élément? Les réponses renvoient aux modèles d'affichage externe et interne.
Rangées ou colonnes ?
Une fois défini notre conteneur flex, certaines valeurs initiales doivent être précisées. Sans l'ajout de propriétés supplémentaires, les éléments flex s'affichent sous forme de rangée car la valeur initiale de la propriété flex-direction
est row
. Si vous ne le définissez pas, vous obtenez une rangée.
On utilise la propriété flex-direction
pour définir la direction de l'axe principal. Les autres valeurs de flex-direction
sont:
column
row-reverse
column-reverse
Si nos items (éléments individuels) sont sur une rangée, ils sont placés avec le premier au départ de la dimension inline et s'affichent dans l'ordre dans lequel ils apparaissent dans la source. Dans la spécification, ce point de départ est décrit comme le main-start
:
Si nous utilisons la valeur column
, les items s'affichent à partir du point de départ de la dimension block, et par conséquent forment une colonne.
Si nous utilisons row-reverse
, alors main-start
et main-end
sont inversés et les items s'affichent l'un après l'autre dans l'ordre inverse.
La valeur column-reverse
fait la même chose. Il est important de se rappeler que ces valeurs ne changent pas l’ordre des items, elles modifient simplement le point de départ du flux d’éléments: en basculant main-start
. Nos items s'affichent donc dans l'ordre inverse, mais c'est parce qu'ils commencent à se placer à l'autre bout du conteneur.
L'effet est purement visuel. Nous demandons aux items de s'afficher eux-mêmes en commençant par l'autre côté mais ils circulent toujours dans le même ordre, celui utilisé par votre lecteur d'écran, qui est aussi celui de tabulation. Par conséquent, il est important de ne jamais utiliser row-reverse
lorsque vous voulez vraiment changer l'ordre des éléments. Faites ce changement dans votre document.
Les deux axes de Flexbox
Nous avons déjà exposé une caractéristique importante de Flexbox: la possibilité de basculer l’axe principal de rangée à colonne, qui peut sembler complexe. Il est souvent plus facile de comprendre l’alignement dans Grid layout. Avec Grid, comme on travaille en deux dimensions, on peut aligner les deux axes à peu près de la même manière. Flexbox est un peu plus compliqué car différentes choses se produisent selon que vous travaillez avec l'axe principal ou avec l'axe transversal.
Nous avons déjà rencontré l’axe principal (main-axis), c’est-à-dire l’axe que vous définissez comme valeur de flex-direction
. L'axe transversal (cross-axis) est l'autre dimension. Si vous avez défini flex-direction: row
, votre axe principal est le long de la rangée et votre axe transversal descend le long de la colonne. Avec flex-direction: column
, l'axe principal suit la colonne et votre axe transversal le long des rangées. C’est ici que nous devons explorer une autre caractéristique importante de Flexbox, à savoir le fait qu’elle n’est pas liée aux dimensions physiques de l’écran. Nous ne parlons pas d’une ligne allant de gauche à droite, ni d’une colonne de haut en bas, car ce n’est pas toujours le cas.
Modes d'écriture
Lorsque j'ai décrit la rangée et la colonne, j'ai mentionné les dimensions block
et inline
. Cet article est écrit à l'origine en anglais, qui est un mode d'écriture horizontal. Cela signifie que lorsque vous demandez à Flexbox de vous donner une ligne, vous obtenez un affichage horizontal de vos éléments flexibles. Dans ce cas, main-start est à gauche - l'endroit où les phrases commencent en anglais.
Si je travaillais dans une langue écrite de droite à gauche telle que l'arabe, le bord de départ serait à droite:
Les valeurs initiales de flexbox signifient que si tout ce que je fais est de créer un conteneur flex, mes items partiront de la droite et s'afficheront en se déplaçant vers la gauche. Le point de départ dans la direction inline est l'endroit où les phrases commencent dans le mode d'écriture que vous utilisez.
Si vous vous trouvez en mode d'écriture verticale et demandez une rangée, celle-ci s'exécutera verticalement, car c'est ainsi que les rangées de texte s'affichent dans un langage vertical. Vous pouvez essayer ceci en ajoutant la propriété writing-mode
à votre conteneur flex et en lui attribuant la valeur vertical-lr
. Désormais, lorsque vous définissez flex-direction
sur row
, vous obtenez une colonne verticale d'éléments.
Ainsi, une rangée peut se dérouler horizontalement, avec un main-start
à gauche ou à droite, et verticalement avec un main-start
en haut. C’est toujours une flex-direction
de row
même si nos esprits habitués au texte horizontal ont du mal à penser une ligne qui court verticalement !
Pour que les éléments s'affichent dans la dimension block
, définissez la valeur de flex-direction
sur column
ou column-reverse
. En anglais (ou en arabe), nous voyons ensuite les éléments s’afficher de manière superposée jusqu'en bas de la page, en commençant par le sommet du conteneur.
Dans un mode d'écriture vertical, la dimension block
traverse la page, car il s'agit de la direction des blocs dans ces modes d'écriture. Si vous demandez une colonne dans vertical-lr
, vos blocs iront de gauche à droite verticalement:
Toutefois, quelle que soit la direction d'affichage des blocs, si vous travaillez avec une colonne, vous travaillez dans la dimension block
.
Pour comprendre la terminologie de Grid et Flexbox, il est utile de bien saisir qu'une rangée ou une colonne peut être exécutée dans différentes directions physiques. Nous ne faisons pas référence à "gauche et droite" ou "haut et bas" dans Flexbox et Grid car nous ne faisons aucune hypothèse quant au mode d’écriture de notre document. CSS est de plus en plus conscient des différences de mode écriture. Si vous êtes intéressés par d'autres propriétés et valeurs implémentées de la sorte en CSS, lisez mon article sur les propriétés et valeurs logiques.
En résumé, rappelez-vous que:
flex-direction : row
- axe principal = dimension inline
- main-start sera l'endroit où les phrases commencent dans ce mode d'écriture
- axe transversal = dimension block
flex-direction : column
- axe principal = dimension block
- main-start sera le point de départ des blocs dans ce mode d'écriture
- axe transversal = dimension inline
Alignement initial
D'autres choses se produisent lorsque nous utilisons display: flex
. Un alignement initial se produit. Dans un prochain article de cette série, nous examinerons en détail l’alignement, mais dans notre exploration de display: flex
, nous devrions déjà examiner les valeurs initiales appliquées.
Remarque: il est à noter que, bien que ces propriétés d'alignement trouvent leur origine dans la spécification Flexbox, elles seront à terme remplacées par la spécification BoxAlignement.
Alignement sur l'axe principal
La valeur initiale de justify-content
est flex-start
. Tout se passe comme si notre CSS était:
.container {
display: flex;
justify-content: flex-start;
}
C'est la raison pour laquelle nos items flex s'alignent au départ du conteneur flex. C’est aussi la raison pour laquelle, lorsque nous définissons row-reverse
, ils basculent de l'autre côté, qui devient alors le départ de l’axe principal.
Lorsque vous voyez une propriété d’alignement qui commence par justify-
, elle s’applique à l’axe principal de Flexbox. Donc justify-content
effectue l'alignement sur l'axe principal et aligne nos éléments au début.
Les autres valeurs possibles pour justify-content
sont :
flex-end
center
space-around
space-between
space-evenly
(ajouté dans Box Alignment)
Ces valeurs gèrent la distribution de l'espace disponible dans le conteneur flex, c'est ainsi que les éléments sont déplacés ou espacés. Par exemple, si vous ajoutez justify-content: space-between
, tout l'espace disponible est partagé entre les éléments. Cependant, cela ne peut se produire que s'il existe effectivement un espace libre. Si vous aviez un conteneur flex sans espace supplémentaire après que tous les items aient été disposés, alors justify-content
ne ferait rien du tout.
Vous pouvez le constater aisément si vous changez votre flex-direction
en column
. Si vous n'indiquez pas de hauteur sur le conteneur flex, il n’y aura pas d’espace libre entre les items, donc utiliser justify-content: space-between
n'aura aucun effet. Si vous ajoutez une hauteur et faites en sorte que le conteneur soit plus grand que ce qui est nécessaire pour afficher les éléments, alors la propriété aura un effet :
Alignement croisé
Les items sont également alignés sur l'axe transversal avec un conteneur flex à une seule ligne. Cela revient à aligner les boîtes les unes contre les autres sur la ligne. Dans l'exemple suivant, l'une de nos boîtes comporte plus de contenu que toutes les autres. Quelque chose dit aux autres cases de s’étirer à la même hauteur. Ce quelque chose est la propriété align-items
, qui a pour valeur initiale stretch
:
Lorsque vous voyez une propriété d'alignement qui commence par align-
et que vous êtes dans une flexbox, vous avez alors affaire à un alignement transversal et align-items
aligne les éléments dans la ligne de flex. Les autres valeurs possibles sont:
flex-start
flex-end
center
baseline
Si vous ne souhaitez pas que les hauteurs des boîtes soient toutes étirées pour correspondre à la plus haute, align-items: flex-start
les alignera toutes sur le bord supérieur de départ de l'axe transversal.
Valeurs initiales pour les éléments flex
Enfin, les éléments flex eux-mêmes ont également des valeurs initiales, elles sont définies sur:
flex-grow: 0
flex-shrink: 1
flex-basis: auto
Cela signifie que nos éléments ne s'agrandiront pas par défaut pour occuper l'espace disponible sur l'axe principal. Si flex-grow
avait une valeur positive, les éléments grandiraient et occuperaient tout l'espace disponible.
Les items peuvent être réduits, cependant, puisque flex-shrink
est défini sur la valeur positive de 1. Cela signifie que si nous avons un conteneur flex très étroit, les éléments seront aussi petits que possible avant tout débordement. C'est un comportement qui fait sens: en général, nous voulons que les choses restent à l'intérieur de leurs boîtes et ne débordent pas s'il y a assez d'espace pour les afficher.
Afin d'obtenir la meilleure mise en page possible par défaut, flex-basis
est réglé sur auto
. Nous verrons ce que cela signifie dans un futur article de cette série. Cependant, la plupart du temps, on peut voir auto
comme "assez grand pour correspondre au contenu". Lorsque des éléments flexibles remplissent le conteneur et que l’un de ces éléments a un contenu plus volumineux que les autres, l’élément le plus gros dispose de plus d’espace.
C’est la flexibilité de Flexbox en action. Avec une flex-basis
réglée sur auto
et aucun dimensionnement appliqué aux éléments, les items flexibles ont une taille de base égale à la taille max-content
. Ce serait la taille qu'ils auraient s'ils s'étendaient sans retour à la ligne. Ensuite, l’espace est pris à chaque item en proportion, comme indiqué dans la remarque suivante de la spécification flexbox.
Remarque: le facteur
flex-shrink
est multiplié par la taille de la base de flex lors de la répartition de l’espace négatif. Cela répartit l’espace négatif proportionnellement à la capacité de réduction de l’item, de sorte que, par exemple, un petit item ne sera pas réduit à zéro avant qu'un article plus grand ait été sensiblement réduit.
Le plus gros item a moins de place, nous obtenons donc la mise en page finale. Vous pouvez comparer les deux captures d'écran ci-dessous, toutes deux prises à partir de l'exemple précédent. Dans la première capture d'écran, la troisième zone a un contenu moins volumineux et, par conséquent, nos colonnes ont une distribution d'espace plus égale.
Flexbox nous aide ici à obtenir un résultat final raisonnable, sans autre intervention de la part de la personne qui écrit le CSS. Plutôt que de réduire l'espace de manière uniforme et de finir avec un élément très grand affichant péniblement quelques mots sur chaque ligne, il attribue à cet élément davantage d'espace. Ce type de comportement est la clé des cas d'utilisation réels de Flexbox. Flexbox est à son meilleur lorsqu'il est utilisé pour placer des ensembles d'éléments – le long d'un axe – de manière flexible et soucieuse du contenu. J'aborde un peu les détails ici, mais nous examinerons plus en détail ces algorithmes plus tard dans cette série.
Résumé
Dans cet article, je me suis intéressée aux valeurs initiales de Flexbox afin d’expliquer ce qui se passe réellement lorsque vous dites display: flex
. Il y en a un nombre surprenant et ces quelques propriétés contiennent de nombreuses caractéristiques-clés des layouts flex.
Les mises en page flex sont flexibles : elles essaient de faire de bons choix par défaut concernant votre contenu – réduire ou étirer pour obtenir la meilleure lisibilité. Les mises en page flex prennent en compte le mode d'écriture : les directions des rangées et des colonnes se rapportent au mode d'écriture utilisé. Les layout flex permettent l’alignement des éléments en tant que groupe sur l’axe principal, en choisissant la manière dont l’espace est réparti. Ils permettent l'alignement des éléments dans leur rangée flex, en les déplaçant sur l'axe transversal les uns par rapport aux autres. Il est important de noter que les mises en page flexibles comprennent la taille de votre contenu et tentent de prendre les bonnes décisions de base pour l'afficher. Dans les prochains articles, nous explorerons ces domaines plus en profondeur et nous examinerons plus précisément quand et pourquoi nous pourrions choisir d'utiliser Flexbox.