FlexBox

Introduction à Flexbox

FlexBox : un module CSS3

Flexbox Layout est un module qui fournit une façon efficace de disposer, aligner et distribuer l'espace entre les blocs enfants d'un bloc container, même lorsque leurs dimensions sont inconnues et/ou dynamiques.

  • Spécification CSS3
  • C'est un ensemble de propriétés
  • Des propriétés qui concernent le container
  • Des propriétés qui concernent les enfants

Comportement de FlexBox

Flex attribue plusieurs possibilités à l'élément container

  • Changer la hauteur et la largeur de ses blocs enfants
  • Oprimiser le remplissage de l'espace disponible
  • Adapter la taille des blocs enfants à différentes résolutions (mobile/tablette/laptop)
  • Augmenter ou diminuer la taille des blocs enfants pour éviter les débordements

Flex vs. inline & block

La principale caractéristique du positionnement Flex est qu'il n'est pas rigide, au sens directionnel.

Block et Inline

Block

  • Empilement vertical
  • Pas de bloc à gauche, pas de bloc à droite
  • Ordre des blocs défini par l'ordre des balises dans le code

Inline & Inline-block

  • Alignement horizontal des blocs les uns à la suite des autres
  • Retour à la ligne si le container n'est pas assez grand
  • Ordre des blocs défini par l'ordre des balises dans le code
  • Prise en compte des espaces

Flex

  • Alignement vertical ou horizontal
  • Rétrécissement ou agrandissement des blocs selon l'espace disponible
  • Ordre des blocs défini par défaut par l'ordre des balises dans le code
  • Possibilité de réordonner indépendamment chaque bloc les uns par rapport aux autres
  • Possibilité de réordonner indépendamment chaque bloc par rapport à l'ordre du code

Le code minimal

Le module FlexBox s'active avec la combinaison propriété/valeur display: flex;

Les valeurs autorisées

  • flex dans le cas où le container doit avoir un comportement d'empilement vis à vis de ses éléments frères
  • inline-flex dans le cas où le container accepte d'être aligné avec des éléments frères

Un exemple basique



Et prima post Osdroenam quam, ut dictum
Vita est illis semper in fuga
Ut enim quisque sibi plurimum
Quam ob rem ut ii qui superiores
Minime hercule! ac ne ego quidem


Le CSS

.parent { display: flex; } .enfant:nth-child(even){ background-color: orange; }

Le HTML

<section class="parent"> <div class="enfant">Et prima post Osdroenam quam, ut dictum</div> <div class="enfant">Vita est illis semper in fuga</div> <div class="enfant">Ut enim quisque sibi plurimum</div> <div class="enfant">Quam ob rem ut ii qui superiores</div> <div class="enfant">Minime hercule! ac ne ego quidem</div> </section>

Comparatif Flex / Inline-block / Block

Flex

Et prima post Osdroenam quam, ut dictum
Vita est illis semper in fuga
Ut enim quisque sibi plurimum
Quam ob rem ut ii qui superiores
Minime hercule! ac ne ego quidem

Le CSS

.container { display: flex; } .child {}

Inline-block

Et prima post Osdroenam quam, ut dictum
Vita est illis semper in fuga
Ut enim quisque sibi plurimum
Quam ob rem ut ii qui superiores
Minime hercule! ac ne ego quidem

Le CSS

.container {} .child { display: inline-block; }

Block

Et prima post Osdroenam quam, ut dictum
Vita est illis semper in fuga
Ut enim quisque sibi plurimum
Quam ob rem ut ii qui superiores
Minime hercule! ac ne ego quidem

Le CSS

.container {} .child {}

Les axes de positionnement

Axes directionnels

On distingue deux axes de références en positionnement Flex

  • L'axe principal (main axis)
  • L'axe transversal

Ce sont les axes que vont suivre les blocs enfants pour se positionner.

Définir la direction de l'axe principal

flex-direction est la propriété qui va spécifier la direction principale

Les valeurs de flex-direction

  • row définit un positionnement en ligne (valeur par défaut)
  • column définit un positionnement en empilement

Inverser l'ordre des blocs

  • row-reverse
  • column-reverse

Exemples avec flex-direction

flex-direction: row;



1
2
3
4
5


Le CSS

.container { display: flex; flex-direction: row; } .child {}

Le HTML

<section class="container"> <div class="child">1</div> <div class="child">2</div> <div class="child">3</div> <div class="child">4</div> <div class="child">5</div> </section>

flex-direction: column;



1
2
3
4
5


Le CSS

.container { display: flex; flex-direction: column; } .child {}

Des valeurs supplémentaires :

  • row-reverse
  • column-reverse

Distribuer l'espace entre les blocs

La propriété justify-content permet de distribuer l'espace restant entre les blocs dans le cas où ceux-ci n'occupe pas toute la largeur disponible.

Utilisation par défaut

justify-content: flex-start; est la valeur par défaut lorsqu'elle pas précisée.

Les Gremlins
Harry Potter
Starwars
Les Goonies
Ça

Aligner à droite

Les Gremlins
Harry Potter
Starwars
Les Goonies
Ça

Le CSS

.container { display: flex; justify-content: flex-end; } .child {}

La valeur flex-end aura l'effet inverse : un alignement à droite.

Distribuer l'espace équitablement

Les valeurs space-between et space-around permettent de répartir l'espace équitablement autour des blocs.

Répartition autour des blocs

Gremlins
L'Histoire sans fin
Starwars Episode V
Les Goonies
ET

Le CSS

.container { display: flex; justify-content: space-around; } .child {}

Le HTML

<section> <div>Gremlins</div> <div>L'Histoire sans fin</div> <div>Starwars</div> <div>Les Goonies</div> <div>ET</div> </section>

Répartition équitable bords à bords

Gremlins
L'Histoire sans fin
Starwars Episode V
Les Goonies
ET

Le CSS

.container { display: flex; justify-content: space-between; } .child {}

Le HTML

<section> <div>Gremlins</div> <div>L'Histoire sans fin</div> <div>Starwars</div> <div>Les Goonies</div> <div>ET</div> </section>

Aligner les blocs les uns par rapport aux autres

align-items permet de choisir un type d'alignement entre les blocs enfants.

C'est plus ou moins l'équivalent de vertical-align combinée à display: inline-block;

  • flex-start les blocs s'alignent par le haut
  • flex-end les blocs s'alignent par le haut
  • center les blocs se centrent les uns par rapport aux autres
  • baseline les blocs s'alignent sur la ligne typographique
  • stretch les blocs s'étirent pour avoir tous la même hauteur (valeur par défaut)

Exemple avec des items centrés

Gremlins
L'Histoire sans fin
Starwars Episode V
Les Goonies
ET

Le CSS

.container { display: flex; align-items: center; justify-content: space-around; } .child {}

Le HTML

<section> <div style="height: 50px">Gremlins</div> <div style="height: 150px">L'Histoire sans fin</div> <div style="height: 70px">Starwars Episode V</div> <div style="height: 300px">Les Goonies</div> <div style="height: 200px">ET</div> </section>

align-items pour harmoniser la hauteur des blocs

align-items a la capacité d'harmoniser la hauteur des blocs enfants

Avec la valeur align-items: stretch; la hauteur des blocs est harmonisée sur celui possédant la plus grande hauteur

Exemple avec des blocs de hauteur forcée

Gremlins

Caesar nullum post haec adhibens modum primatibus nec plebeiis.

L'Histoire sans fin

Vitalic disseminata

Starwars Episode V

Latius iam bonis omnibus Caesar nullum post haec adhibens modum orientis latera cuncta vexabat nec honoratis parcens nec urbium primatibus nec plebeiis adhibens modum orientis latera cuncta adhibens modum orientis latera cuncta.

Les Goonies

Giorgio iam .

ET

Latius iam disseminata licentia vexabat nec honoratis parcens nec urbium primatibus nec plebeiis.

Le CSS

.container { display: flex; } .child {}

align-items: stretch; est la valeur par défaut de align-items, il n'est donc pas nécessaire de le préciser

La valeur strech ne fonctionne pas si les blocs sont pourvus de propriétés height ou max-height

Flex-basis pour attribuer une largeur

flex-basis est la propriété équivalente à width pour le module FlexBox

Note : si flex-basis et width sont utilisés en même temps, flex-basis prendra l'ascendant

Exemple

On va forcer la largeur des blocs à 150px;

Gremlins

Caesar nullum post haec adhibens modum primatibus nec plebeiis.

L'Histoire sans fin

Vitalic disseminata

Starwars Episode V

Latius iam bonis omnibus Caesar nullum post haec adhibens modum orientis latera cuncta vexabat nec honoratis parcens nec urbium primam orientis latera cuncta.

Les Goonies

Giorgio iam .

ET

Latius iam disseminata licentia vexabat nec honoratis parcens nec urbium primatibus nec plebeiis.

Le CSS

.container { display: flex; justify-content: space-between; } .child { flex-basis: 150px; }

La valeur flex-basis sera surchargée si les blocs sont pourvus de propriétés max-width ou min-width

Grossissement et retrécissement

Dans le module FlexBox, les blocs enfants ont la capacité de se dilater ou de se contracter pour remplir au mieux l'espace à disposition

Les propriétés CSS

Il existe deux propriétés CSS qui s'appliquent aux blocs enfants

  • flex-shrink spécifie la capacité à se contracter
  • flex-grow spécifie la capacité à se dilater

Le saviez-vous ?

La capacité des blocs enfant à tous tenir à l'intérieur de leur container quelque soit leur contenu provient de la propriété flex-shrink qui leur permet de se contracter

La capacité de grossissement

flex-grow est une propriété qui pilote la capacité de dilatation d'un bloc enfant

flex-grow est une propriété enfant, c'est à dire qu'elle s'applique sur les blocs enfants

Valeurs de flex-grow

Cette propriété accepte des valeurs numériques entières positives

  • 0 (la valeur par défaut)
  • 1
  • 2
  • ...

Fonctionnement

Si flex-grow possède la valeur 0, cela signifie que le bloc n'a pas l'autorisation de grossir

Sa taille sera donc définie par :

  • flex-basis
  • ...ou bien son contenu

Flex-grow in action

Exemple

On va autoriser les blocs à grossir pour occuper au mieux l'espace

1
2
3
4
5

Le CSS

.container { display: flex; } .child { flex-grow: 1; }

Le HTML

<section> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> </section>

Des flex-grow différents

Que se passe t-il si on assigne des valeurs de flex-grow différents à chaque blocs ?

Essai avec 3 valeurs différentes

Les blocs se dimensionnent relativement par rapport à leur valeur de flex-grow respectives, et selon l'écart qui existe entre la plus grande valeur de flex-grow et la plus petite

1
2
3
4
5

Le CSS

.container { display: flex; } .child { flex-grow: 1; } .child:nth-child(2) { flex-grow: 2; } .child:nth-child(5) { flex-grow: 3; }

Le HTML

<section> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> </section>

La capacité de retrécissement

flex-shrink est une propriété qui pilote la capacité d'un bloc enfant à se contracter

flex-shrink est une propriété enfant, c'est à dire qu'elle s'applique sur les blocs enfants et pas sur le container

Valeurs de flex-shrink

Cette propriété accepte des valeurs numériques entières positives

  • 0
  • 1 (la valeur par défaut)
  • 2
  • ...

Fonctionnement

Si flex-shrink possède la valeur 0, cela signifie que le bloc n'a pas l'autorisation de retrécir

Sa taille sera donc définie par :

  • flex-basis
  • ...ou bien son contenu

Si les blocs ont interdiction, ils dépasseront de leur container. On assistera à un overflow

Flex-shrink in action

Exemple

On va autoriser des blocs trop gros à retrécir pour occuper au mieux l'espace

1
2
3
4
5

Le CSS

.container { display: flex; } .child { flex-basis: 250px; flex-shrink: 1; }

Le HTML

<section> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> </section>

Des flex-shrink relatifs

Si les valeurs de flex-shrink sont différentes d'un enfant à l'autre, on observera le même comportement que pour flex-grow, mais inversé

  • Plus la valeur de flex-shrink est haute, plus le bloc se réduira par rapport aux autres enfants
  • Plus la valeur de flex-shrink est basse, moins le bloc se réduira par rapport aux autres enfants

Flex-shrink non autorisé

On va interdire aux blocs de retrécir

Résultat : on constate un overflow

1
2
3
4
5

Le CSS

.container { display: flex; } .child { flex-basis: 230px; flex-shrink: 0; }

Le HTML

<section> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> </section>

Les valeurs par défaut

flex-grow et flex-shrink possède des valeurs par défaut qui confèrent au comportement des containers des comportements remarquables.

Valeurs par défaut :

  • flex-grow: 0
  • flex-shrink: 1

Autrement dit...

Par défaut, les blocs ne sont pas autorisés à grossir et peuvent ne pas être amenés à remplir l'intégralité du container si leur contenu n'est pas suffisament large

...et les blocs sont forcés à retrécir si leur largeur est trop importante pour la largeur du container

C'est le comportement que l'on observe quand on ne spécifie aucune de ces deux propriétés !

Le passage à la ligne

On a vu que les blocs enfant sont forcés à l'alignement par la propriété flex-shrink

  • Si flex-shrink vaut 1, ils se serrent tous pour tenir dans le container
  • Si flex-shrink vaut 0, il y a overflow sur le container

Dans les deux cas, les blocs ne passent pas à la ligne.

Comment forcer les blocs à passer à la ligne ?

La propriété flex-wrap va spécifier le comportement des blocs enfant lorsque ceux-ci ont une largeur qui dépasse celle du container

flex-wrap est une propriété parent : elle s'applique sur le container

Les valeurs de flex-wrap

3 valeurs différentes pour flex-wrap

  • flex-wrap: nowrap (valeur par défaut)
  • flex-wrap: wrap
  • flex-wrap: wrap-reverse

Les comportements associés :

  • nowrap interdit le retour à la ligne : tous les blocs enfants se collent les uns aux autres pour tenir sur une ligne
  • wrap force le retour à la ligne : tous les blocs enfants se collent les uns aux autres et passent à la ligne quand la largeur du container va être dépassée
  • wrap-reverse force le retour à la ligne, mais les blocs sont affichés du dernier au premier (l'ordre d'affichage est inversé par rapport à l'ordre dans le code)

Dans la plupart des cas, on définit flex-wrap à la valeur wrap

Exemple avec flex-wrap

Dans l'exemple, on va assigner une valeur de flex-basis de 230 pixels, ce qui implique que la somme des largeurs des blocs enfant sera supérieure à la largeur du container

Exemple

On assigne la valeur wrap à flex-wrap

1
2
3
4
5

Le CSS

.container { display: flex; flex-wrap: wrap; } .child { flex-basis: 230px; }

Le HTML

<section> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> </section>

Répartir l'espace verticalement

Rappel

On a vu qu'il existait une propriété qui permettait de répartir l'espace entre les blocs sur l'axe horizontal, ou plutôt sur l'axe principal défini par flex-direction

Cette propriété est justify-content

Un équivalent vertical

justify-content possède un équivalent sur l'axe transversal.

La propriété align-content permet de spécifier un mode de répartition d'espace similaire mais sur l'axe transversal.

Les valeurs pour align-content

  • flex-start (valeur par défaut)
  • flex-end
  • space-between
  • space-around
  • center

Ces valeurs sont les mêmes que pour justify-content !

Exemple avec align-content

align-content ne peut s'appliquer qu'à 2 conditions :

  • si flex-wrap autorise le retour à la ligne des blocs
  • si le container possède une hauteur fixe définie par height
1
2
3
4
5
7
8
9
10
11
12
13
14
15

Exemple avec align-content : le code

Le CSS

.container { display: flex; flex-wrap: wrap; align-content: space-between; height: 400px; } .child { flex-basis: 230px; }

Le HTML

<section> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <div>...</div> <div>15</div> </section>

Exemple avec la valeur flex-end

align-content: flex-end;

1
2
3
4
5
7
8
9
10
11
12
13
14
15

Le CSS

.container { display: flex; flex-wrap: wrap; align-content: flex-end; height: 400px; } .child { flex-basis: 230px; }

Le HTML

<section> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>...</div> <div>15</div> </section>

Modifier l'ordre des blocs

Rappel

Il existe des valeurs de propriétés du module Flex qui permettent de modifier l'ordre d'affichage des éléments par rapport à leur ordre naturel dans le flux.

Exemple :

  • flex-direction: row-reverse( ou column-reverse)
  • flex-wrap: wrap-reverse

La propriété order

Il s'agit d'une propriété enfant : elle s'applique aux blocs enfant

La propriété order permet de modifier la position d'un bloc par rapport aux autres blocs enfant.

Les valeurs de order

Cette propriété accepte des valeurs numériques entières positives

  • 0 (la valeur par défaut)
  • 1
  • 2
  • ...

La valeur définit la position relative d'un bloc par rapport aux autres. Plus la valeur est élevée, plus le bloc sera repoussé loin.

order fonctionne de la même manière que z-index

Exemple avec align-content

1
2
3
4
5

Le CSS

.container { display: flex; } .child { border-right: 5px solid yellow; } .child:nth-child(1) { order: 7; } .child:nth-child(4) { order: 10; }

Le HTML

<section> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> </section>

La valeur de order n'a rien à voir avec le nombre de blocs présents dans le container.

Aligner un bloc indépendamment

Rappel

La propriété align-items permet d'aligner les items les uns par rapport aux autres

Il s'agit d'une propriété parent, qui s'applique sur le bloc container

Modifier l'alignement indépendamment sur un bloc

La propriété align-self permet de désaligner spécifiquement un bloc par rapport à tous les autres.

align-self est une propriété qui s'applique aux blocs enfant. Elle vient surcharger la propriété align-items

Les valeurs

Ce sont les mêmes que pour align-items

  • flex-start les blocs s'alignent par le haut
  • flex-end les blocs s'alignent par le haut
  • center les blocs se centrent les uns par rapport aux autres
  • stretch les blocs s'étirent pour avoir tous la même hauteur (valeur par défaut)

Exemple avec align-self

Gremlins
L'Histoire sans fin
Starwars Episode V
Les Goonies
ET

Le CSS

.container { display: flex; align-items: flex-start; justify-content: space-around; } .child { } .child:nth-child(2) { align-self: center; }

Le HTML

<section> <div style="height: 50px">Gremlins</div> <div style="height: 150px">L'Histoire sans fin</div> <div style="height: 70px">Starwars Episode V</div> <div style="height: 300px">Les Goonies</div> <div style="height: 200px">ET</div> </section>

Les propriétés raccourcies

Comme pour beaucoup de propriétés CSS, il existe des notations raccourcies qui permettent d'alléger le code, voir parfois de le rendre plus lisible

Le flow

flex-flow permet de spécifier en une propriété le comportement général du container. Cette propriété s'applique sur le container.

Ce raccourci permet de fusionner les propriétés flex-direction et flex-wrap

Exemple :

.container { display: flex; flex-flow: row wrap; } .child { }

est équivalent à :

.container { display: flex; flex-direction: row; flex-wrap: wrap; } .child { }

Sa valeur par défaut est flex-flow: row nowrap;.
Soit des blocs qui s'alignent horizontalement et qui ne passent jamais à la ligne

Raccourci sur les blocs enfant

La propriété raccourcie flex permet de spécifier en une propriété le comportement général des blocs enfants. Cette propriété s'applique sur les blocs enfant.

flex permet de fusionner les propriétés flex-grow, flex-shrink et flex-basis

Exemple :

.container { display: flex; flex-flow: row wrap; } .child { flex: 0 1 150px; }

est équivalent à :

.container { display: flex; flex-direction: row; flex-wrap: wrap; } .child { flex-grow: 0; flex-shrink: 1; flex-basis: 150px; }

Sa valeur par défaut est flex: 0 1 auto;

Soit des blocs...

  • qui ne peuvent pas se dilater même s'il reste de l'espace disponible à occuper
  • qui peuvent se contracter si besoin pour tenir à l'intérieur de l'espace disponible
  • dont la largeur est définie par leur contenu respectif