Flexbox : Quelle est la taille de cette boîte flexible ?
Publié: 2022-03-10Ceci est la troisième partie de ma série sur Flexbox. Dans les deux derniers articles, nous avons examiné ce qui se passe lorsque vous créez un conteneur flexible et exploré l'alignement tel qu'il fonctionne dans Flexbox. Cette fois, nous allons nous intéresser au dimensionnement. Comment contrôlons-nous la taille de nos éléments flexibles et quels choix le navigateur fait-il lorsqu'il contrôle la taille ?
Affichage initial des éléments flexibles
Si j'ai un ensemble d'éléments, qui ont des longueurs de contenu variables à l'intérieur, et que leur parent est défini sur display: flex
, les éléments s'afficheront sous forme de ligne et s'aligneront au début de cet axe. Dans l'exemple ci-dessous, mes trois éléments ont une petite quantité de contenu et sont capables d'afficher le contenu de chaque élément sous la forme d'une ligne ininterrompue. Il y a de l'espace à la fin du conteneur flexible dans lequel les éléments ne grandissent pas car la valeur initiale de flex-grow
est 0
, ne grandit pas .
Si j'ajoute plus de texte à ces éléments, ils finissent par remplir le conteneur et le texte commence à s'enrouler. Les boîtes se voient attribuer une partie de l'espace dans le conteneur qui correspond à la quantité de texte dans chaque boîte - un élément avec une chaîne de texte plus longue se voit attribuer plus d'espace. Cela signifie que nous ne nous retrouvons pas avec une grande colonne maigre avec beaucoup de texte lorsque l'élément voisin ne contient qu'un seul mot.
Ce comportement vous est probablement familier si vous avez déjà utilisé Flexbox, mais peut-être vous êtes-vous demandé comment le navigateur fonctionne avec ce dimensionnement, comme si vous regardiez dans plusieurs navigateurs modernes, vous verrez qu'ils font tous la même chose. Cela est dû au fait que des détails tels que celui-ci sont élaborés dans la spécification, garantissant que toute personne implémentant Flexbox dans un nouveau navigateur ou un autre agent utilisateur est consciente de la façon dont ce calcul est censé fonctionner. Nous pouvons utiliser la spécification pour trouver ces informations par nous-mêmes.
La spécification de dimensionnement CSS intrinsèque et extrinsèque
Vous découvrez assez rapidement en regardant quoi que ce soit sur le dimensionnement dans la spécification Flexbox, qu'une grande partie des informations dont vous avez besoin se trouve dans une autre spécification - CSS Intrisnic et Extrinsic Sizing. En effet, les concepts de dimensionnement que nous utilisons ne sont pas propres à Flexbox, de la même manière que les propriétés d'alignement ne sont pas propres à Flexbox. Cependant, pour savoir comment ces constructions de dimensionnement sont utilisées dans Flexbox, vous devez consulter la spécification Flexbox. Vous pouvez avoir l'impression de sauter d'avant en arrière, alors je vais résumer ici quelques définitions clés, que j'utiliserai dans le reste de l'article.
Taille préférée
La taille préférée d'une boîte est la taille définie par une width
ou une height
, ou les alias logiques pour ces propriétés inline-size
et block-size
. En utilisant:
.box { width: 500px; }
Ou l'alias logique inline-size
:
.box { inline-size: 500px; }
Vous indiquez que vous voulez que votre boîte ait une largeur de 500 pixels ou 500 pixels dans le sens de l'alignement.
Taille du contenu min
La taille min-content est la plus petite taille qu'une boîte peut avoir sans provoquer de débordement. Si votre boîte contient du texte, toutes les possibilités d'emballage souple seront prises.
Taille maximale du contenu
La taille max-content est la plus grande taille que la boîte peut avoir pour contenir le contenu. Si la zone contient du texte sans mise en forme pour le décomposer, elle s'affichera sous la forme d'une longue chaîne ininterrompue.
Taille principale de l'article flexible
La taille principale d'un élément flexible est la taille qu'il a dans la dimension principale. Si vous travaillez en ligne - en anglais - la taille principale est la largeur. Dans une colonne en anglais, la taille principale est la hauteur.
Les articles ont également une taille principale minimale et maximale définie par leur min-width
minimale ou leur min-height
minimale sur la dimension principale.
Déterminer la taille d'un élément flexible
Maintenant que nous avons défini certains termes, nous pouvons voir comment nos éléments flexibles sont dimensionnés. La valeur initiale des propriétés flex
est la suivante :
-
flex-grow: 0
-
flex-shrink: 1
-
flex-basis: auto
La flex-basis
est la chose à partir de laquelle le dimensionnement est calculé. Si nous définissons flex-basis
sur 0
et flex-grow
sur 1, toutes nos boîtes n'ont pas de largeur de départ, de sorte que l'espace dans le conteneur flex est partagé uniformément, en attribuant la même quantité d'espace à chaque élément.
Alors que si flex-basis
est auto
et flex-grow: 1
, seul l'espace disponible est distribué en tenant compte de la taille du contenu.
Dans les situations où il n'y a pas d'espace libre, par exemple lorsque nous avons plus de contenu que ne peut tenir sur une seule ligne, il n'y a pas d'espace à distribuer.
Cela nous montre que comprendre ce que signifie auto
est assez important si nous voulons savoir comment Flexbox calcule la taille de nos boîtes. La valeur de auto
va être notre point de départ.
Définition automatique
Lorsque auto est défini comme une valeur pour quelque chose dans CSS, il aura une signification très spécifique dans ce contexte, qui mérite d'être examinée. Le groupe de travail CSS passe beaucoup de temps à comprendre ce que signifie auto dans n'importe quel contexte, comme l'explique cette conférence pour l'éditeur de spécifications Fantasai.
Nous pouvons trouver des informations sur ce que signifie auto
lorsqu'il est utilisé comme flex-basis
dans la spécification. Les termes définis ci-dessus devraient nous aider à décortiquer cette affirmation.
"Lorsqu'il est spécifié sur un élément flexible, le mot-clé auto récupère la valeur de la propriété de taille principale en tant que 'flex-basis' utilisé. Si cette valeur est elle-même auto, alors la valeur utilisée est 'content'.
Donc, si notre flex-basis
est auto
, Flexbox examine la propriété de taille principale définie. Nous aurions une taille principale si nous avions donné une width
à l'un de nos éléments flexibles. Dans l'exemple ci-dessous, les éléments ont tous une largeur de 110px, donc c'est utilisé comme taille principale car la valeur initiale de flex-basis est auto.
Cependant, notre exemple initial a des éléments qui n'ont pas de largeur, cela signifie que leur taille principale est auto
et nous devons donc passer à la phrase suivante, "Si cette valeur est elle-même auto, alors la valeur utilisée est content
."
Nous devons maintenant examiner ce que dit la spécification à propos du mot-clé de content
. Il s'agit d'une autre valeur que vous pouvez utiliser (dans les navigateurs compatibles) pour votre flex-basis
, par exemple :
.item { flex: 1 1 content; }
La spécification définit le content
comme suit :
"Indique une taille automatique basée sur le contenu de l'élément flexible. (Il est généralement équivalent à la taille maximale du contenu, mais avec des ajustements pour gérer les rapports d'aspect, les contraintes de dimensionnement intrinsèques et les flux orthogonaux"
Dans notre exemple, avec des éléments flexibles contenant du texte, nous pouvons ignorer certains des ajustements les plus compliqués et traiter le content
comme étant la taille maximale du contenu.
Cela explique donc pourquoi, lorsque nous avons une petite quantité de texte dans chaque élément, le texte n'est pas renvoyé à la ligne. Les éléments flexibles sont dimensionnés automatiquement, donc Flexbox regarde leur taille maximale de contenu, les éléments tiennent dans leur conteneur à cette taille, et le travail est fait !
L'histoire ne s'arrête pas là, car lorsque nous ajoutons plus de contenu, les boîtes ne restent pas à la taille maximale du contenu. S'ils le faisaient, ils sortiraient du conteneur flexible et provoqueraient un débordement. Une fois qu'ils remplissent le conteneur, le contenu commence à s'enrouler et les éléments deviennent de tailles différentes en fonction du contenu qu'ils contiennent.
Résolution des longueurs flexibles
C'est à ce stade que la spécification devient raisonnablement complexe, cependant, les étapes à suivre sont les suivantes :
Tout d'abord, additionnez la taille principale de tous les articles et voyez si elle est plus grande ou plus petite que l'espace disponible dans le conteneur.
Si la taille du conteneur est supérieure au total, nous allons nous soucier du facteur flex-grow
, car nous avons de l'espace pour grandir.
Si la taille du conteneur est plus petite que le total, nous allons nous soucier du facteur flex-shrink
car nous devons rétrécir.
Congelez tous les articles inflexibles, ce qui signifie que nous pouvons déjà décider d'une taille pour certains articles. Si nous utilisons flex-grow
, cela inclurait tous les éléments qui ont flex-grow: 0
. C'est le scénario que nous avons lorsque nos éléments flexibles ont de la place dans le conteneur. La valeur initiale de flex-grow
est 0, donc ils deviennent aussi grands que leur largeur maximale et ensuite ils ne grandissent plus à partir de leur taille principale.
Si nous utilisons flex-shrink
, cela inclurait tous les éléments avec flex-shrink: 0
. Nous pouvons voir ce qui se passe dans cette étape si nous donnons à notre ensemble d'éléments flex-shrink
de 0. Les éléments deviennent figés dans leur état max-content
et ne se plient donc pas et ne s'arrangent pas pour tenir dans le conteneur.
Dans notre cas, avec les valeurs initiales des éléments flexibles, nos éléments peuvent rétrécir. Ainsi, les étapes se poursuivent et l'algorithme entre dans une boucle dans laquelle il calcule la quantité d'espace à attribuer ou à supprimer. Dans notre cas, nous utilisons flex-shrink
car la taille totale de nos articles est plus grande que le conteneur, nous devons donc prendre de l'espace.
Le facteur flex-shrink
est multiplié par la taille de base interne des éléments, dans notre cas, il s'agit de la taille max-content
. Cela donne une valeur avec laquelle réduire l'espace. Si les éléments supprimaient de l'espace uniquement en fonction du facteur flex-shrink
, les petits éléments pourraient essentiellement disparaître, après avoir perdu tout leur espace, tandis que l'élément le plus grand a encore de l'espace pour rétrécir.
Il y a une étape supplémentaire dans cette boucle pour vérifier les éléments qui deviendraient plus petits ou plus grands que leur taille principale cible, auquel cas l'élément cesse de croître ou de rétrécir. Encore une fois, cela évite que certains éléments ne deviennent minuscules ou massifs par rapport au reste des éléments.
Tout cela a été simplifié en termes de spécifications car je n'ai pas examiné certains des scénarios les plus avancés, et vous pouvez généralement simplement aller plus loin dans votre esprit, en supposant que vous êtes heureux de laisser Flexbox faire son travail et que vous n'êtes pas après pixel la perfection. Se souvenir des deux faits suivants fonctionnera dans la plupart des cas.
Si vous vous développez à partir d' auto
, la flex-basis
sera soit traitée comme n'importe quelle largeur ou hauteur sur l'élément, soit comme la taille max-content
. L'espace sera ensuite attribué en fonction du facteur flex-grow
utilisant cette taille comme point de départ.
Si vous réduisez auto
, la flex-basis
sera soit traitée comme n'importe quelle largeur ou hauteur sur l'élément, soit comme la taille max-content
. L'espace sera alors supprimé en fonction de la taille flex-basis
multipliée par le facteur flex-shrink
, et donc supprimé proportionnellement à la taille max-content des éléments.
Contrôler la croissance et la diminution
J'ai passé la majeure partie de cet article à décrire ce que fait Flexbox lorsqu'il est laissé à lui-même. Vous pouvez, bien sûr, exercer un plus grand contrôle sur vos éléments flexibles en utilisant les propriétés flex
. Espérons qu'ils sembleront plus prévisibles avec une compréhension de ce qui se passe dans les coulisses.
En définissant votre propre flex-basis
, ou en donnant à l'élément lui-même une taille qui est ensuite utilisée comme flex-basis
vous reprenez le contrôle de l'algorithme, indiquant à Flexbox que vous souhaitez augmenter ou réduire cette taille particulière. Vous pouvez désactiver complètement la croissance ou la réduction en réglant flex-grow
ou flex-shrink
sur 0. Sur ce point, cependant, il vaut la peine d'utiliser le désir de contrôler les éléments flexibles pour vérifier si vous utilisez la bonne méthode de mise en page. Si vous essayez d'aligner des éléments flexibles en deux dimensions, vous feriez peut-être mieux de choisir Grid Layout.
Débogage des problèmes liés à la taille
Si vos éléments flexibles finissent par avoir une taille inattendue, c'est généralement parce que votre base flexible est automatique et qu'il y a quelque chose qui donne à cet élément une largeur, qui est ensuite utilisée comme base flexible. L'inspection de l'élément dans DevTools peut aider à identifier l'origine de la taille. Vous pouvez également essayer de définir une flex-basis
de 0
, ce qui forcera Flexbox à traiter l'élément comme ayant une largeur nulle. Même si ce n'est pas le résultat que vous souhaitez, cela vous aidera à identifier la valeur flex-basis
utilisée comme étant la cause de vos problèmes de dimensionnement.
Écarts flexibles
Une fonctionnalité très demandée de Flexbox est la possibilité de spécifier des espaces ou des gouttières entre les éléments flexibles de la même manière que nous pouvons spécifier des espaces dans la disposition de la grille et la disposition multi-colonnes. Cette fonctionnalité est spécifiée pour Flexbox dans le cadre de Box Alignment, et la première implémentation de navigateur est en cours. Firefox s'attend à fournir les propriétés d'écart pour Flexbox dans Firefox 63. L'exemple suivant peut être consulté dans Firefox Nightly.
Comme pour la disposition en grille, la longueur de l'espace est prise en compte avant que l'espace ne soit distribué aux éléments flexibles.
Emballer
Dans cet article, j'ai essayé d'expliquer certains des points les plus subtils de la façon dont Flexbox calcule la taille des éléments flexibles. Cela peut sembler un peu académique, cependant, prendre du temps pour comprendre comment cela fonctionne peut vous faire gagner énormément de temps lors de l'utilisation de Flexbox dans vos mises en page. Je trouve vraiment utile de revenir sur le fait que, par défaut, Flexbox essaie de vous donner la disposition la plus sensée d'un tas d'éléments de tailles différentes. Si un élément a plus de contenu, il reçoit plus d'espace. Si vous et votre conception n'êtes pas d'accord avec ce que Flexbox pense être le meilleur, vous pouvez reprendre le contrôle en définissant votre propre flex-basis
.