Tutos :
- https://developer.mozilla.org/fr/docs/Web/CSS/CSS_Flexible_Box_Layout/Concepts_de_base_flexbox
- https://la-cascade.io/flexbox-guide-complet/
- https://flexboxfroggy.com/
- https://codepen.io/enxaneta/full/adLPwv/ pour bien comprendre la différence entre align-content et align-items
display: flex; Création du conteneur flexible
section { display : flex; }
L’élément section dispose maintenant d’un axe principal (main axis) qui est par défaut horizontal. L’axe principal d’un conteneur flexbox peut être horizontal ou vertical, mais par défaut il est horizontal. Le conteneur dispose également d’un axe transversal (cross axis) quit est part défaut vertical.
flex-direction : Choix de l'axe
On définit l'axe principal grâce à la propriété "flex-direction".
Les valeurs possibles sont :
- row,
- row-reverse,
- column,
- column-reverse
Exemple de code :
HTML
<section> <article>Contenu 1</article> <article>Contenu 2</article> <article>Contenu 3</article> <article>Contenu 4</article> </section>
CSS
Elément parent (conteneur flexible)
section { display: flex; flex-direction: row; border: 5px solid black; height: 400px; }
Eléments enfants (éléments flexibles)
section > article { border: 5px solid red; padding: 20px; }
Résultat
On observe que :
- les éléments enfants sont maintenant côte à côte sur une même ligne. Si l'on avait choisi "column" comme valeur à la propriété flex-direction, les articles seraient les uns sous les autres
- même si la largeur du navigateur est inférieure à la somme des largeurs des éléments enfants, ceux ci restent sur la même ligne, quitte à faire apparaître un ascenceur horizontal
- Si l'on agrandit la hauteur du conteneur, les éléments flexibles suivent cette hauteur. Les éléments sont donc étirés le long de l'axe secondaire afin d'occuper l'espace sur cet axe.
- La propriété flex-basis vaut auto (voir plus bas)
- La propriété flex-wrap vaut nowrap (voir plus bas)
flex-wrap : conteneur flexible sur plusieurs lignes
Par défaut la propriété flex-wrap vaut "nowrap". En modifiant cette valeur, les éléments enfants flexibles vont pouvoir passer à la ligne lorsque la largeur de leur conteneur ne sera plus suffisante.
Les valeurs possibles sont :
- wrap
- nowrap
- wrap-reverse
css :
section { display: flex; flex-direction: row; border: 5px solid black; flex-wrap: wrap; }
Résultat :
flex-flow : la proprité raccourcie pour flex-direction et flex-wrap
Flex flow permet simplement de regrouper sur une même ligne les valeurs des propriétés flex-direction et flex-wrap.
Ainsi le code css du dessus peut être raccourci comme ceci :
section { display: flex; border: 5px solid black; flex-flow: row wrap; }
Propriétés s'appliquant aux éléments flexibles
flex-grow : facteur d'expansion d'un élément flexible
flex-grow va permettre de savoir comment l'élément doit "grossir" en fonction :
-
de l'espace disponible sur l'axe principal,
- de la valeur de flex-grow des autres éléments flexibles qui sont sur le même axe principal.
Les valeurs possibles sont : un nombre positif qui correspond au facteur de grossissement utilisé. Plus la valeur est élevée, plus l'élément sera étendu si nécessaire au regard et en proportion de la valeur de flex-grow des autres éléments.
Exemple 1:
/* éléments enfants */ section > article { border: 5px solid red; padding: 20px; flex-grow: 1; // ici tous les éléments auront le même comportement }
Résultat dans le cas où tous les éléments peuvent se trouver sur la même ligne :
Résultat dans le cas où tous les éléments ne peuvent se trouver sur la même ligne :
Flex-grow différents
/* éléments enfants flexibles */ section > article { border: 5px solid red; padding: 20px; flex-grow: 1; }ali section > article:first-child { flex-grow: 2; }
Dans ce cas, le premier élément va prendre 2 fois plus de place le long de l'axe prinicipal :
flex-shrink : facteur de rétrécissement d'un élément flexible.
flex-shrink se comporte de la même façon que flex-grow mais s'applique dans le cas où il n'y a pas assez de place pour les éléments flexibles sur l'axe principal.
Les valeurs possibles sont : un nombre positif qui correspond au facteur de rétrécissement utilisé. Plus la valeur est élevée, plus l'élément sera rétréci si nécessaire au regard et en proportion de la valeur de flex-shrink des autres éléments.
flex-basis : taille initiale des éléments flexibles
Tuto pour comprende en profondeur flex-basis
flex-basis détermine la base de flexibilité utilisée comme taille initiale principale pour un élément flexible. Cette propriété détermine la taille de la boîte de contenu mais son comportement peut être modifié si min-width et max-width sont définis.
Globalement, voici comment est déterminé la largeur d'un élément flex :
content —> width —> flex-basis (limité par max|min-width)
Il faut donc comprendre cette formule de la façon suivante :
- si rien n'est défini la largeur de l'élément dépend de son contenu.
- si seul width est défini, c'est lui qui s'applique
- sinon c'est flex-basis qui prend le dessus mais limité par max-width et min-widh
Les principales valeurs possibles pour flex-basis sont : auto (par défaut), 0 (prend le minimum de place),
Exemples de valeurs possibles :
- flex-basis: 30%; /* relatif */
- flex-basis: 3px;
- flex-basis: auto; /* par défaut */
- flex-basis: content; /* en fonction du contenu de l'élément */
- ...
Ex :
/* éléments enfants flexibles */
section > article {
border: 5px solid red;
padding: 20px;
flex-grow: 1;
flex-basis: auto;
}
section > article:first-child {
flex-grow: 1;
flex-basis: 0;
}
Résultat :
On note que la base de calcul de la taille des éléments n'étant pas la même, le premier élément est moins large que les autres. C'est d'autant plus visible lorsque l'espace disponible dans le conteneur parent n'est plus suffisant.
flex : la propriété raccourcie pour flex-grow, flex-shrink et flex-basis
La propriété raccourcie flex permet de définir les valeurs de cette propriété dans cet ordre : flex-grow, flex-shrink, flex-basis.
Ex :
/* éléments enfants flexibles */ section > article { border: 5px solid red; padding: 20px; flex: 1 1 auto; }
La propriété flex permet également d'utiliser des valeurs synthétiques qui couvrent la majorité des scénarios.
- flex: initial
- flex: auto
- flex: none
- flex: <nombre-positif>
Avec flex: initial, les éléments récupèrent les valeurs initiales pour les différentes propriétés du modèle de boîte flexible. Cette valeur permettra d'obtenir le même comportement que flex: 0 1 auto. Ici, flex-grow vaut 0 et les éléments ne s'agrandiront pas au-delà de la taille flex-basis. flex-shrink vaut 1 et les éléments pourront rétrécir si besoin plutôt que de dépasser du conteneur. flex-basis vaut auto et les éléments utiliseront donc la taille qui leur a été définie sur l'axe principale ou la taille déterminée à partir du contenu.
Avec flex: auto, on obtient le même comportement que flex: 1 1 auto, la seule différence avec flex:initial est que les éléments peuvent s'étirer si besoin.
Avec flex: none, les éléments ne seront pas flexibles. Cette valeur est synonyme de flex: 0 0 auto. Les éléments ne peuvent ni s'agrandir, ni se rétrécir mais seront disposés avec flex-basis: auto.
On voit aussi souvent des valeurs comme flex: 1 ou flex: 2, etc. Cela correspond à flex: 1 1 0. Les éléments peuvent s'agrandir ou bien rétrécir à partir d'une taille de base égale à 0.
justify-content et align-items : Alignement, justification et distribution de l'espace disponible entre les éléments
justify-content
La propriété justify-content est utilisée afin d'aligner les éléments le long de l'axe principal dans la direction définie par flex-direction. La valeur initiale est flex-start qui place les éléments à partir de la ligne de début du conteneur sur l'axe principal. La valeur flex-end permet de les placer vers la fin et la valeur center permet de les centrer le long de l'axe principal.
Attention : notez que tous les flex-items doivent avoir la propriété flex-grow: 0; afin que la propriété justify-content fontionne.
Les valeurs possibles sont :
- flex-start
- flex-end
- center
- space-around
- space-between
- space-evenly (même chose que "space-between" sauf que l'espace est le même à gauche du premier élément, à droite du dernier élément et entre les éléments)
Exemple :
/* élément parent */
section {
display: flex;
flex-flow: row wrap;
align-items: stretch;
justify-content: space-around;
}
/* éléments enfants flexibles */
section > article {
padding: 0;
flex: 0 0 auto;
width: 23%;
background-color: blueviolet;
}
/* éléments enfants des enfants flexibles */
section > article > div {
padding: 1rem;
}
Résultat :
align-items
La propriété align-items permet d'aligner les éléments le long de l'axe secondaire.
La valeur initiale de cette propriété est stretch, ce qui explique pourquoi, par défaut, les éléments flexibles sont étirés sur l'axe perpendiculaire afin d'avoir la même taille que l'élément le plus grand dans cet axe (qui définit la taille du conteneur sur cet axe).
Les valeurs possibles sont :
- stretch,
- flex-start,
- flex-end,
- center
align-content : Répartition de l'espace entre et autour des éléments le long de l'axe transversal
https://developer.mozilla.org/fr/docs/Web/CSS/align-content
Cette propriété n'a de sens que si les éléments flexibles passent à la ligne (flex-wrap: wrap)
align-content définit la façon dont l'espace est réparti entre et autour des éléments le long de l'axe transversal lorsque celui-ci est un conteneur de boîte flexible.
Les valeurs possibles sont :
- center; /* Les éléments sont groupés au centre */
- start; /* Les éléments sont groupés au début */
- end; /* Les éléments sont groupés à la fin */
- flex-start; /* Les éléments flexibles sont groupés au début */
- flex-end; /* Les éléments flexibles sont groupés à la fin */
- space-between; /* Espace réparti entre les éléments mais le premier et le dernier élément sont "collés" au conteneur */
- space-around; /* L'espace est réparti entre les éléments */
- normal /* default */
Attention, le comportement par défaut est un peu étrange. Si on prend le cas où l'axe principal est horizontal, la première ligne va être "collée" en haut du container. S'il y a plusieurs lignes et qu'il reste de l'espace, ce dernier sera réparti à part égale entre les lignes. C'est un comportement très proche de
- "space between" sauf que de l'espace sera réparti après la dernière ligne,
- "space around" sauf qu'il n'y aura pas d'espace réparti avant la première ligne.
align-self
Quand on veut changer les propriétés d'un enfant en particulier sur l'axe secondaire.
Les valeurs possibles sont :
- auto
- flex-start
- flex-end
- center
- baseline
- stretch
gap
Gère l'espace de la gouttière sur l'axe secondaire (perme de ne plus utiliser les margin négatifs).
Ex pour une gouttière de 20px verticale lorsque l'axe principal est "row" :
gap: 20px 0;
Order
https://developer.mozilla.org/fr/docs/Web/CSS/order
La propriété order définit l'ordre avec lequel on dessine les éléments d'un conteneur d'éléments flexibles ou d'une grille d'éléments. Les éléments sont appliqués dans l'ordre croissant des valeurs de order. Les éléments ayant la même valeur pour order seront appliqués dans l'ordre selon lequel ils apparaissent dans le code source du document.
Exercice 1
Trouver le code css adapté pour obtenir le résultat classique ci-dessus :
section { display: flex; flex-wrap: wrap; justify-content: space-between; align-content: flex-start; border: 1px solid black; } section > div { border: 1px solid blue; margin-bottom: 30px; flex-basis: 30%; }
Exercice 2 : Création d'une grille 960 avec flex
Exemple d'utilisation