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: blocksur 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: gridpour 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 1frpour 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 100pxpour 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: 1positionne l’élément dans la colonne 1grid-column: 1 / 3positionne l’élément de la colonne 1 à la colonne 3 (exclue)grid-column: 1 / span 2positionne 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 (
200pxet1fr) et 3 lignes (50px,1fret50px) - 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-rowest 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 (
240pxet1fr) - Création de 3 lignes (
auto,1fretauto)
-
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: flexpour définir un élément Flexbox
Sur cet élément, il faut alors définir ses axes que les enfants vont suivre
flex-directiondéfinit l’axe principal (avec les valeurscolumn,column-reverse,rowourow-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: 1définit le facteur d’étirement possible des éléments (s’il y a de l’espace libre)flex-shrink: 1définit le facteur de rétrécissement possible des éléments (s’il n’y a pas assez d’espace)flex-basis: 50pxdé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 :
*-contentpour aligner la grille (les lignes et les colonnes)*-itemspour aligner les éléments de cette grille*-selfpour aligner un élément indépendamment
Pour Grid, c’est donc un jeu de 6 propriétés :
justify-content/align-contentpour aligner la grille (les colonnes et les lignes)justify-items/align-itemspour aligner le contenu de la grille (les éléments au sein de chaque cellule)justify-self/align-selfpour 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-contentpour aligner la «grille» (et donc ses enfants) sur l’axe principalalign-itemspour aligner le contenu de la «grille» (ses éléments de l’unique ligne) sur l’axe secondairealign-selfpour aligner un élément indépendamment
Dans Flexbox, on peut noter que :
align-contentpermet d’aligner plusieurs lignes d’un élément Flexbox (si forcé avecflex-wrap)justify-itemsetjustify-selfn’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 :
startaligne au départ (flex-startpour Flexbox)centeraligne au centreendaligne à la fin (flex-endpour Flexbox)
En plus pour les propriétés d’alignements des lignes et colonnes de la grille (*-content) :
space-around/space-between/space-evenlydistribue l’espace
Et enfin, pour les propriétés d’alignements des éléments (*-items, *-self) :
stretchpour é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,leftetrightse 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: leftouclear: righten fonction dufloatappliqué.
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.