title: Le petit flexbox illustré
url: http://www.vincent-valentin.name/articles/le-petit-flexbox-illustre
hash_url: fbd6c4abb6
Flexbox est un nouveau module d’affichage CSS qui apporte quelques possibilités graphiques jusqu’alors impossibles et qui permet aussi de grandement simplifier les constructions habituelles.
Son principal frein reste le support limité à IE 10+ (pas de souci pour la majorité des autres navigateurs), mais au regard des nouveautés offertes, il est d’ores et déjà intéressant d’en comprendre le fonctionnement et de résoudre certaines problématiques grâce à celui-ci.
Déclencher un affichage flexbox passe par la propriété display
.
Flexbox diffère un peu des types d’affichages habituels car le changement va ici non seulement impacter l’élément sélectionné, mais également ses enfants directs.
Ainsi on parlera de flex-container et de flex-items ; et il sera possible de passer des propriétés spécifiques à ces deux composants.
Il sera tout à fait possible aussi qu’un élément soit à la fois un flex-items et un flex-container : autrement dit, les imbrications flexbox sont possibles.
La courbe d’apprentissage du module peut paraître abrupte au premier abord. C’est sans compter les simplifications que permettent des outils comme autoprefixer, qui viennent gommer les historiques de nommages et d’implémentations qui ont été faites.
En effet flexbox en est toujours au stade du brouillon et a déjà subi trois refontes. On peut néanmoins penser qu’après un travail mené depuis plus de six ans, il soit maintenant suffisamment mature ; tout comme le statut actuel (last call) de la spécification et le nombre très faible de tickets encore ouverts le laisse entendre.
Quoi qu’il en soit, au lieu de devoir écrire :
.foo
{
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
il suffira simplement de passer par ce code pour que le post-processeur génère la même chose :
.foo
{
display: flex;
}
On retrouve alors une courbe d’apprentissage relativement douce, où la principale difficulté reste le nombre de nouveautés. Nous allons donc passer en revue chacune d’elles méthodiquement, en commençant par les propriétés qui peuvent s’appliquer au flex-container.
Retenez cependant avant tout qu’un flex-container ou un flex-item appliquent un contexte de formatage de type flex équivalent au type block
. (N’hésitez pas à lire maintenant ou plus tard l’article lié si ce concept ne vous semble pas clair.)
flex-direction
permet de gérer la direction, par défaut en ligne (row
) ; on pourra aussi la passer en colonne (column
) très facilement.
La démonstration qui suit fait alterner différents affichages à chaque clic de votre part.
(Il en sera de même sur la plupart des démonstrations de cette page.)
On pourra également inverser les flux et utiliser row-reverse
et column-reverse
.
flex-wrap
permet de gérer les débordements des flex-items dans les lignes ou dans les colonnes.
Bien que par défaut ils ne soient pas autorisés (nowrap
), il est tout à fait possible de changer ce comportement avec wrap
.
On pourra même inverser le flux et les débordements avec wrap-reverse
.
Notez que flex-direction
et flex-wrap
peuvent s’utiliser conjointement avec la propriété raccourcie flex-flow
.
Par exemple :
.bar
{
flex-direction: column;
flex-wrap: wrap;
}
sera équivalent à :
.bar
{
flex-flow: column wrap;
}
justify-content
aligne les flex-items le long de l’axe principal.
On parle d’axe principal et d’axe secondaire plutôt que d’axe vertical et horizontal car cela varie en fonction de la direction.
Par défaut les éléments sont empilés en début de flux (flex-start
). Ils pourront l’être en fin de flux (flex-end
), au milieu (center
), espacés entre eux au maximum (space-between
) ou espacés chacun d’eux par une marge identique (space-around
).
Vous remarquerez quelques petites animations CSS qui permettent de mieux comprendre comment sont effectuées certaines répartitions d’espaces.
Les enfants du flex container sont alignés :
align-items
au niveau de chaque ligne ;align-content
au niveau de l’ensemble des lignes (il en faut donc plusieurs pour en constater l’effet).align-items
prend par défaut la valeur stretch
, et accepte également flex-start
, flex-end
, center
et baseline
.
align-content
prend par défaut la valeur stretch
, et accepte également flex-start
, flex-end
, center
, space-between
et space-around
.
flex-items
Passons maintenant aux propriétés qui s’appliquent sur les enfants directs du flex-container et commençons par la plus riche : flex
.
Ne confondez pas : nous avons vu plus haut ce mot-clef comme une nouvelle valeur de display
; il s’agit maintenant d’une nouvelle propriété.
flex
est une propriété raccourcie qui combine flex-grow
, flex-shrink
et flex-basis
.
.baz {
flex: 0 1 auto;
}
a donc pour équivalent :
.baz {
flex-grow: 0; flex-shrink: 1; flex-basis: auto;
}
flex-grow
définit les possibilités d’étirements d’un élément,flex-shrink
ses possibilités de contractions,flex-basis
sa dimension initiale.Par étirement et contraction, comprenez par là qu’un élément pourra voir sa taille surchargée afin de répondre au mieux à vos conditions et au contexte d’affichage courant.
flex-grow
ne permet pas d’étirement quand il est à 0
, il faut passer un nombre positif plus ou moins important pour changer ce comportement par défaut.
Nous expliciterons un peu plus loin (avec flex-basis
) la méthode de calcul qui définit les agrandissements.
flex-shrink
a pour valeur initiale 1 : la contraction est donc possible par défaut. On pourra lui passer un nombre nul ou un nombre positif pour annuler ou amplifier ce comportement.
Plus un flex-shrink
sera important, plus l’élément sera à même d’être compressé.
Comment sont calculées les compressions ?
Lorsque les facteurs de compression sont identiques, les proportions entre les éléments sont conservées.
Dans le prochain exemple la taille du conteneur est revue (et animée) de manière à compresser les flex-items dont les largeurs sont définies en pixels.
On constate une largeur identique entre le premier flex-item et les trois suivants quelle que soit la taille du flex-container.
Et il en va de même pour les largeurs des trois derniers flex-items qui restent identiques.
Vous aurez peut-être noté que la largeur initiale des éléments intervient dans les calculs. Ainsi un élément deux fois plus large qu’un autre (et pourtant le même facteur de compression) se verra proportionnellement deux fois plus compressé si nécessaire.
Quand les facteurs de compression sont différents, l’espace retiré lors de la compression est aussi proportionnel au facteur de compression.
On constate ici que l’espace retiré du dernier flex-item est trois fois plus grand que sur le second ; ainsi que deux fois plus grand que sur le troisième.
Aucun espace n’est par contre retiré du premier.
Ce sont donc les facteurs de compressions et les tailles initiales des éléments qui influent sur le taux de compression possible de chacun.
flex-basis
est une propriété qui hérite par défaut (avec la valeur auto
) de la largeur (width
) ou de la hauteur (height
) d’un élément, et ce en fonction de la direction définie sur le flex-container.
Elle peut aussi prendre une valeur qui viendra surcharger cette dimension.
flex-basis
va également redéfinir la taille minimale d’un élément (min-width
ou min-height
) et faire passer sa valeur par défaut de 0
à auto
.
On peut ainsi définir un flex-basis
à 0
, tout en conservant visuellement une taille minimale pour l’élément.
Comment sont calculés les agrandissements ?
Ce qui est très intéressant avec flex-basis
, c’est qu’il entre en jeu pour les calculs de dimensionnement : sa valeur va donc considérablement influencer les comportements d’agrandissement.
flex-basis
est à 0
, c’est la taille des flex-items qui sera revue ;flex-basis
est à auto
, c’est l’espace restant qui sera revu.align-items
(que nous avons vu plus haut) permet de justifier tous les éléments au sein d’un conteneur.
align-self
permet de cibler individuellement ses enfants.
Par défaut il est à auto
et hérite du comportement du flex-container mais on retrouve les même valeurs possibles que pour align-items
. À savoir : flex-start
, flex-end
, center
, baseline
et stretch
.
order
accepte uniquement des nombres entiers (négatifs ou positifs) et permet d’ordonner les éléments dans le flux. Il est fixé à 0
par défaut.
Les ordres qui sont appliqués aux éléments sont alors classés par ordre croissant et c’est tout le flux d’affichage qui peut s’en retrouver modifié.
Outre cette compréhension basique des propriétés, il faudra bien sûr à l’avenir mieux appréhender l’utilisation de ce nouveau module. Agencements de propriétés, dégradations possibles, bugs…
Par bien des aspects, je trouve que flexbox mélange les avantages des flottants et les avantages des tableaux. Nul doute : si vous êtes amenés à travailler dans des contextes responsifs, les possibilités offertes par flexbox vous intéresseront.
Voici pour compléter une liste de liens sur le sujet :
Bonnes lectures et bonnes expérimentations à tous.