flex grow shrink basis...
2022
Lorsque qu'on applique une propriété CSS à un élément, il y a, surtout avec les flexbox beaucoup de choses qui se passent sous le capot.
Par exemple, si nous avons le code HTML suivant:
<div class="conteneurFlex">
<div class="elementFlex">elementFlex</div>
<div class="elementFlex">elementFlex</div>
<div class="elementFlex">elementFlex</div>
</div>
Et que nous écrivons le CSS sur le conteneur
.conteneurFlex {
display: flex;
}
Toute une série de propriétés par défaut seront appliquées aux
éléments .elementFlex
, comme si nous avions écrit
nous-mêmes le css suivant:
.elementFlex {
flex: 0 1 auto; /* valeur par default de flex */
}
parce que certaines propriétés ont des valeurs par défaut; ces valeur peuvent évidemment être remplacées par nos soins en écrivant du code explicite. Si nous ne savons pas que ces styles implicites sont appliqués lorsque nous écrivons notre CSS, nos résultats de mises en page peuvent devenir assez difficiles à comprendre et a gérer.
La propriété flex
ci-dessus est ce que l'on appelle
une propriété raccourcie.
En réalité, il s'agit de définir trois propriétés CSS distinctes en même temps.
Ce que nous avons écrit ci-dessus revient donc à écrire ceci :
.elementFlex {
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
}
Ainsi, une propriété raccourcie regroupe des propriétés CSS différentes pour faciliter l'écriture de plusieurs propriétés à la fois.
On à déjà manipulé des propriétés raccourcies, par exemple:
border
qui est un raccourci pour border-width
,
border-style
et border-color
.
ainsi
border:1em dashed red;} p {
equivaut à:
p {border-width:1em;
border-style:dashed
red;
border-color: }
<style>
border:1em dashed red;}
p {</style>
<p>exemple propriété raccourcie</p>
exemple propriété raccourcie
Quand on débute en CSS, il est souvent preferable d'utiliser les
versions longues dont le nom est plus significative et donc plus facile
à mémoriser. Mais, lorsqu'il s'agit de flexbox, il est
plutôt recommandé d'utiliser les raccourcis car la propriété
flex
fait beaucoup de travail et que chacune de ses
sous-propriétés interagit avec les autres.
De plus, les styles par défaut sont une bonne chose car, dans 90 % des cas, nous n'avons pas besoin de savoir ce que font ces propriétés par défaut. Par exemple, lorsque qu'on utilise les flexbox, on peut commencer par écrire quelque chose comme ceci :
.conteneurFlex {
display: flex;
justify-content: space-between;
}
sans se soucier des éléments .elementFlex
ou des styles
qui leur ont été appliqués.
Dans ce cas, nous alignons les éléments .elementFlex
côte à côte, puis nous les espaçons de manière égale les uns des autres.
Deux lignes de CSS suffise ici et c'est ce qu'il y a de mieux avec la
flexbox et ces styles hérités , on n'a pas besoin de comprendre toute la
complexité du système si on veut simplement faire la même chose dans 90
% des cas.
C'est très pratique parce que toute la complexité est cachée .
Mais qu'en est-il si nous voulons comprendre le fonctionnement réel
de flexbox, y compris les propriétés flex-grow
,
flex-shrink
et flex-basis
? Et quelles sont
les choses intéressantes que nous pouvons faire avec elles ?
Commençons par un aperçu rapide et un peu simplifié, et revenons aux
propriétés flex par défaut qui sont appliquées aux éléments
.elementFlex
:
.elementFlex {
flex: 0 1 auto;
}
Ces styles par défaut indiquent aux éléments
.elementFlex
comment s'étirer et se développer. Pour
comprendre ou se rappeler se que cela fait on peut penser ces propriétés
abrégées comme ceci:
.elementFlex {
/* c'est pas du css, juste une façon de penser la règle ci-dessus */
flex: [flex-grow] [flex-shrink] [flex-basis];
}
ou...
.elementFlex {
/* c'est pas du css, juste une façon de penser la règle ci-dessus */
flex: [max] [min] [taille idéale];
}
La première valeur est flex-grow
et elle est définie
à 0 car, par défaut, nous ne voulons pas que nos
éléments s'étendent du tout (la plupart du temps). Nous voulons plutôt
que chaque élément dépende de la taille du contenu qu'il contient. Voici
un exemple :
.conteneurFlex {
display: flex;
}
.conteneurFlex {
background-color: orange;
display: flex;
padding: 10px;
border:dotted;
}
.elementFlex {
background-color: green;
padding: 10px;
height:80px;
border:solid;
}<div class="conteneurFlex">
<div class="elementFlex un" contenteditable>element</div>
<div class="elementFlex deux" contenteditable>grand element</div>
<div class="elementFlex trois" contenteditable>element</div>
</div>
On a ajouté la propriété contenteditable
à chaque
élément .elementFlex
ci-dessus pour que vous puissiez
cliquer dessus et modifier les contenus et voir comment cela réagit.
C'est le comportement par défaut d'un élément flexbox :
flex-grow
est défini sur 0
car nous voulons
que **l'élément grandisse en fonction du contenu qu'il contient.
Mais si nous modifions la valeur par défaut de la propriété
flex-grow
de 0
à 1
, comme ceci
:
.elementFlex {
flex: 1 1 auto;
}
Tous les éléments se répartissent la place complète du conteneur et
prendront donc une part égale de l'élément .conteneurFlex
,
seulement si la longueur de leur contenu est la même.
.conteneurFlex {
background-color: orange;
display: flex;
padding: 10px;
border:dotted;
}
.elementFlex {
background-color: green;
padding: 10px;
border:solid;
height:80px;
flex-grow:1;
}<div class="conteneurFlex">
<div class="elementFlex un" contenteditable>element</div>
<div class="elementFlex deux" contenteditable>grand element</div>
<div class="elementFlex trois" contenteditable>element</div>
</div>
c'est exactement t la meme chose que d'écrire
.elementFlex {
flex-grow: 1;
}
et en ignorant les autres valeurs parce qu'elles ont été définies par défaut de toute façon.
Cela peut être deroutant quand on commence à travailler avec des
mises en page flexibles. car le flex-grow
que l'on ajoute
interagit (ie., son comportement depend aussi de la valeur des
autres propriétés) avec des valeur par défaut que l'on n'a pas
positionné. -
Maintenant, si nous voulons qu'un seul de ces éléments croisse plus que les autres, il suffit de faire ce qui suit :
.elementFlex.trois {
flex: 5 1 auto;
}
/* ou juste */
.elementFlex.trois {
flex-grow: 5;
}
<style>
.conteneurFlex {
background-color: orange;
display: flex;
padding: 10px;
}
.elementFlex {
background-color: green;
padding: 10px;
border:solid;
height:80px;
flex-grow:1;
}
// l'élément trois
.elementFlex.trois {
flex-grow:5;
}</style>
<div class="conteneurFlex">
<div class="elementFlex un" contenteditable>element</div>
<div class="elementFlex deux" contenteditable>grand element</div>
<div class="elementFlex trois" contenteditable>element</div>
</div>
dans l'exemple ci-dessus, les deux premiers éléments
.elementFlex
occuperont proportionnellement la même
quantité d'espace, mais le troisième élément essaiera de croître jusqu'à
cinq fois l'espace des autres.
C'est là que les choses se compliquent , car tout dépend du contenu
des éléments .elementFlex
. Même si nous définissons
flex-grow:5
, comme nous l'avons fait dans l'exemple
ci-dessus, puis que nous ajoutons du contenu, la mise en page sera
modifiée comme ci-dessous :
<style>
.conteneurFlex {
background-color: orange;
display: flex;
padding: 10px;
}
.elementFlex {
background-color: green;
padding: 10px;
border:solid;
height:80px;
flex-grow:1;
}
.elementFlex.trois {
flex-grow:5;
}</style>
<div class="conteneurFlex">
<div class="elementFlex un" contenteditable>element</div>
<div class="elementFlex deux" contenteditable>un tres tres tres grand elementFlex </div>
<div class="elementFlex trois" contenteditable>element</div>
</div>
La deuxième colonne prend maintenant trop d'espace ! Nous reviendrons
sur ce point plus tard, mais pour l'instant, il est important de se
rappeler que le contenu d'un élément flex a un impact sur la façon dont
flex-grow
, flex-shrink
et
flex-basis
fonctionnent ensemble.
Voyons , maintenant flex-shrink
.
Rappelez-vous que c'est la deuxième valeur dans le raccourci
flex
:
.elementFlex {
flex: 0 1 auto; /* flex-shrink = 1 */
}
flex-shrink
indique au navigateur quelle doit être la
taille minimale d'un élément; sa valeur par défaut est
1, ce qui revient à dire : "occupez toujours la même quantité
d'espace". Cependant ! Si nous devions définir cette valeur à
0
comme ceci :
.elementFlex {
flex: 0 0 auto;
}
alors on dit à cet élément de ne pas rétrécir du tout. Nous reviendrons sur cette propriété une fois que nous aurons examiné la valeur finale de la propriété raccourcie.
flex-basis
est la dernière valeur ajoutée par défaut
dans le raccourci flex
, et c'est la façon dont nous
indiquons à un élément sa taille idéale.
Par défaut,on a flex-basis:auto
, ce qui
signifie "Utilisez ma hauteur ou ma largeur". Ainsi, lorsque nous
définissons display:flex
sur un conteneur
.conteneurFlex
.conteneurFlex {
display: flex;
}
//donc par default
.elementFlex {
flex: 0 1 auto;
}
On aura, par défaut dans le navigateur :
<style>
.conteneurFlex {
background-color: orange;
display: flex;
padding: 10px;
border:dotted;
}
.elementFlex {
background-color: green;
padding: 10px;
height:80px;
border:solid;
}
</style>
<div class="conteneurFlex">
<div class="elementFlex un" contenteditable>element</div>
<div class="elementFlex deux" contenteditable>element</div>
<div class="elementFlex trois" contenteditable>element</div>
</div>
Tous les éléments ont par défaut la largeur de leur contenu.
C'est parce qu'Auto
veut dire que la taille idéale
de notre élément est définie par son contenu.
Pour que tous les éléments occupent tout l'espace du
conteneurFlex
, nous pouvons définir les éléments
.elementFlex
avec width : 100%
, ou nous
pouvons définir flex-basis:100%
, ou nous pouvons définir
flex-grow:1
.
Chacune de ces valeurs abrégées a un impact sur les autres et c'est pourquoi il est recommandé d'utiliser lla propriété raccourcie plutôt que de définir ces valeurs indépendamment les unes des autres.
Lorsque nous écrivons quelque chose comme:
.elementFlex.trois {
flex: 0 1 1000px;
}
Ce que nous disons au navigateur, c'est de définir la base flexible à
1000px
soit "s'il te plaît, essaye d'occuper
1000px
d'espace". Si ce n'est pas possible, l'élément
occupera cet espace proportionnellement aux autres éléments.
<style>
.conteneurFlex {
background-color: orange;
display: flex;
padding: 10px;
border:dotted;
}
.elementFlex {
background-color: green;
padding: 10px;
height:80px;
border:solid;
}
.elementFlex.trois {
flex:0 1 1000px;
}</style>
<div class="conteneurFlex">
<div class="elementFlex un" contenteditable>element</div>
<div class="elementFlex deux" contenteditable>element</div>
<div class="elementFlex trois" contenteditable>element</div>
</div>
Sur les petits écrans, ce troisième élément ne fait pas
1000px
!
Il s'agit en fait d'une suggestion et flex-shrink
, qui
demande à l'élément de se réduire à la même taille que les autres
éléments, s'applique toujours
De même, l'ajout de contenu aux autres .elementFlex
aura
toujours un impact, comme illustré ci-dessous :
<style>
.conteneurFlex {
background-color: orange;
display: flex;
padding: 10px;
border:dotted;
}
.elementFlex {
background-color: green;
padding: 10px;
height:80px;
border:solid;
}
.elementFlex.trois {
flex:0 1 1000px;
}</style>
<div class="conteneurFlex">
<div class="elementFlex un" contenteditable>element</div>
<div class="elementFlex deux" contenteditable>anticonstitutionnellement, est un mot tres grand dans l'element</div>
<div class="elementFlex trois" contenteditable>element</div>
</div>
Maintenant, si nous voulions interdire à cet élément de rétrécir , nous pourrions écrire quelque chose comme ceci :
.elementFlex.trois {
flex: 0 0 1000px;
}
flex-shrink
est la deuxième valeur et en la
mettant à 0
nous disons, "Ne rétrécis jamais". Et c'est ce
qui se passe ! L'élément se détachera même du conteneurFlex
parce que sa largeur ne sera jamais inférieure à 1000px
:
<style>
.conteneurFlex {
background-color: orange;
display: flex;
padding: 10px;
}
.elementFlex {
background-color: green;
padding: 10px;
height:80px;
border:solid;
}
.elementFlex.trois {
flex:0 0 1000px;
}</style>
<div class="conteneurFlex">
<div class="elementFlex un" contenteditable>element</div>
<div class="elementFlex deux" contenteditable>grand element</div>
<div class="elementFlex trois" contenteditable>element</div>
</div>
Maintenant, tout cela change si nous définissons
flex-wrap
dans l'élément .conteneurFlex
:
.conteneurFlex {
display: flex;
flex-wrap: wrap;
}
.elementFlex.trois {
flex: 0 0 1000px;
}
Nous verrons quelque chose comme ceci :
<style>
.conteneurFlex {
background-color: orange;
display: flex;
padding: 10px;
border:dotted;
flex-wrap:wrap;
}
.elementFlex {
background-color: green;
padding: 10px;
border:solid;
height:80px;
flex: 0 1 auto;
}
.elementFlex.trois {
flex:1 0 1000px;
}</style>
<div class="conteneurFlex">
<div class="elementFlex un" contenteditable>element</div>
<div class="elementFlex deux" contenteditable>element</div>
<div class="elementFlex trois" contenteditable>element</div>
</div>
En effet, par défaut, les éléments flexibles essaieront de tenir sur
une seule ligne, mais flex-wrap : wrap
si ces flexibles ne
peuvent pas tenir dans le même espace, ils se seront disposé sur
plusieurs lignes.
Quoi qu'il en soit, il ne s'agit là que de quelques-unes des façons dont les propriétés flex interagissent et de la raison pour laquelle il est important de comprendre comment ces propriétés fonctionnent ensemble.
Chacune de ces propriétés peut affecter l'autre, et si vous ne comprenez pas le fonctionnement d'une propriété, alors vous ne comprenez pas du tout comment tout cela fonctionne.
flex
flex
: taille maximale, minimale et
idéale.