Quelles sont les différences entre flex-base et largeur?

224

Il y a eu des questions et des articles à ce sujet, mais rien de concluant pour autant que je sache. Le meilleur résumé que j'ai pu trouver est

flex-based vous permet de spécifier la taille initiale / de départ de l'élément, avant tout autre calcul. Il peut s'agir d'un pourcentage ou d'une valeur absolue.

... qui en soi ne dit pas grand-chose sur le comportement des éléments avec flex-base set. Avec ma connaissance actuelle de flexbox, je ne vois pas pourquoi cela ne pourrait pas décrire la largeur également.

Je voudrais savoir en quoi exactement la flex-base est différente de la largeur dans la pratique:

  • Si je remplace largeur par flex-base (et vice versa), qu'est-ce qui changera visuellement?
  • Que se passe-t-il si je règle les deux sur une valeur différente? Que se passe-t-il s'ils ont la même valeur?
  • Y a-t-il des cas particuliers où l'utilisation de la largeur ou de la base flexible aurait une différence significative par rapport à l'utilisation de l'autre?
  • En quoi la largeur et la base flex diffèrent - elles lorsqu'elles sont utilisées en conjonction avec d'autres styles de flexbox, tels que flex-wrap , flex-grow et flex-shrink ?
  • Y a-t-il d'autres différences importantes?

Edit / clarification : Cette question a été posée dans un format différent dans Quels ensembles de propriétés flex-based exactement? mais je pensais qu'une comparaison ou un résumé plus direct des différences de flex-base et de largeur (ou de hauteur ) serait bien.

jpeltoniemi
la source
Meilleur article expliquant la base du flex, la croissance et le rétrécissement du flex
ZenVentzi

Réponses:

339

Considérer flex-direction

La première chose qui vient à l'esprit lors de la lecture de votre question est que flex-basiscela ne s'applique pas toujours width.

Quand flex-directionest row, flex-basiscontrôle la largeur.

Mais quand flex-directionc'est column, flex-basiscontrôle la hauteur.


Différences clés

Voici quelques différences importantes entre flex-basiset width/ height:

  • flex-basiss'applique uniquement aux articles flexibles. Les conteneurs flexibles (qui ne sont pas également des éléments flexibles) ignoreront flex-basismais peuvent utiliser widthet height.

  • flex-basisne fonctionne que sur l'axe principal. Par exemple, si vous êtes dedans flex-direction: column, la widthpropriété serait nécessaire pour dimensionner les éléments flexibles horizontalement.

  • flex-basisn'a aucun effet sur les éléments flexibles positionnés de manière absolue. widthet les heightpropriétés seraient nécessaires. Les éléments flex absolument positionnés ne participent pas à la mise en page flex .

  • En utilisant la flexpropriété, trois propriétés - flex-grow, flex-shrinket flex-basis- peuvent être parfaitement combinées en une seule déclaration. En utilisant width, la même règle nécessiterait plusieurs lignes de code.


Comportement du navigateur

En ce qui concerne la façon dont ils sont rendus, il devrait y avoir aucune différence entre flex-basiset width, à moins flex-basisest autoou content.

De la spécification:

7.2.3. La flex-basispropriété

Pour toutes les valeurs autres que autoet content, flex-basisest résolu de la même manière que widthdans les modes d'écriture horizontale.

Mais l'impact de autoou contentpeut être minime ou rien du tout. Plus de la spécification:

auto

Lorsqu'il est spécifié sur un élément flexible, le automot clé récupère la valeur de la propriété size principale telle qu'elle est utilisée flex-basis. Si cette valeur est elle-même auto, alors la valeur utilisée est content.

content

Indique un dimensionnement automatique, basé sur le contenu de l'élément flexible.

Remarque: Cette valeur n'était pas présente dans la version initiale de Flexible Box Layout, et donc certaines implémentations plus anciennes ne la prendront pas en charge. L'effet équivalent peut être obtenu en utilisant autoconjointement avec une taille principale ( widthou height) de auto.

Donc, selon la spécification, flex-basiset widthrésolvez à l'identique, sauf si flex-basisest autoou content. Dans de tels cas, flex-basispeut utiliser la largeur du contenu (qui, vraisemblablement, la widthpropriété utiliserait également).


Le flex-shrinkfacteur

Il est important de se rappeler les paramètres initiaux d'un conteneur flexible. Certains de ces paramètres incluent:

  • flex-direction: row - les éléments flexibles s'aligneront horizontalement
  • justify-content: flex-start - les éléments flexibles s'empileront au début de la ligne sur l'axe principal
  • align-items: stretch - les articles flexibles se dilateront pour couvrir la taille transversale du conteneur
  • flex-wrap: nowrap - les articles flexibles sont obligés de rester sur une seule ligne
  • flex-shrink: 1 - un élément flexible est autorisé à rétrécir

Notez le dernier réglage.

Étant donné que les éléments flexibles sont autorisés à rétrécir par défaut (ce qui les empêche de déborder du conteneur), le flex-basis/ width/ spécifié heightpeut être remplacé.

Par exemple, flex-basis: 100pxou width: 100px, couplé à flex-shrink: 1, ne sera pas nécessairement 100px.

Pour rendre la largeur spécifiée - et la maintenir fixe - vous devrez désactiver la réduction:

div {
   width: 100px;
   flex-shrink: 0;
}  

OU

div {
  flex-basis: 100px;
  flex-shrink: 0;
}

OU, comme recommandé par la spécification:

flex: 0 0 100px;    /* don't grow, don't shrink, stay fixed at 100px */

7.2. Composants de flexibilité

Les auteurs sont encouragés à contrôler la flexibilité en utilisant la flexsténographie plutôt qu'avec ses propriétés de sténographie directement, car la sténographie réinitialise correctement tous les composants non spécifiés pour s'adapter aux utilisations courantes .


Bogues du navigateur

Certains navigateurs ont du mal à dimensionner les éléments flexibles dans des conteneurs flex imbriqués.

flex-basisignoré dans un conteneur flexible imbriqué. widthtravaux.

Lors de l'utilisation flex-basis, le conteneur ignore le dimensionnement de ses enfants et les enfants débordent du conteneur. Mais avec la widthpropriété, le conteneur respecte le dimensionnement de ses enfants et se dilate en conséquence.

Références:

Exemples:


flex éléments à l'aide flex-basiset conteneur de white-space: nowrapdébordement inline-flex. widthtravaux.

Il semble qu'un conteneur flexible défini sur inline-flexne reconnaisse pas flex-basisun enfant lors du rendu d'un frère avec white-space: nowrap(bien qu'il puisse s'agir simplement d'un élément avec une largeur non définie). Le conteneur ne se dilate pas pour accueillir les articles.

Mais lorsque la widthpropriété est utilisée à la place de flex-basis, le conteneur respecte le dimensionnement de ses enfants et se développe en conséquence. Ce n'est pas un problème dans IE11 et Edge.

Références:

Exemple:


flex-basis(et flex-grow) ne fonctionne pas sur l'élément de table

Références:


flex-basiséchoue dans Chrome et Firefox lorsque le conteneur de grand-parent est un élément rétractable. La configuration fonctionne correctement dans Edge.

Comme dans l'exemple présenté dans le lien ci-dessus, impliquant position: absolute, l'utilisation de floatet inline-block, rendra également la même sortie défectueuse ( démo jsfiddle ).


Bogues affectant IE 10 et 11:

Michael Benjamin
la source
2
Et alors min-width:100px;? Peut-il être une option pour désactiver la réduction?
Mori
1
@Mori, oui, flex-shrinks'arrête à min-width. La règle de flexion équivalente serait flex: 1 0 100px.
Michael Benjamin
flex: 1 0 100pxconduit au même résultat, mais je ne sais pas ce que vous entendez par "équivalent".
Mori
Je veux dire pourquoi ne devrions-nous pas le considérer égal à flex: 0 0 100px, par exemple?
Mori
2
@Mori, car alors c'est juste égal à la largeur . Il a besoin du composant flex-grow: 1 pour permettre à l'élément de croître à partir de la largeur minimale, définie par la base flex .
Michael Benjamin
33

En plus de l'excellent résumé de Michael_B, il vaut la peine de le répéter:

flex-based vous permet de spécifier la taille initiale / de départ de l'élément, avant tout autre calcul. Il peut s'agir d'un pourcentage ou d'une valeur absolue.

La partie importante ici est initiale .

En soi, cela se résout en largeur / hauteur jusqu'à ce que les autres propriétés de croissance / rétraction flexibles entrent en jeu.

Alors. un enfant avec

.child {
 flex-basis:25%;
 flex-grow:1;
}

sera de 25% de large au départ, mais ensuite se dilater immédiatement autant que possible jusqu'à ce que les autres éléments soient pris en compte. S'il n'y en a pas, il sera de 100% large / haut.

Une démo rapide:

Expérimenter avec le flex-grow, flex-shrinket flex-basis (ou le raccourci flex :fg fs fb) ... peut conduire à des résultats intéressants.

Paulie_D
la source
Je trouve que généralement dans le contexte flex les deux flex-basiset width / heightdéfinir la taille initiale / à partir d'un élément. Par exemple, flex-basis: 200pxfonctionne essentiellement comme flex-basis: auto; width: 200px;. Il semble que lorsque flex-basisn'est pas défini sur autoalors il remplace simplement la width / heightvaleur. La seule différence que je vois est la façon dont le débordement de contenu est géré.
Karolis
5

Peut-être le point le plus important à ajouter:

Et si le navigateur ne prend pas en charge flex? Dans un tel cas, width/heightprenez le relais et leurs valeurs s'appliquent.

C'est une très bonne idée - presque essentielle - de définir des width/heightéléments, même si vous avez alors une valeur complètement différente pour flex-basis. N'oubliez pas de tester en désactivant display:flexet en voyant ce que vous obtenez.

Niet l'Absolu Noir
la source
2
Parmi les principaux navigateurs, les seuls qui ne prennent pas en charge les propriétés flex sont IE <10. caniuse.com/#search=flex
Michael Benjamin
1
@Michael_B Bien sûr, et c'est peut-être juste moi, mais je dois aussi prendre en charge les navigateurs mobiles, jusqu'au navigateur Nintendo 3DS inclus, qui ne le prend décidément pas flex.
Niet the Dark Absol