web-dev-qa-db-fra.com

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

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

flex-base vous permet de spécifier la taille initiale/de départ de l'élément, avant que toute autre chose soit calculée. 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 mes connaissances actuelles de flexbox, je ne vois pas pourquoi cela ne pourrait pas décrire width également.

J'aimerais savoir en quoi flex-base est différent de width en pratique:

  • Si je remplace width par flex-based (et vice versa), qu'est-ce qui va changer visuellement?
  • Que se passe-t-il si je mets les deux sur une valeur différente? Que se passe-t-il s'ils ont la même valeur?
  • Existe-t-il des cas spéciaux où l’utilisation de width ou flex-based aurait une différence significative par rapport à l’utilisation de l’autre?
  • En quoi width et flex-based diffèrent-elles lorsqu'elles sont utilisées conjointement avec d'autres styles flexbox, tels que flex-wrap , flex-grow et flex-shrink ?
  • Toute autre différence significative?

Éditer/clarification : Cette question a été posée dans un format différent en Quels ensembles de propriétés de base flexibles? mais je me suis senti une comparaison ou un résumé plus direct des différences de flex-base et width (ou height ) serait bien.

183
jpeltoniemi

Considérez flex-direction

La première chose qui me vient à l’esprit en lisant votre question est que flex-basis ne s’applique pas toujours à width.

Lorsque flex-direction est row, flex-basis contrôle la largeur.

Mais lorsque flex-direction est column, flex-basis contrôle la hauteur.


Différences Clés

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

  • flex-basis s'applique uniquement aux éléments flexibles. Les conteneurs Flex (qui ne sont pas également des éléments flex) ignoreront flex-basis mais pourront utiliser width et height.

  • flex-basis fonctionne uniquement sur l'axe principal. Par exemple, si vous êtes dans flex-direction: column, la propriété width sera nécessaire pour le dimensionnement horizontal des éléments flexibles.

  • flex-basis n'a aucun effet sur les éléments flex positionnés de manière absolue. Les propriétés width et height seraient nécessaires. Les éléments flex absolument positionnés ne participent pas à la mise en page flexible .

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


Comportement du navigateur

En termes de rendu, il devrait y avoir pas de différence entre flex-basis et width, à moins que flex-basis ne soit auto ou content.

À partir de la spécification:

7.2.3. La propriété flex-basis]

Pour toutes les valeurs autres que auto et content, flex-basis est résolu de la même manière que width en mode d'écriture horizontale.

Mais l'impact de auto ou content peut être minime ou rien du tout. Plus de la spec:

auto

Lorsqu'il est spécifié sur un élément flex, 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, la valeur utilisée est content.

content

Indique le dimensionnement automatique, basé sur le contenu de l’élément flex.

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

Ainsi, conformément à la spécification, flex-basis et width se résolvent de manière identique, sauf si flex-basis est auto ou content. Dans de tels cas, flex-basis peut utiliser une largeur de contenu (que la propriété width utiliserait vraisemblablement également).


Le facteur flex-shrink

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

  • flex-direction: row - les éléments flexibles seront alignés horizontalement
  • justify-content: flex-start - les éléments flexibles s'empilent au début de la ligne sur l'axe principal
  • align-items: stretch - les éléments flexibles se développeront pour couvrir la taille croisée du conteneur
  • flex-wrap: nowrap - les éléments flexibles sont forcés de rester sur une seule ligne
  • flex-shrink: 1 - un élément flexible peut être réduit

Notez le dernier réglage.

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

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

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

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

OR

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 la flexibilité

Les auteurs sont encouragés à contrôler la flexibilité en utilisant le raccourci flex plutôt que directement avec ses propriétés longhand, car le raccourci réinitialise correctement tous les composants non spécifiés pour tenir compte de tilisations courantes .


Bugs du navigateur

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

flex-basis ignoré dans un conteneur Flex imbriqué. width fonctionne.

Lors de l'utilisation de flex-basis, le conteneur ignore le dimensionnement de ses enfants et les enfants débordent du conteneur. Mais avec la propriété width, le conteneur respecte le dimensionnement de ses enfants et s’agrandit en conséquence.

Références:

Exemples:

ajustez les éléments en utilisant flex-basis et white-space: nowrap overflow inline-flex. width fonctionne.

Il semble qu'un conteneur flex défini sur inline-flex ne reconnaît pas flex-basis sur un 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 développe pas pour accueillir les éléments.

Mais lorsque la propriété width 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:


Bugs affectant IE 10 et 11:

276
Michael_B

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

flex-base vous permet de spécifier la taille initiale/initiale de l'élément, avant que toute autre chose soit calculée. 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 entre en jeu les autres propriétés de croissance/diminution.

Alors. un enfant avec

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

aura une largeur de 25% au début, puis sera immédiatement étendu autant que possible jusqu'à ce que les autres éléments soient pris en compte. S'il n'y en a pas..il sera 100% large/grand.

Une démo rapide:

.flex {
  width: 80%;
  margin: 1em auto;
  height: 25px;
  display: flex;
  background: rebeccapurple;
}
.child {
  flex-basis: auto;
  /* default */
  background: Plum;
}
.value {
  flex-basis: 25%;
}
.grow {
  flex-grow: 1;
}
<div class="flex">
  <div class="child auto">Some Content</div>
</div>
<div class="flex">
  <div class="child value">Some Content</div>
</div>
<div class="flex">
  <div class="child grow">Some Content</div>
</div>

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

29
Paulie_D

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

Que faire si le navigateur ne supporte pas flex? Dans un tel cas, width/height prend le relais et leurs valeurs s'appliquent.

C'est une très bonne idée - presque essentielle - de définir width/height sur des é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:flex et en voyant ce que vous obtenez.

4