Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site
Le positionnement des boites a toujours été, en programmation web, un point délicat. Les développeurs web ont longtemps utilisé les tableaux
HTML pour mettre en forme les pages web.
Puis le CSS a proposé différentes techniques de positionnement via la propriété POSITION (voir chapitre relatif à cette propriété).
Mais beaucoup de développeurs WEB utilisaient la propriété float pour positionner les boites alors que celle-ci était initialement
prévue pour disposer des éléments inline dans une boite (à gauche ou à droite du conteneur).
Nous avons vu par ailleurs qu'en transformant des éléments "block" ou "inline" en "inline-block", ceux-ci se positionnaient de
front avec les marges externes précisées.
Je vous annonce une excellente nouvelle : CSS3 introduit deux nouvelles spécifications pour le positionnement des boites :
flexbox & grid layout.
L'outil flexbox (boites flexibles) est déjà bien implémenté sur les navigateurs.
Concernant l'outil grid layout (positionnement en grille), est connu de la dernière version de MS Edge sortie en 2020 et bien entendu
de Chrome et Firefox.
L'emploi des deux méthodes n'est pas du tout incompatible.
L'outil flexbox n'étant à l'aise que dans une dimension, est pratique pour gérer des menus, des galeries d'images, etc.
L'outil grid layout étant conçu pour les deux dimensions, sera utilisé pour la mise en forme générale de la page.
Pour prendre une exemple, l'outil "grid layout" sera utilisé pour disposer les grandes divisions de la page (les boites header, nav, article, aside, footer)
tandis que l'outil "flexbox" permettra de disposer les différents DIV contenus dans la division ARTICLE et dans la division NAV.
Je débute par l'outil "grid layout" (positionnement en grille).
Comme je disais plus haut, cet outil est implémenté par tous les navigateurs récents.
Aucune difficulté : 6 boites affectées de la même classe : "boite".
La page a une largeur de 90% de celle de la fenêtre.
La page a une hauteur minimale égale à la hauteur de l'écran (min-height : 100vh).
En effet "vh" signifie "viewport height" donc la hauteur minimale de la page est égale à 100% de la hauteur du viewport.
Aperçu de la page dans un cadre :
Le premier DIV occupe implicitement la première cellule, le deuxième DIV la deuxième cellule et ainsi de suite.
Les trois colonnes ont la même largeur, les deux lignes ont la même hauteur donc les six cellules sont identiques !
Pour les que les lignes et les colonnes aient la même hauteur / largeur il suffit de leur attribuer la valeur "auto".
Le code HTML inchangé et le code CSS devient alors ...
Notez les valeurs des propriétés grid-template-rows & grid-template-columns !
Le raccourci grid-gap : esp. lig. esp. col. remplace avantageusement les propriétés grid-row-gap & grid-column-gap.
Le rendu :
Comme les colonnes ne doivent pas avoir la même largeur, j'ai utilisé une nouvelle unité de mesure : "fr".
Pour les lignes j'ai aussi utilisé cette nouvelle unité de mesure à la place de "auto".
Donc le code HTM sera :
Quatre boites seulement !
Nous devons créer une grille de 2 colonnes et 3 lignes donc 6 cellules alors que nous n'avons que quatre divisions ...
Il n'est plus question d'une affectation implicite des boites aux cellules. L'affectation doit être explicite !
Pour l'affectation explicite des divisions aux différentes cellules de la grille nous avons trois solutions !
Pour chaque division on précise la première cellule d'affectation et l'éventuelle fusion de cellules.
On définit d'abord une grille de trois lignes et deux colonnes donc 6 cellules.
Chaque "fr" représente ici le dixième de la hauteur /largeur disponibles.
Le rendu :
La valeur "span ..." a été ici associée à la propriété grid-column donc on fusionne (sur une même ligne) des colonnes.
Mais on peut aussi fusionner sur une même colonne des lignes ; il suffit d'associer la valeur "span ..." à la propriétégrid-row.
Pour chaque boite on précise les bornes de ligne et de colonne.
La grille comprend 2 colonnes et trois lignes. Donc les bornes de colonnes sont 1,2,3 (et non pas 0,1,2) et les bornes de lignes sont 1,2,3,4.
Ainsi la première ligne est entre les bornes de ligne 1 et 2 ; la dernière ligne est entre les bornes de ligne 3 et 4 ;
La première colonne est entre les bornes de colonne 1 et 2 ; la deuxième colonne est entre les bornes de colonnes : 2 et 3.
Extrait de la feuille de style :
Le reste de la feuille de style est inchangé.
Pour chaque sélecteur il y a deux propriétés (grid-row & grid-colunm) et pour chaque propriété il y a deux valeurs séparées par une "/".
La première valeur est la borne début et la deuxième valeur est la borne fin.
Ainsi il faut lire pour HEADER : bornes de ligne de 1 à 2 (donc première ligne) et bornes de colonne de 1 à 3 (donc deux colonnes).
Personnellement, j'aime pas trop cette technique.
Le rendu est strictement identique ; donc je ne le présente pas.
On nomme chaque cellule de la grille (propriété grid-template-area) ; plusieurs cellules pouvant porter le même nom. Puis on affecte à chaque division de la page un nom (propriétégrid-area)
C'est la technique que je préfère car elle me parait la plus claire au niveau du code CSS.
Je vous communique toute la feuille de style.
Apparition de la propriété grid-template-areas qui nomme les six cellules de la grille.
Les deux cellules de la première ligne se nomment "h" ; les cellules de la deuxième ligne
se nomment respectivement "n" et "a" ; les deux cellules de la troisième ligne se nomment "f" ;
Apparition de la propriété grid-area qui affecte un nom de cellule à chaque grande division de la page :
Les propriétés grid-row & grid-column disparaissent !
Le rendu :
En combinant les "media queries" et le positionnement en grille on peut obtenir un site "responsive" c'est à dire qui s'adapte à tous les écrans : de l'écran géant d'un ordinateur de bureau au minuscule écran d'un "ordiphone" (comme disent les québecois).
Sur un petit écran la boite ASIDE est masquée ; chacune des quatre autres boites occupent toute la largeur de l'écran.
Il est totalement indépendant de la taille de l'écran.
N'oubliez pas la balise meta viewport dans la partie HEAD!
L'espacement entre rangées et colonnes est le même : 10px.
Une grille de 3 colonnes et 4 lignes.
Par défaut la largeur de BODY est égale à 800 pixels mais si largeur de la fenêtre est inférieure à 801px alors la largeur de la page = 100% et la boite ASIDE est masquée (display : none); la division "article" occupe alors toute la troisième ligne (nouvelles valeurs pour grid-template-areas).
Le rendu sera fonction de la largeur de l'écran. Sur votre PC réduisez progressivement la largeur de la fenêtre d'affichage.
Sur un petit écran les quatres boites (puisque ASIDE est masqué) sont les unes en dessous des autres.
Lorsqu'on travaille avec l'outil flexbox, deux axes interviennent : l'axe principal et l'axe secondaire.
L'axe principal est défini par la propriété flex-direction et l'axe secondaire est alors l'axe qui lui est perpendiculaire.
La valeur par défaut de flex-direction est "row" (donc l'axe principal est l'axe horizontal).
Je vais vous montrer ci-dessous que l'outil flexbox est parfaitement adapté pour créer des menus responsives et produire de superbes galeries photos.
Le conteneur SECTION contient trois DIV.
Notez que la largeur par défaut de BODY est de 100% de la fenêtre sauf si celle-ci fait au moins 1000px (BODY fait alors
900px de large avec centrage).
Remarquez la règle de style relative à l'élément SECTION : display : flex; flex-direction : row;
Ce qui signifie que SECTION est le "flex container" et les éléments contenus dans ce conteneur seront des "flex-items".
Notez que pour les trois "flex-items" je n'ai défini ni hauteur ni largeur, la taille est flexible (en fonction du contenu).
Les flex-items occupent toute la largeur disponible et ont tous la même hauteur.
Le code de la page est strictement identique au précédent sauf dans la règle de style relative
à SECTION : display : flex; flex-direction : column;
Donc cette fois l'axe principal est l'axe vertical (et l'axe secondaire sera l'axe horizontal).
Cette fois je fixe pour chaque "flex-item" une largeur : div {width : 250px ; margin : 10px ; }
Axe principal = axe horizontal.
Problème : sur un grand écran les trois items sont alignés à gauche sur l'axe horizontal et sur un petit écran la largeur de 250px n'est pas respectée.
Il faut rendre possible un saut de ligne lorsque le "flex-container" est étroit.
Il faut donc modifier la règle de style relative au conteneur.
section {display : flex; flex-direction : row; flex-wrap : wrap; }
J'introduis une nouvelle propriété flex-wrap avec la valeur "wrap". Ce qui veut dire que les items peuvent passer sur
une nouvelle ligne si c'est nécessaire.
Bien sûr, si l'axe principal est l'axe vertical il s'agira d'un saut de colonne.
Valeur par défaut de cette propriété est "nowrap" (saut de ligne impossible).
Le rendu :
Sur un petit écran le troisième item passe à la ligne puis le deuxième si la fenêtre est encore plus étroite. Observez que les items sont alignés à gauche (en début de l'axe de façon générale).
Pour l'esthétique il faut une distribution équilibrée des blocs sur l'axe principal. C'est l'affaire de la propriété justify-content.
Le "flex-container" contient six "flex-items" ; la répartition des blocs selon l'axe horizontal doit être équilibrée ; un saut de ligne doit être possible.
Le code :