CSS Positionnement
La propriété display
#
Par défaut, chaque boite de type block est positionnée l’une à la suite de l’autre, à la ligne. Elles peuvent être dimensionnées et les marges s’appliquent, contrairement aux éléments type inline.
Il est possible de changer le comportement initial de chaque élément à l’aide de la propriété display
.
display: block
: convertit un élément en type blockdisplay: inline
: convertit un élément en type inline
L’utilisation d’un
display: block
sur un élément inline permet notamment de pouvoir lui affecter une taille, mais l’élément crée une nouvelle ligne.
Pour ce qui est de la création d’architecture globale, il existe 2 modes de positionnement en CSS : Grid et Flexbox
Grid#
Pour réaliser une architecture simplement, le mode Grid est préconisé. Pour cela :
display: grid
pour définir un élément comme nouvelle grille
Sur cet élément, il faut alors définir les lignes et colonnes virtuelles :
grid-template-columns: 100px 1fr
pour définir les colonnes. Ici, une première colonne de 100px, puis une seconde d’une fraction de l’espace restant (unitéfr
)grid-template-rows: 100px auto 100px
pour définir les lignes. Ici, une première et dernière ligne de 100px. La seconde ligne a une hauteur basée sur le contenu de l’élément enfant
Ensuite, il ne reste plus qu’à positionner les éléments au sein de cette grille :
grid-column: 1
positionne l’élément dans la colonne 1grid-column: 1 / 3
positionne l’élément de la colonne 1 à la colonne 3 (exclue)grid-column: 1 / span 2
positionne l’élément de la colonne 1, puis s’étend sur 2 colonnes (mot-cléspan
)- idem pour les lignes avec
grid-row
Voilà un exemple de grille
Partie HTML
<body>
<header></header>
<nav></nav>
<article></article>
<footer></footer>
</body>
Partie CSS
body {
min-height: 100vh; /* 1 */
display: grid; /* 2 */
grid-template-columns: 200px 1fr; /* 3 */
grid-template-rows: 50px 1fr 50px; /* 3 */
}
header {
grid-column: 1 / span 2; /* 4 */
}
nav {
grid-column: 1; /* 5 */
grid-row: 2; /* 5 */
}
article {
grid-column: 2; /* 6 */
}
footer {
grid-column: 1 / span 2; /* 7 */
grid-row: 3; /* 7 */
}
On a donc :
- On définit une hauteur minimale de 100% de la hauteur de l’écran (unité
vh
) - On définit le mode grid
- On crée 2 colonnes (
200px
et1fr
) et 3 lignes (50px
,1fr
et50px
) - Le
<header>
est positionné dans la première colonne, et s’étend sur 2 colonnes - Le
<nav>
est positionné dans la première colonne de la seconde ligne (grid-row
est facultatif car le<header>
occupe toute la première ligne) - Le
<article>
est positionné dans la seconde colonne - Le
<footer>
est positionné dans la troisième ligne, et s’étend sur 2 colonnes
Notez qu’il est également possible d’imbriquer les niveaux de grille. Un enfant d’une grille peut définir une grille pour ses propres enfants.
Le mode Grid étant assez récent, il est préférable d’utiliser Autoprefixer pour ajouter les préfixes afin de supporter des navigateurs plus anciens
Exercice - Finalisez l’architecture des éléments#
-
Body:
- Modification du mode d’affichage vers Grid
- Création de 2 colonnes (
240px
et1fr
) - Création de 3 lignes (
auto
,1fr
etauto
)
-
Entête
- Occupe toute la première ligne
-
Menu
- Occupe la première colonne de la deuxième ligne
-
Contenu
- Occupe la deuxième colonne de la deuxième ligne
-
Menu et contenu
- Gestion des marges internes, externes
- Attention aux images qui débordent ou qui agrandissent la grille (utilisation de
max-width
)
-
Pied de page
- Occupe toute la dernière ligne
Flexbox#
Pour réaliser des composants flexibles, il existe le modèle Flexbox. Pour cela :
display: flex
pour définir un élément Flexbox
Sur cet élément, il faut alors définir ses axes que les enfants vont suivre
flex-direction
définit l’axe principal (avec les valeurscolumn
,column-reverse
,row
ourow-reverse
). Défautrow
, les enfants sont affichés les uns à coté des autres- l’axe secondaire est perpendiculaire à l’axe principal
Chaque enfant est donc flexible au sein de son parent. Sa taille est calculée en fonction de la taille déclarée en CSS et l’espace restant à remplir. La propriété flex
gère cela et est un raccourci de 3 autres :
flex-grow: 1
définit le facteur d’étirement possible des éléments (s’il y a de l’espace libre)flex-shrink: 1
définit le facteur de rétrécissement possible des éléments (s’il n’y a pas assez d’espace)flex-basis: 50px
définit la taille de base souhaitée
Par défaut, c’est flex: 0 1 auto
. Un élément récupère donc sa taille définie avec width
, il ne peut pas s’étirer, mais peut se rétrécir.
Voilà un exemple de composant flexible
Partie HTML
<ul id="menu">
<li>...</li>
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
Partie CSS
ul {
display: flex; /* 1 */
flex-direction: row; /* 2 */
}
li {
flex: 1 0 150px; /* 3 */
}
On a donc :
- On définit le mode Flexbox
- On précise que les éléments s’affichent en ligne (par défaut)
- On précise que les éléments
- ont une taille (largeur) souhaitée de
150px
- peuvent s’agrandir si l’espace le permet (
flex-grow: 1
) - ne peuvent pas se réduire (
flex-shrink: 0
)
- ont une taille (largeur) souhaitée de
Notez également que chaque enfant peut à son tour être un élément Flexbox pour ses propres enfants.
Alignements Grid et Flexbox#
Propriétés#
Les propriétés d’alignements respectent le même modèle dans Grid et Flexbox. Elles commencent par :
justify-*
pour les propriétés d’alignements selon l’axe principal (le sens de lecture par défaut)align-*
pour les propriétés d’alignements selon l’axe secondaire (de haut en bas par défaut)
Suivies de :
*-content
pour aligner la grille (les lignes et les colonnes)*-items
pour aligner les éléments de cette grille*-self
pour aligner un élément indépendamment
Pour Grid, c’est donc un jeu de 6 propriétés :
justify-content
/align-content
pour aligner la grille (les colonnes et les lignes)justify-items
/align-items
pour aligner le contenu de la grille (les éléments au sein de chaque cellule)justify-self
/align-self
pour aligner un élément de la grille indépendamment
Pour Flexbox, c’est quasiment la même chose. Pour simplifier, on considère qu’un élément Flexbox est un élément Grid d’une seule ligne, ses colonnes étant définies par ses enfants. On a donc uniquement :
justify-content
pour aligner la «grille» (et donc ses enfants) sur l’axe principalalign-items
pour aligner le contenu de la «grille» (ses éléments de l’unique ligne) sur l’axe secondairealign-self
pour aligner un élément indépendamment
Dans Flexbox, on peut noter que :
align-content
permet d’aligner plusieurs lignes d’un élément Flexbox (si forcé avecflex-wrap
)justify-items
etjustify-self
n’existent pas en mode Flexbox. Les enfants sont considérés comme les colonnes et sont donc alignés avecjustify-content
Valeurs#
Pour toutes ces propriétés justify-*
et align-*
, voici les valeurs utilisables :
start
aligne au départ (flex-start
pour Flexbox)center
aligne au centreend
aligne à la fin (flex-end
pour Flexbox)
En plus pour les propriétés d’alignements des lignes et colonnes de la grille (*-content
) :
space-around
/space-between
/space-evenly
distribue l’espace
Et enfin, pour les propriétés d’alignements des éléments (*-items
, *-self
) :
stretch
pour étirer
Les marges classiques continuent de fonctionner, et notamment margin: auto
des 4 cotés. Pour des marges sur les lignes et colonnes au sein de Grid, il existe les propriétés gap
, row-gap
et column-gap
.
Exercice - Flexbox#
- Créez une nouvelle page HTML
- Partez du code HTML ci-dessous (un menu de navigation, et un champ de recherche)
<nav>
<ul>
<li>Logo</li>
<li>Home</li>
<li>Products</li>
<li>Services</li>
</ul>
<form>
<input type="text">
<button>Go</button>
</form>
</nav>
- Faites-en sorte d’obtenir le résultat visuel ci-dessous :
- les éléments
<ul>
et<form>
sont côte à côte, et alignés verticalement - la navigation (
<ul>
) est alignée à gauche - le
<form>
est aligné à droite - les éléments de listes (
<li>
) n’ont pas de puces et sont espacés
- les éléments
La propriété position
#
La propriété position
permet de sortir un élément du flux et de créer une sorte de calque. Cet élément est ensuite déplaçable avec les propriétés top
, bottom
, left
et right
.
position: static
#
C’est le comportement par défaut.
position: absolute
#
L’élément sort du flux et superpose les autres.
Élément positionné à 100px du haut et à 300px de la gauche de l’écran.
#menu {
position: absolute;
top: 100px;
left: 300px;
}
position: fixed
#
Ce positionnement produit le même comportement qu’avec position: absolute
. La seule différence est que la boite ne suit pas le défilement de la page. Elle reste fixe.
position: relative
#
Ce positionnement permet 2 choses:
- sortir la boite du flux mais sans superposition. L’élément reste en place. Le positionnement avec
top
,bottom
,left
etright
se fait par rapport à l’endroit où devrait être la boite en position normale (et non par rapport à la page). - spécifier la boite comme nouvelle origine des éléments enfants en
position: absolute
.
position: sticky
#
Le mode sticky
est un mode hybride entre relative
et fixed
. L’élément est fixed
, mais ne peut pas sortir de son parent. Donc, tant que l’élément est visuellement dans son parent (et que les conditions de positionnement sont respectées), l’élément ne bouge pas. Sinon, l’élement sticky
suit le défilement avec son parent.
Empilement#
Lorsque plusieurs éléments utilisent la propriété position
, il est possible de modifier l’ordre de superposition avec z-index
.
L’élément 1 sera sous l’élément 2
#element1, #element2 {
position: absolute;
}
#element1 {
z-index: 5;
}
#element2 {
z-index: 10;
}
La propriété float
#
Lorsque un élément est placé en float
, l’élément suivant prend l’espace disponible du coté inverse au float
(si c’est possible). Les valeurs possibles sont left
, right
ou none
.
Par exemple, une image positionnée en float: left
, le texte suivant se positionnera sur la droite et contournera l’image.
La propriété float
provoque une sortie du flux de l’élément et pose plusieurs problèmes:
- un élément dont tous les enfants sont en
float
à une hauteur de 0px. - si l’on souhaite annuler l’effet du
float
, on utiliseclear: left
ouclear: right
en fonction dufloat
appliqué.
Cette propriété a été très utilisée pour le positionnement complet d’un site, même si elle n’a jamais été prévue pour cela.