Flexbox

Posted 2024-02-29 by Sami Garcia ‐ 12 min read

À la fin de cet article, vous connaitrez tout ce qu'il y a savoir à propos des flexbox.

Flexbox CSS

Les flexbox ont trop tendance à faire peur aux développeurs débutant et intermédiaire, alors que quand on comprend enfin comment les utiliser intelligemment, elles deviennent un outil puissant et indispensable lors de la création de nos pages !

Cette confusion à l’égard des flexbox et leur image mystérieuse vient surtout du fait que les explications qu'on trouve sur internet ne sont souvent pas très claire quant à leur utilité et comment les utiliser intelligemment.

Alors dans cet article, on va voir ensemble comment bien s'en servir et comment utiliser à fond leur potentielle. Mais commençons déjà par voir ce qu'est une flexbox, et à quoi ça sert.

Qu'est ce qu'une flexbox ?

Une flexbox, comme son nom l'indique, est une boite flexible (jusqu’à là on n'est pas trop avancé).

Ça peut paraître bête, mais c'est là le principale avantage d'une flexbox, et il faut bien le garder en tête.

Dans les faits, la flexbox est un élément permettant de disposer son contenu dans la direction qu'on veut (en ligne ou en colonne), en plaçant ce même contenu dans l'espace disponible, et comme on l’a vu juste avant, en restant toujours flexible.

Mais qu'est qu'on entend réellement par flexible ?

Les flexbox font en sorte de toujours occuper tout l'espace disponible tout en gérant l'espace dédier à son contenu, afin de ne jamais avoir d'overflow (de débordements). On dit donc qu'elles sont flexibles, parce qu'elles se redimensionnent (elles-mêmes ainsi que leurs contenu) automatiquement afin d'occuper idéalement l'espace qui leurs ai dédié.

Pourquoi utiliser une flexbox ?

Les flexbox, te permettent de positionner tes éléments sans avoir à leurs donner une taille fixe. La taille de chaque élément dépendra de la taille de son contenu, de la place disponible, et des propriétés qu'on lui aura données.

C'est très pratique pour rendre ton site responsive sans avoir besoin d'utiliser 40 breakpoints.

De plus, comme on le verra dans la suite de cet article, elles te donnent une grande liberté quant au positionnement de ces éléments, autant collectivement (depuis la flexbox) qu'individuellement.

Comment on crée un flexbox ?

C'est bien de savoir à quoi sert une flexbox, mais c'est encore mieux de savoir l'utiliser !

On va commencer par créer un élément dans notre HTML et y ajouter du contenu :

<div class="parent">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
</div>

On a donc un élément parent qui contient 3 enfants.

Maintenant, on va vouloir transformer le parent en flexbox:

.parent{
    display: flex;
}

IMPORTANT ! un display flex influe sur le contenu de l’élément sur lequel il est défini, au contraire d'un display inline ou block, qui aura une influence sur le placement de ce même élément.

PS: on peut aussi utiliser display : inline-flex; ainsi, l’élément parent sera positionné en ligne avec les autres élément (d’où inline), et sera aussi une flexbox.

Maintenant qu'on sait créer une flexbox, passons aux choses sérieuses et voyons comment les ajuster à nos besoins !

Le flow

Le flow d'une flexbox, défini son comportement dans l'espace qui lui est donné ainsi que sa direction.

Direction

Les flexbox te permettent de disposer ton contenu de différente façon (on parle bien sûr ici des éléments contenus dans la flexbox). On peut les disposer en ligne ou en colonne de cette façon :

<div class="parent">
    <p class="child">1</p>
    <p class="child">2</p>
    <p class="child">3</p>
</div>
.parent{
    display: flex;
    flex-direction: row | column; /* row etant en ligne et column en colone */
}
  • Row:

  • Column:

Une autre option qui nous est donné en utilisant des flexbox, et de disposer les éléments enfants dans l'ordre inverse de leur apparition dans le code :

.parent{
    display: flex;
    flex-direction: row-reverse | column-reverse;
}
  • Row-reverse:

  • Column-reverse:

wrapping

Voyons maintenant comment gérer le comportement de notre flexbox.

Lorsque l'espace d'une flexbox est restreint, et ne lui donne plus assez de place pour afficher les éléments enfants correctement, il va falloir qu'on choisisse quel comportement elle va devoir adopter.

On a ici deux choix :

  • Soit la flexbox "wrap", c'est à dire, qu'elle fait passer un ou plusieurs éléments à la ligne inférieure quand il n'y a plus de place sur la première ligne.

  • Soit elle ne wrap pas, et les éléments réduisent leurs tailles en fonction de la taille de l’écran (ce qui peut mener à une mauvaise lisibilité ou visibilité des éléments).

Pour définir si la flexbox wrap ou ne wrap pas, rien de plus simple :

.parent{
    display: flex;
    flex-wrap: wrap | nowrap;
}

On notera que par défaut, la flexbox ne wrap pas.

  • Wrap:

  • Nowrap:

Je dois avouer vous avoir menti en disant que seulement deux choix s'offraient à nous, car en vérité il nous reste une dernière option : wrap-reverse.

Ça peut paraître un peu bizarre, mais on va voir par la suite, que ça peut être très utile.

En définissant flex-wrap à wrap-reverse, on dit à la flexbox que lorsqu'il n'y a plus de place pour garder tous les éléments sur une même ligne, il doit wrapper, mais au lieu de wrapper "en dessous" (de passer les éléments à la ligne), on veut qu'il wrap "au-dessus", j’entends par là qu'au lieux d'aller à la ligne inférieure, il ira à la ligne supérieure :

.parent{
    display: flex;
    flex-wrap: wrap-reverse;
}

voyons maintenant un exemple dans lequel cela pourrait nous être utile.

Imaginons qu'on ait un texte et une photo pour l'illustrer le tout dans une flexbox avec une direction row. Le texte se trouve à gauche et la photo à droite comme cela :

Ici lorsque la flexbox va wrap, la photo va se retrouver en dessous du texte :

Or, nous voulons que la photo soit au-dessus. C'est ici que notre wrap-reverse entre en jeux :

Flow

Avec ce qu'on vient d'apprendre, ton CSS devrait ressembler à quelque chose comme ça :

.parent{
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}

Mais une façon plus concise de gérer le flow de notre flexbox s'offre à nous.

En effet la propriété flex-flow, te permet de définir la direction et le comportement de ta flexbox en même temps.

Voyons comment ça marche :

.parent{
    display: flex;
    flex-flow: row wrap; /* l'ordre n'a pas d'importance */
}

On peut donc définir la direction et le wrapping comme on le fais dans les propriétés flex-wrap et flex-direction à l’intérieur de la propriété flex-flow.

Le placement global

Maintenant qu'on sait créer une flexbox, qu'on sait lui donner une direction et lui dire de wrap ou non, voyons comment gérer globalement le placement de son contenu.

Align-items

La propriété align-items te permet de définir le positionnement du contenu perpendiculairement à l'axe directionnelle de la flexbox.

C'est à dire que align-items alignera le contenu d'une flexbox en colonne sur cet axe :

Et d'une flexbox en ligne sur cet axe :

Voyons ensemble quelles options s'offrent à toi :

  • flex-start:

    Aligne le contenu en haut de ta flexbox.

    .parent{
      display: flex;
      align-items: flex-start;
    }
    
  • flex-end:

    Aligne le contenu en bas de ta flexbox.

    .parent{
      display: flex;
      align-items: flex-end;
    }
    
  • center:

    Aligne le contenu au centre de ta flexbox.

    .parent{
      display: flex;
      align-items: center;
    }
    
  • baseline:

    Aligne la première ligne de texte du contenu.

    .parent{
      display: flex;
      align-items: baseline;
    }
    
  • stretch:

    Étend le contenu sur toute la hauteur de la flexbox.

    .parent{
      display: flex;
      align-items: stretch;
    }
    

Justify-content

La propriété justify content te permet de positionner le contenu de ta flexbox au long de son axe directionnel.

Voici les options qui s'offrent à toi:

  • flex-start:

    Place le contenu au début de ta flexbox:

    .parent{
      display: flex;
      justify-content: flex-start;
    }
    
  • flex-end:

    Place le contenu à la fin de ta flexbox:

    .parent{
      display: flex;
      justify-content: flex-end;
    }
    
  • center:

    Place le contenu au centre de ta flexbox:

    .parent{
      display: flex;
      justify-content: center;
    }
    
  • space-between:

    Espace au maximum les éléments de ta flexbox:

    .parent{
      display: flex;
      justify-content: space-between;
    }
    
  • space-around:

    Tous les éléments auront un espacement égal à leurs deux extrémités. Ainsi, le premier et dernier élément seront espacés d'une unité de l'extrémité de la flexbox, et chaque élément sera espacé les uns des autres de 2 unités :

    .parent{
      display: flex;
      justify-content: space-around;
    }
    
  • space-evenly:

    Les éléments sont espacés de distances égales, et le premier et dernier élément sont espacés de cette même distance des extrémités de la flexbox :

    .parent{
      display: flex;
      justify-content: space-evenly;
    }
    

Gap

Le gap te permet de définir l'espacement entre les éléments de ta flexbox.

On peut le définir de plusieurs façons :

  • Tout d’abord grâce à la propriété gap en lui assignant une seule valeur :

    Ainsi, on définit un gap d'une valeur x, qui sera appliquer sur les 2 axes

    .parent{
      display: flex;
      gap: 10px;
    }
    
  • On peut aussi utiliser la propriété gap mais cette fois en lui assignant 2 valeurs :

    Ici la première valeur définira l'espacement en ligne (sur l'axe horizontal), et la deuxième valeur l'espacement en colonne (sur l'axe vertical).

    .parent{
      display: flex;
      gap: 10px 20px;
    }
    
  • On peut aussi utiliser la propriété row-gap, afin de définir l'espacement horizontal :

    .parent{
      display: flex;
      row-gap: 10px;
    }
    
  • Et pour finir column-gap pour définir l'espacement vertical :

    .parent{
      display: flex;
      column-gap: 10px;
    }
    

Les propriétés du contenu

On a maintenant passé en revue toutes les propriétés permettant de gérer le comportement général de la flexbox.

Passons maintenant pour finir aux propriétés permettant de gérer le comportement individuel d'un élément contenu dans une flexbox !

Order

Order te permet de définir l'ordre des éléments de ta flexbox. Par défaut, chaque élément de la flexbox à un order défini à 0, par conséquent, ils sont positionnés par ordre d'apparition dans l'HTML comme on a pu le voir jusqu’à présent.

Si par exemple on veut que le premier élément de la flexbox soit placé en dernier, on peut le faire de cette façon :

<div class="parent">
    <p class="first">1</p>
    <p>2</p>
    <p>3</p>
</div>
.parent{
    display:flex;
}

.first{
    order:1;
}

On se souvient que par défaut, les autres éléments on un order définis à 0. C'est pour cela que le premier élément, qui a désormais un order=1 se retrouve en dernière position.

En gros plus l'order d'un élément sera élevé, plus il sera positionné à la fin.

Align-self

On se souvient que par défaut, les autres éléments ont un order définis à 0. C'est pour cela que le premier élément, qui a désormais un order=1 se retrouve en dernière position.

En gros plus l'order d'un élément sera élevé, plus il sera positionné à la fin.

<div class="parent">
    <p class="first">1</p>
    <p>2</p>
    <p>3</p>
</div>
.parent{
    display: flex;
    align-items: flex-start;
}

.first{
    align-self: center;
}

Flex

Le flex d'un élément contenu dans une flexbox permet de définir la place qu'il va occuper, ainsi que son comportement lorsque la place va venir à manquer.

Pour le définir, on a 3 paramètres.

Flex-basis

Flex-basis va définir la taille par défaut d'un élément. Cette taille sera respectée tant que la place disponible le permettra :

<div class="parent">
    <div class="first"></div>
    <div></div>
    <div></div>
</div>
.parent{
    display:flex;
}

.first{
    flex-basis: 50%;
}

On peut utiliser des pourcentages des pixel ou n'importe quel type de valeur pour définir le flex-basis.

On voit cependant que quand la flexbox devient trop petite, le flex-basis n'est plus respecté.

Grow

Et c'est là que le flex-grow entre en jeux. Grace au flex-grow, on va pouvoir définir à quel point un élément s’étend dans l'espace donné.

Par défaut, les éléments d'une flexbox ont un flex-grow définis à 0, et plus la valeur de flex-grow d'un élément sera élevé, plus il s’étendra (et écrasera les autres éléments) dans l'espace donné :

<div class="parent">
    <div class="first"></div>
    <div></div>
    <div class="third"></div>
</div>
.parent{
    display: flex;
}

.first{
    flex-grow:1;
}
.parent{
    display: flex;
}

.first{
    flex-grow: 1;
}

.third{
    flex-grow: 2;
}

Shrink

Flex-shrink, est l'inverse de flex-grow. Il va définir à quel point un élément va laisser de place aux autres éléments. Plus sa valeur sera élevée, plus l’élément va s’écraser :

<div class="parent">
    <p class="first">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p>
    <p class="second">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p>
    <p class="third">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. </p>
</div>
.parent{
    display: flex;
}

.second{
    flex-shrink: 2;
}

.third{
    flex-shrink: 3;
}

Par défaut les éléments d'une flexbox ont un flex-shrink défini à 1.

Flex

Grace à la propriété flex, tu peux définir ces trois valeurs d'un coup :

.child{
    flex: 2 3 300px;
}

L'ordre est le suivant:

  • 1: flex-grow, ici 2
  • 2: flex-shrink, ici 3
  • 3 flex-basis ici 300px