NFA016 : les cascading style sheets (CSS) : Flex

O. Pons, S. Rosmorduc

Conservatoire National des Arts & Métiers

Les flex

Principe

Exemple

Cases de même hauteur sur une seule ligne

display: flex;
flex: 1 1 auto
blah
blah
blah
flex: 1 1 auto
blah
flex: 3 1 auto
agagax !
flex: 1 1 auto

Autre exemple

Ici, la valeur de flex n'est pas précisée pour les enfants ; elle équivaut à flex: 0 1 auto;.

display: flex;
Premier élément, Premier élément.

Second paragraphe

Second élément
Troisième élément
On voit ici que les éléments se sont placés les uns à côté des autres, en prenant chacun la place dont il a besoin. Ils ont tous la même hauteur.

La propriété flex

Définie sur l'élément enfant.

Trois paramètres: flex-grow, flex-shrink et flex-basis

grow
capacité de l'élément à utiliser de l'espace libre. 0: l'élément ne grossit pas. Un élément avec grow=2 grossit deux fois plus qu'un élément à 1.
shrink
capacité de l'élément à rétrécir ; fonctionne comme grow.
basis
fixe la taille de départ (à partir de laquelle on essaie de grossir ou de rétrécir). Peut être une dimension (comme 3cm ou 2em), content, qui utilise le contenu de l'élément lui-même pour calculer sa taille, ou auto, qui réparti l'espace total disponible dans cette alignement (c'est à dire celui laissé par tous les éléments).

Premier exemple

Ci dessous, on a trois éléments en flex : 1 1 auto.

On remarque que:

display: flex;
flex: 1 1 auto;
Premier élément, Premier élément, Premier élément.
flex: 1 1 auto;
Second élément
flex: 1 1 auto;
Troisième élément

auto et élément large

Ici, nous sommes toujours sur des flex à 1 1 auto, mais le premier élément est trop long pour que tout tienne sur une ligne.

Flex doit réduire les éléments (en utilisant la propriété shrink qui est à 1). L'espace assigné par défaut dépend de la largeur « naturelle » de l'élément, ainsi que de sa capacité à être réduit. Observez le premier et le second élément en particulier.

display: flex;
flex: 1 1 auto;
Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément,
a a a a a a a a a a a
flex: 1 1 auto;
du texte
flex: 1 1 auto;
bla bla bla
display: flex;
flex: 1 1 auto;
Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément,
a a a a a a a a a a a
flex: 1 1 auto;
du texte
flex: 1 1 auto;
bla bla bla
display: flex;
flex: 1 1 auto;
Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément,
a a a a a a a a a a a
flex: 1 1 auto;
du texte
flex: 1 1 auto;
bla bla bla
display: flex;
flex: 1 1 auto;
Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément,
a a a a a a a a a a a
flex: 1 1 auto;
du texte
flex: 1 1 auto;
bla bla bla

Basis à auto

avec une basis de auto, les éléments se partagent l'espace restant disponible: on retire la taille naturelle des éléments de l'espace disponible, et on partage équitablement (en fonction de grow) l'espace qui reste.

display: flex;
flex: 1 1 auto; Premier élément. Premier.
flex: 1 1 auto; 2
flex: 1 1 auto; 3

Basis à 0em

avec une basis de 0em, les éléments se partagent équitablement l'espace total (les colonnes ont alors toutes la même largeur).

display: flex;
flex: 1 1 0em; Premier élément, Premier élément, Premier élément, Premier élément
flex: 1 1 0em;Second élément
flex: 1 1 0em;Troisième élément

Comparez avec :

display: flex;
flex: 1 1 auto; Premier élément, Premier élément, Premier élément, Premier élément
flex: 1 1 auto;Second élément
flex: 1 1 auto;Troisième élément

Basis fixée à un pourcentage

On peut aussi décrire basis avec un pourcentage. Ici, le troisième élément a une basis de 80%. Du coup, il ne reste plus beaucoup d'espace pour les autres.

display: flex;
flex: 1 1 0em;Premier élément, Premier élément, Premier élément, Premier élément
flex: 1 1 0em;Second élément
flex: 1 1 80%;Troisième élément
En ajoutant la possibilité de placer les éléments en plusieurs couches (avec wrap), on pourra utiliser une largeur de 100% pour occuper tout une ligne:
display: flex; flex-flow: row wrap;
flex: 1 1 0em;Premier élément, Premier élément, Premier élément, Premier élément
flex: 1 1 0em;Second élément
flex: 1 1 100%;Troisième élément
...
...
...
...
...
...

Grow

grow permet de fixer comment l'espace disponible sera réparti. Un élément avec un grow de 4 récupèrera 4 fois plus d'espace disponible qu'un élément avec un grow de 1. Un élément avec un grow de 0 ne sera pas étendu.

Avec une basis de 0em, si l'élément central un un coefficient grow de 4, il prend 4 fois plus de place qu'un élément avec un grow à 1.

display: flex;
flex: 1 1 0em; Premier élément, Premier élément, Premier élément, Premier élément
flex: 4 1 0em; Second élément
flex: 1 1 0em; Troisième élément

Même chose, mais avec basis=auto : s'il n'y a pas d'espace à répartir, c'est l'élément avec le plus de contenu qui sera le plus large. S'il y a de l'espace, il sera partagé selon la valeur de grow

display: flex;
flex: 1 1 0em; Premier élément, Premier élément, Premier élément, Premier élément
flex: 4 1 0em; Second élément
flex: 1 1 0em; Troisième élément

Shrink à zéro

Si on place le shrink du premier élément à 0, il n'est plus capable de diminuer, et essaie d'être sur une seule ligne

display: flex;
flex: 1 0 auto; Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément
flex: 1 1 auto; Second élément
flex: 1 1 auto; Troisième élément

Utilisation de flex-flow

Se place sur le parent ; permet

Exemple : ici, les éléments sont tous en flex 1 1 auto, et flex-flow est row wrap. Le premier élément prend sa taille naturelle, qui est de la largeur de la page, et repousse les deux autres sur la ligne suivante.

Dans le cas présent, les éléments ont les mêmes caractéristiques ; c'est juste la taille du contenu de la première case qui déclenche la mise en page sur plusieurs rangées.

display: flex; flex-flow: row wrap;
flex: 1 1 auto;Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément
flex: 1 1 auto;Second élément
flex: 1 1 auto;Troisième élément
En enlevant du contenu au premier élément, on obtient :
display: flex; flex-flow: row wrap;
flex: 1 1 auto;Premier élément, Premier élément
flex: 1 1 auto;Second élément
flex: 1 1 auto;Troisième élément

Quelques essais en jouant sur les paramètres

En fixant une basis différente d'auto ou zéro, on se donne une taille de départ en dessous de laquelle on aura recours à un saut de ligne.
display: flex; flex-flow: row wrap;
flex: 2 1 10em; Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément
flex: 1 1 10em; Second élément
flex: 1 1 10em; Troisième élément Troisième élément Troisième élémentTroisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément
display: flex; flex-flow: row wrap;
flex: 2 1 10em; Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément
flex: 2 1 0em; Second élément
flex: 2 1 0em; Troisième élément Troisième élément Troisième élémentTroisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément

Usage de flex-direction : column ;

Dans le cas des colonnes, les éléments de la même colonne ont normalement une même largeur, et remplissent la colonne.

Contrairement à la largeur d'une ligne, la hauteur d'une colonne n'est pas bornées par les limites de l'écran.

display: flex; flex-flow: column nowrap;
Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément, Premier élément,
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
Second élément
Troisième élément

L'utilisation de column wrap est beaucoup plus compliquée, et ne fonctionne bien que si les éléments ne sont pas trop larges.

Utilisation pour une mise en page complexe

Flow permet de créer très facilement des mises en pages complexes et adaptatives (« responsive »).

Dans l'exemple qui suit, en-tête et pied de page prennent toute la largeur de l'écran ; le reste de la page est sur trois colonnes, sauf s'il y a moins de 30em d'espace disponible, auquel cas, les éléments se placent les uns en dessous des autres.

display: flex; flex-flow: row wrap;
flex 1 1 100%; En-tête
flex 0 0 10em; Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche. Côté gauche.
flex 1 1 10em; Contenu de la page.
flex 0 0 10em; Troisième élément Troisième élément Troisième élémentTroisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément Troisième élément
flex 1 1 100%; Pied de page

Autres propriétés

order

justify-content, align-items, align-content, align-self

Permettent de régler la disposition des éléments les uns par rapport aux autres et leur espacement dans le conteneur.

inline-flex

Un élément en display flex fonctionne extérieurement comme un bloc. Si on veut le placer à côté d'un autre élément, il faut utiliser inline-flex.