https://www.fonderie.download/
Nous avons vu que les éléments HTML pouvaient être affichés de différentes manières et que le type d’affichage conditionnait la disposition par défaut d’un élément: affichage en bloc avec display: block;
, en ligne avec display: inline;
ou encore combiner ces valeurs avec display: inline-block;
.
Nous allons voir aujourd'hui un mode d’affichage et de disposition très puissant: la disposition selon un modèle de boites flexibles appelé flexbox avec display: flex
et les différentes propriétés CSS liées à ce modèle.
Flexbox va nous permettre de contrôler facilement et avec précision l’alignement, la direction, l’ordre et la taille de nos éléments.
Alternative beaucoup plus puissante à float
, flex permet de définir des conteneurs flexibles dont les enfants directs vont être des éléments qui vont pouvoir se réarranger (se redimensionner, se réaligner, etc.) automatiquement dans leur parent lorsque celui-ci change de dimension.
Dans les exemples que je vais vous donner ci-dessous, n'hésitez pas à copier-coller le code et le manipuler pour bien comprendre le fonctionnement de ce principe de mise en page assez complexe de prime abord.
Définissons un conteneur html comportant un certain nombre d'enfants:
xxxxxxxxxx
<div class="container">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
</div>
Nous allons définir le conteneur comme flexible en lui attribuant un display : flex
. Tous les éléments directement contenus dans ce conteneur (c’est-à-dire tous les enfants directs) vont alors automatiquement devenir des éléments flexibles.
xxxxxxxxxx
.container{
display: flex;
}
Nous pouvond maintenant manipuler chaque flex-item de manière indépendante grâce à certaines propriétés du modèle des boites flexibleset / ou leur appliquer des propriétés de disposition en tant que groupe en manipulant le conteneur flexible.
Deux axes vont intervenir dans le modèle des boites flexibles : l’axe horizontal et l’axe vertical.
La propriété flex-direction
va nous permettre de définir quel va être l’axe principal pour un conteneur flexible et ses éléments flexibles ainsi que la direction des éléments le long de cet axe. Le deuxième axe sera ainsi appelé axe secondaire.
Dupliquons donc notre container html:
xxxxxxxxxx
<div class="containerHorizontal">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
</div>
<div class="containerVertical">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
</div>
Et ajoutons le css:
xxxxxxxxxx
.containerHorizontal,
.containerVertical{
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-around;
align-content: space-around;
background-color: blue;
width: 100%;
}
.containerHorizontal{
flex-direction: row;
}
.containerVertical{
flex-direction: column;
}
.element{
flex: 1 1 50px;
width: 40%;
}
La seule différence entre ces deux conteneurs est donc que le premier est positionné en flex-direction: row;
et le second en flex-direction: column;
. Il est possible d'inverser l'ordre des éléments en utlisant les valeurs row-reverse
et column-reverse
. On passera donc de 1 2 3 à 3 2 1.
Comme vous vous en doutez, ces propriétés sont très utiles pour les versions responsives de vos sites web.
Les éléments flexibles n’ont pas le droit par défaut d’aller à la ligne (si l’axe principal est l’axe horizontal) ou de se placer sur une autre colonne (si l’axe principal est l’axe vertical). Il est possible d'outrepasser cela en utilisant la propriété flex-wrap: wrap
.
Il est possible de redéfinir complétement l'ordre des éléments avec la propriété order
et ainsi choisir leur ordre d’affichage élément par élément.
La valeur par défaut de order
est 0 et si plusieurs éléments possèdent la même valeur pour leur propriété order
ils seront affichés selon l’ordre d’écriture du code. Notez que la valeur de order
d’un élément va être comparée à celle
des autres et l’élément possédant la plus petite valeur sera affiché en premier, celui possédant la deuxième plus petite valeur en deuxième, etc.
xxxxxxxxxx
.element:nth-of-type(2){
order: -1;
}
Dans l'exemple ci-dessous, le deuxième élément vas se positionner devant, étant donné que la valeur donnée est négative, donc inférieure à 0.
Flex va nous permettre de définir l’alignement des éléments à l’intérieur du conteneur selon l’axe principal ou l’axe secondaire en se servant des propriétés suivantes :
justify-content
;align-items
;align-content
;align-self
.La propriété justify-content
va nous permettre de définir de quelle manière doit être distribué l’espace restant dans le conteneur. On va l’appliquer au conteneur et pouvoir lui passer l’une des valeurs suivantes :
flex-start
: Valeur par défaut. Les éléments vont être concentrés au début du conteneur (selon leur axe principal) ;flex-end
: Les éléments vont être concentrés à la fin du conteneur (selon leur axe principal) ;center
: Les éléments vont être centrés dans le conteneur (selon leur axe principal) ;space-between
: Les éléments vont être régulièrement distribués dans le conteneur. Les éléments se trouvant contre un bord du conteneur vont être collés au bord ;space-around
: Les éléments vont être régulièrement distribués dans le conteneur. Chaque élément va posséder le même espace et les espaces vont être cumulatifs entre deux éléments, ce qui fait que la taille de l’espace entre le conteneur et un élément contre le bord du conteneur sera deux fois plus petite qu’entre deux éléments ;space-evenly
Les éléments vont être régulièrement distribués dans le conteneur. L’espace entre le bord du conteneur et un élément sera le même que celui entre deux éléments.Vous pouvez tester toutes ces propriétés en collant ce code dans vos fichiers:
xxxxxxxxxx
<div class="conteneur ligne debut">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
<div class="element">4</div>
</div>
<div class="conteneur ligne fin">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
<div class="element">4</div>
</div>
<div class="conteneur ligne centre">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
<div class="element">4</div>
</div>
<div class="conteneur ligne space-between">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
<div class="element">4</div>
</div>
<div class="conteneur ligne space-around">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
<div class="element">4</div>
</div>
<div class="conteneur ligne space-evenly">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
<div class="element">4</div>
</div>
xxxxxxxxxx
.conteneur{
display: flex;
font-size: 20px;
background-color: blue;
border: 2px solid black;
box-sizing: border-box;
margin: 10px 0px;
}
.ligne{
flex-flow: row wrap;
}
.debut{
justify-content: flex-start;
}
.fin{
justify-content: flex-end;
}
.centre{
justify-content: center;
}
.space-between{
justify-content: space-between;
}
.space-around{
justify-content: space-around;
}
.space-evenly{
justify-content: space-evenly;
}
.element{
flex: 0 0 10%;
width: 25%;
height: 25%;
background-color: green;
padding: 10px 0px;
text-align: center;
border: 2px solid black;
box-sizing: border-box;
margin: 5px;
}
La gestion de l’alignement des éléments flexibles selon l’axe secondaire va pouvoir se faire de différentes façons et avec plusieurs propriétés :
align-items
va nous permettre de gérer l’alignement des éléments au sein d’une ligne (ou d’une colonne selon les axes principal et secondaires choisis) dans l’axe secondaire ;align-content
va nous permettre de gérer l’alignement des lignes (ou des colonnes selon l’axe) les unes par rapport aux autres dans l’axe secondaire et ne va donc avoir un effet que si nous avons plusieurs lignes (ou colonnes) d’éléments flexibles ;align-self
va nous permettre de gérer l’alignement d’un élément flexible en particulier dans l’axe secondaire.Cette propriété est l’équivalent de la propriété justify-content
mais va permettre l’alignement des éléments selon leur axe secondaire et non pas principal cette fois-ci.
Nous allons une nouvelle fois devoir définir align-items
pour le conteneur flexible et allons pouvoir lui passer les valeurs suivantes :
stretch
: Valeur par défaut. Les éléments vont s’étirer dans leur axe secondaire jusqu’à remplir tout l’espace disponible ;flex-start
: Les éléments vont être placés au début de leur conteneur en fonction de l’axe secondaire ;flex-end
: Les éléments vont être placés à la fin de leur conteneur en fonction de l’axe secondaire ;center
: Les éléments vont être placés au milieu de leur conteneur en fonction de l’axe secondaire ;baseline
: Les éléments vont être alignés dans leur axe secondaire de telle sorte à ce que leurs lignes de base (ligne imaginaire sur laquelle est écrit le texte) soient alignées.xxxxxxxxxx
<div class="conteneur stretch-sec">
<div class="element">1</div>
<div class="element petit">2</div>
<div class="element">3</div>
<div class="element petit">4</div>
</div>
<div class="conteneur debut-sec">
<div class="element">1</div>
<div class="element petit">2</div>
<div class="element">3</div>
<div class="element petit">4</div>
</div>
<div class="conteneur fin-sec">
<div class="element">1</div>
<div class="element petit">2</div>
<div class="element">3</div>
<div class="element petit">4</div>
</div>
<div class="conteneur centre-sec">
<div class="element">1</div>
<div class="element petit">2</div>
<div class="element">3</div>
<div class="element petit">4</div>
</div>
<div class="conteneur baseline-sec">
<div class="element">1</div>
<div class="element petit">2</div>
<div class="element">3</div>
<div class="element petit">4</div>
</div>
xxxxxxxxxx
.conteneur{
display: flex;
font-size: 20px;
background-color: #0AD; /*Bleu*/
border: 2px solid blue;
box-sizing: border-box;
margin: 10px 0px;
height: 100px;
}
.stretch-sec{
align-items: stretch;
}
.debut-sec{
align-items: flex-start;
}
.fin-sec{
align-items: flex-end;
}
.centre-sec{
align-items: center;
}
.baseline-sec{
align-items: baseline;
}
.element{
flex: 0 0 10%;
width: 25%;
background-color: #0DA; /*Vert*/
padding: 10px 0px;
text-align: center;
border: 2px solid green;
box-sizing: border-box;
margin: 5px;
}
.petit{
padding: 0px;
}
Le modèle des boites flexibles nous offre une dernière série de propriété qui vont nous permettre de gérer la taille des éléments et de définir leur capacité à grossir et à se rétracter en cas de besoin dans le conteneur, c’est-à-dire définir leur capacité à être « flexible ».
xxxxxxxxxx
<div class="conteneur ligne">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
</div>
<div class="conteneur colonne">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
</div>
<div class="conteneur ligne dim">
<div class="element">1</div>
<div class="element ef30">2</div>
<div class="element">3</div>
</div>
xxxxxxxxxx
.conteneur{
display: flex;
font-size: 20px;
background-color:blue;
border: 2px solid black;
box-sizing: border-box;
margin: 10px 0px;
height: 250px;
}
.ligne{
flex-flow: row wrap;
}
.colonne{
flex-flow: column wrap;
}
.element{
flex-basis: 20%;
flex-grow: 0;
flex-shrink: 0;
background-color: green;
padding: 10px 0px;
text-align: center;
border: 2px solid black;
box-sizing: border-box;
margin: 5px;
}
.dim .element{
width: 50%;
height: 50%;
}
.ef30{
flex-basis: 30%;
}
Nous définissons ici un flex-basis : 20% pour chacun des éléments flexibles ainsi qu’un flex-grow : 0 et un flex-shrink : 0 que nous allons étudier ensuite pour interdire à nos éléments de grossir ou rétrécir.
Les éléments de notre premier conteneur vont ainsi avoir une largeur de départ égale à 20% de la largeur du conteneur tandis que les éléments de notre deuxième conteneur auront une hauteur également à 20% de la hauteur du conteneur.
Dans notre troisième conteneur, nous définissons un flex-basis différent pour un élément en particulier. L’élément en question aura donc ici une largeur de départ égale à 30% de celle de son conteneur.
La propriété flex-grow
va nous permettre de définir la capacité des éléments à s’étirer dans leur conteneur pour remplir l’espace vide.
On va passer un nombre positif à flex-grow
qui va définir la quantité d’espace disponible qu’un élément doit récupérer par rapport aux autres. La valeur par défaut de flew-grow
est 0
ce qui signifie que les éléments n’ont pas le droit de grossir dans leur conteneur.
Reprenons l’exemple précédent et appliquons cette fois-ci un flex-grow : 1
aux éléments flexibles.
xxxxxxxxxx
<div class="conteneur ligne">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
</div>
<div class="conteneur colonne">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
</div>
<div class="conteneur ligne dim">
<div class="element fg1">1</div>
<div class="element ef30 fg0">2</div>
<div class="element fg3">3</div>
</div>
xxxxxxxxxx
.conteneur{
display: flex;
font-size: 20px;
background-color: blue;
border: 2px solid black;
box-sizing: border-box;
margin: 10px 0px;
height: 250px;
}
.ligne{
flex-flow: row wrap;
}
.colonne{
flex-flow: column wrap;
}
.element{
flex-basis: 20%;
flex-grow: 1;
flex-shrink: 0;
background-color: green;
padding: 10px 0px;
text-align: center;
border: 2px solid black;
box-sizing: border-box;
margin: 5px;
}
.dim .element{
width: 50%;
height: 50%;
}
.ef30{
flex-basis: 30%;
}
.fg0{
flex-grow: 0;
}
.fg1{
flex-grow: 1;
}
.fg3{
flex-grow: 3;
}
On va laisser la possibilité à nos éléments flexibles de s’étirer pour occuper l’espace vide dans le conteneur avec flew-grow : 1
. L’espace disponible dans le conteneur va donc être équitablement réparti entre les différents éléments de nos deux premiers conteneurs.
Pour notre troisième conteneur, on définit trois comportements de flex-grow différents pour nos trois éléments: notre premier élément va avoir le droit de s’étirer, le deuxième n’aura pas le droit, et le troisième aura le droit et va essayer de récupérer une quantité de l’espace restant dans le conteneur 3 fois plus importante que le premier élément.
Nous allons également pouvoir gérer leur capacité à rétrécir pour éviter que des éléments ne dépassent du conteneur avec la propriété flex-shrink.
Cette propriété va s’utiliser de manière similaire à la précédente : nous allons à nouveau pouvoir passer un nombre positif à flex-shrink
qui va indiquer la capacité des éléments à rétrécir ainsi que l’importance de leur rétrécissement les uns par rapport aux autres.
Cependant, à la différence de flex-grow
, la valeur par défaut de flex-shrink
est 1
ce qui correspond à laisser la capacité aux éléments de rétrécir.
La propriété flex-basis
va nous permettre de définir une taille de départ pour les différents éléments d’un conteneur flexible avant distribution éventuelle de l’espace vide du conteneur ou au contraire rétrécissement des éléments.
Nous allons appliquer cette propriété directement aux éléments flexibles et allons pouvoir lui passer une valeur, que nous exprimerons généralement en pourcentage de la taille du conteneur.
xxxxxxxxxx
<div class="conteneur ligne">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
</div>
<div class="conteneur colonne">
<div class="element">1</div>
<div class="element">2</div>
<div class="element">3</div>
</div>
<div class="conteneur ligne dim">
<div class="element fs1">1</div>
<div class="element ef60 fs0">2</div>
<div class="element fs3">3</div>
</div>
xxxxxxxxxx
.conteneur{
display: flex;
font-size: 20px;
background-color: blue;
border: 2px solid black;
box-sizing: border-box;
margin: 10px 0px;
height: 250px;
}
.ligne{
flex-flow: row nowrap;
}
.colonne{
flex-flow: column nowrap;
}
.element{
flex-basis: 40%;
flex-grow: 1;
flex-shrink: 1;
background-color: green;
padding: 10px 0px;
text-align: center;
border: 2px solid black;
box-sizing: border-box;
margin: 5px;
}
.dim .element{
width: 50%;
height: 50%;
}
.ef60{
flex-basis: 60%;
}
.fs0{
flex-shrink: 0;
}
.fs1{
flex-shrink: 1;
}
.fs3{
flex-shrink: 3;
}
Tout ceci n'était qu'une introduction aux possibilités offertes par Flexbox. Pour un guide complet, vous pouvez vous référer à la page de CSS tricks.
https://jsfiddle.net/EtienneOz/rsd5pe2j/3/
Utiliser les techniques flex sur l'un de vos projets que vous avez fait jusqu'à maintenant (forme géométrique, typothèque, page d'accueil, recettes)
Pensez à dupliquer vos fichiers, il faut que je garde un accès à l'ancienne version. Mettez cette nouvelle version sur Netlify en ajoutant un lien sur votre page d'accueil.
Notez que ce travail doit être responsive. En utilisant Flex astucieusement, cela est très simple.