Une Flexbox, c'est une boîte conteneur que l'on appelle le flex-container et qui contient d'autres boîtes, que l'on appelle les flex-items. La spécificité réside dans le fait que, le programmeur, à travers les propriétés du flex-container va avoir un contrôle quasi total, sur la répartition des flex-items dans ce dernier.
Par contrôle, on entend, la répartition des flex-items dans le flex-container, leur taille, leur position, leur étirement, leur rétrécissement, leur ordre, le retour à la ligne ect. Le contrôle se limite aux flex-items pas à leur contenu.
Le fait d'avoir un contrôle total entraîne une certaine complexité, avec un nombre important de propriétés CSS et de valeurs différentes.
La répartition des flex-items se fait selon deux axes, l'axe principal et l'axe secondaire. Par défaut, l'axe principal est horizontal et la distribution des flex-items se fait de la gauche vers la droite. L'axe secondaire est toujours à angle droit avec l'axe principal et la distribution se fait par défaut du haut vers le bas. On retrouve ici, le sens de l'écriture du texte sur une page écrite par exemple en français.
Suivant les valeurs de la propriété flex-direction l'axe principal se trouve orienté de cette manière.
Ci-dessous, je teste les quatre valeurs de la propriété flex-direction. Soit row puis row-reverse puis column puis column-reverse.
Dans cet exemple, la propriété flex-direction a la valeur row, et les flex-items sont placés sur le côté gauche du flex-container, sur l'origine de l'axe principal.
Dans cet exemple, la propriété flex-direction a la valeur row-reverse, et les flex-items sont placés sur le côté droit du flex-container, sur l'origine de l'axe principal. Cette fois, l'axe principal est dirigé de la droite vers la gauche.
Dans cet exemple, la propriété flex-direction a la valeur column, et les flex-items sont placés en haut du flex-container, sur l'origine de l'axe principal. Cette fois, l'axe principal est dirigé du haut vers le bas.
Dans cet exemple, la propriété flex-direction a la valeur column-reverse, et les flex-items sont placés en bas du flex-container, sur l'origine de l'axe principal. Cette fois, l'axe principal est dirigé du bas vers le haut.
Maintenant, je souhaite rendre cette structure responsive. Ultra simple ! Une média query que j' exploite pour changer la valeur de la propriété flex-direction. Je la passe de la valeur row, qui me donne un affichage en ligne à la valeur column, qui me donne un affichage en colonne. Ma vie de développeur front-end vient de changer 😂 .
Cette propriété gère la distribution des emplacements des flex-items suivant la place disponible dans le flex-container. Elle le fait, selon le positionnement de l'axe principal. Les valeurs possibles sont les suivantes :
flex-start valeur par défaut
flex-end
center
space-around
space-between
space-evenly
Ci-dessous, un code de test qui va me servir pour tester les différentes valeurs de la propriété justify-content.
Dans cet exemple, justify-content vaut flex-start. Avec un flex-direction qui vaut row, les flex-items se placent dans l'ordre du HTML sur le bord gauche du flex-container. Il n'y a aucun espace entre eux. L'espace disponible dans le flex-container est laissé à droite.
Dans cet exemple, justify-content vaut flex-end. Avec un flex-direction qui vaut row, les flex-items se placent dans l'ordre du HTML sur le bord droit du flex-container. Il n'y a aucun espace entre eux. L'espace disponible dans le flex-container est laissé à gauche.
Dans cet exemple, justify-content vaut center. Les flex-items se placent dans l'ordre du HTML au centre du flex-container. Il n'y a aucun espace entre eux. L'espace disponible dans le flex-container est laissé de part et d'autre du groupe de flex-items.
Dans cet exemple, justify-content vaut space-around. Un espace est laissé entre les flex-items, qui vaut le double de celui, qui est laissé sur les côtés du flex-container.
Dans cet exemple, justify-content vaut space-evenly. Tout l'espace disponible est réparti équitablement entre les flex-items et les bords du flex-container.
Cette propriété gère l'alignement des flex-items selon l'axe secondaire du flex-container. Nous allons devoir spécifier une hauteur à notre flex-container pour qu'un alignement puisse être calculé.
Les valeurs que peut prendre la propriété align-items sont les suivantes :
stretch valeur par défaut
flex-start
flex-end
center
baseline
Ci-dessous, un code de test, qui va me servir pour tester les différentes valeurs de la propriété align-items.
Ci-dessous, j'utilise le code précédent dans lequel je spécifie la valeur de la propriété align-items. Je teste toutes les valeurs possibles. L'axe secondaire est dirigé du haut vers le bas.
Dans cet exemple, le flex-container fait 150px de haut et il n'y a pas de hauteur sur les flex-items. Si la propriété align-items vaut stretch, les flex-items vont être étirés sur toute la hauteur du flex-container.
Dans cet exemple, et dans tous ceux qui suivent, je mets une hauteur de 70px sur les flex-items. Ci-dessous, avec la valeur flex-start, les flex-items sont alignés sur le bord haut du flex-container qui est le début de l'axe secondaire.
Ci-dessous, avec la valeur baseline, les flex-items sont placés de sorte que leurs contenus soient alignés sur une ligne. Cette ligne est elle-même placée au centre du flex-container.
Que se passe-t-il, si on réduit la taille du flex-container ? C'est la propriété flex-wrap qui permet de gérer cette situation.
nowrap valeur par défaut.
wrap
wrap-reverse
Si flex-wrap vaut nowrapet que les flex-items sont dans leur configuration par défaut, alors les flex-items seront rétrécis, si le flex-container est lui-même suffisamment rétréci.
Les deux lignes (ou plus) de flex-items sont réparties, au centre du flex-container. L'espace disponible est équitablement réparti, de part et d'autre, de ces deux lignes.
L'espace disponible est réparti entre les deux lignes de flex-items et les bords du flex-container. L'espace sur les bords vaut la moitié de l'espace entre les lignes.
Lorsque les flex-items sont répartis sur plusieurs lignes, c'est la propriété align-content qui gère cette répartition. Ça veut dire que vous avez deux possibilités de répartition des flex-items sur l'axe secondaire.
Un première possibilité, gérée par align-items, lorsqu'il n'y a qu'une seule ligne de flex-items.
Une deuxième possibilité, gérée par align-content, lorsqu'il y a plus d'une ligne de flex-items.
Je donne un exemple, ci-dessous, qui exploite ces possibilités.
Par défaut, l'ordre d'apparition des flex-items correspond à l'ordre de leur apparition dans le code HTML. Toutefois, cet ordre peut être géré manuellement à l'aide de la propriété order. Dans ce cas, l'ordre d'apparition des flex-items devient l'ordre des entiers, sachant qu'un flex-item reçoit la valeur order:0 par défaut. Par exemple, il suffit de choisir un flex-item, de lui affecter la valeur order:-1, pour qu'il passe devant tous les autres.
Dans l'exemple ci-dessous, je réarrange l'ordre HTML et je le remplace par l'ordre des entiers.
La propriété flex-grow définit le coefficient d'étirement d'un flex-item. Sa valeur est positive ou nulle.
Si flex-grow vaut 0 alors le flex-item ne peut pas s'étirer. C'est la valeur par défaut.
Si flex-grow est différent de 0, alors le flex-item peut s'étirer. A ce moment-là, il y a plusieurs cas de figure :
S'il n'y a qu'un seul flex-item dans le flex-container, alors il prend toute la place disponible.
S'il y a plusieurs flex-items dans le flex-container, alors ceux qui ont la possibilité de s'étirer s'étirent proportionnellement à la valeur de leur coefficient flex-grow.
Ci-dessous, vous avez un exemple où j'ai mis de façon explicite une valeur de flex-grow à 0 sur tous les flex-items (bien que ce soit la valeur par défaut).
Ci-dessous, j'ai fait un exemple, où tous les flex-items ont un coefficient d'étirement de 1. Ils vont tous s'étirer équitablement pour occuper tout l'espace disponible.
Dans l'exemple ci-dessous, le deuxième élément a un coefficient d'étirement de 3. Il va s'étirer "3 fois plus vite" que ses deux voisins qui ont un coefficient d'étirement de 1.
La propriété flex-shrink définit le coefficient de rétrécissement d'un flex-item. Sa valeur est positive ou nulle.
La valeur par défaut de flex-shrink vaut 1 donc par défaut les flex-items peuvent se rétrécir.
Par contre, pour qu'un flex-item puisse se rétrécir, il faut qu'on lui ait donné une taille supérieure à la taille de son contenu. Cela peut être fait de plusieurs manières. On peut utiliser width ou flex-basis.
Si flex-shrink vaut 0, alors le flex-item ne peut pas se rétrécir.
Si flex-shrink est différent de 0, alors le flex-item peut se rétrécir. A ce moment-là, il y a plusieurs cas de figure :
S'il n'y a qu'un seul flex-item dans le flex-container, alors il est le seul à se rétrécir lorsque la taille du flex-container diminue.
S'il y a plusieurs flex-items dans le flex-container, alors ceux qui ont la possibilité de se rétrécir se rétrécissent proportionnellement à la valeur de leur coefficient flex-shrink.
Ci-dessous, vous avez un exemple dans lequel j'ai mis de façon explicite une valeur de flex-shrink à 0 sur tous les flex-items. J'ai mis également une taille de 250px en utilisant flex-basis. Lorsque la taille du flex-container diminue, les flex-items ne peuvent pas se rétrécir et il y a débordement.
Ci-dessous, j'ai fait un exemple dans lequel tous les flex-items ont un coefficient de rétrécissement de 1. Ils vont tous se rétrécir équitablement si l'espace disponible diminue.
Dans l'exemple ci-dessous, le deuxième élément a un coefficient de rétrécissement de 3. Il va se rétrécir "3 fois plus vite" que ses deux voisins qui ont un coefficient de rétrécissement de 1.
Il faut voir la valeur de flex-basis comme une valeur de base. En fait, c'est la valeur qu'auraient les flex-items, s'ils n'étaient pas sous le contrôle du flex-container. Le flex-container va les rétrécir ou les grandir selon les contraintes de flexibilité (flex-grow / flex-shrink / taille du flex-container).
Si aucune valeur n'est précisée pour flex-basis, (auto par défaut) les flex-items auront la taille spécifiée dans width ou height.
Comme pour un div, width et height sont soumis aux contraintes liées aux valeurs de min-width / max-width et min-height / max-height.
En l'absence de width / height et des contraintes que je viens de citer, les flex-items prendront la taille de leur contenu.
Il faut remarquer que la propriété flex-basiscorrespond à la largeur ou à la hauteur des flex-items selon la valeur de flex-direction.
Dans cet exemple, la valeur de flex-basis en pixels correspond à la largeur des flex-items, car flex-direction vaut row (ou row-reverse).
Dans cet exemple, la valeur de flex-basis en pixels correspond à la hauteur des flex-items, car flex-direction vaut column (ou column-reverse).
La taille des flex-items sera bornée par les valeurs min-width / max-width ou min-height / max-height.
Dans cet exemple, la valeur de flex-basis en pixels vaut au maximum max-width.
Dans cet exemple, la valeur de flex-basis en pixels vaut au minimum min-width.
Dans cet exemple, une taille est spécifiée à la fois sur flex-basis et sur width et c'est celle du flex-basis qui est prise.
C'est un raccourci qui combine dans l'ordre les valeurs de flex-grow, flex-shrink, flex-basis
initial équivalent à la combinaison 0 1 auto valeur par défaut
auto équivalent à la combinaison 1 1 auto
none équivalent à la combinaison 0 0 auto
entier positif équivalent à la combinaison entier positif 1 0
J'attire votre attention sur le fait que l'utilisation d'un flex:3; va impliquer une valeur de flex-basis de 0. Ce n'est pas équivalent à un flex-grow:3; en laissant flex-basis à sa valeur par défaut qui est auto. L'utilisation de l'espace disponible ne sera pas identique dans les deux cas. La spécification contient des précisions sur ces particularités.