CSS : mise en page avec l'outil flexbox

Le positionnement des boîtes a toujours été en CSS le point le plus délicat.
Les débutants en CSS ont beaucoup de difficultés pour appréhender les subtilités des positionnements fixe, relatif et absolu. Et il faut reconnaître que c'est pas simple. Ainsi pourquoi la valeur auto pour les marges gauche et droite ne fonctionne plus dans le cadre du positionnement absolu ???

Aussi beaucoup de développeurs WEB utilisent la propriété float pour positionner des éléments block mais c'est un mode de positionnement très limité et qui était initialement prévu pour disposer un élément inline (une image par exemple) dans une boîte.
Nous avons vu aussi qu'en transformant des boîtes en éléments "inline-block" on pouvait aussi réaliser une mise en page correcte.

Mais excellent nouvelle, CSS3 introduit l'outil flexbox (boîtes flexibles) qui vise à simplifier la mise en la page.

Ce qui est remarquable c'est que tous les navigateurs récents (même Edge de MS) interprètent correctement les propriétés relatives aux boîtes flexibles sans même avoir besoin de préfixer celles-ci.

Exemple 1 : distribution selon un axe horizontal des différentes boîtes

Le code HTML

<body> <h2>Trois boîtes flexibles disposées horizontalement</h2> <div id ="principale"> <div id="boite1"> <p>Post hanc adclinis Libano monti Phoenice, ... ... </div> <div id="boite2"> <p>Et quoniam mirari posse quosdam peregrinos ... </div> <div id="boite3"> <p>Nihil morati post haec militares avidi saepe ... </div> </div> </body>

Attention ça n'apparaît pas dans l'extrait de code mais sachez que le texte de la deuxième boîte est beaucoup plus long que celui dans les deux autres boîtes.

Le code CSS

#principale { display : flex; flex-direction : row;} div {margin:10px ; } div#boite1 {background : lime ; } div#boite2 {background : pink ; } div#boite3 {background : coral ; } p{margin : 10px ; font-size : 14pt; text-align : justify ; }

La grande nouveauté est la première règle de style : #principale { display : flex; flex-direction : row;}.
Ce qui veut dire que l'élément identifié principale est le conteneur de boîtes flexibles (display : flex) et que ces dernières seront disposées selon un axe horizontal (flex-direction : row).

Pour aucune des trois boîtes flexibles je n'ai précisé de hauteur et de largeur ... C'est CSS qui gère ! Observez le rendu !

Vous pouvez remarquez que la largeur de chaque boîte s'adapte automatiquement à son contenu.
Les boîtes flexibles sont espacées grâce à la règle div {margin:10px ; }

Exemple 2 : distribution des boîtes flexibles selon un axe vertical

Le code de la page

Le code HTML est strictement le même que celui de l'exemple précédent.

Dans la feuille de style la première règle change !

#principale { display : flex; flex-direction : column;}

La deuxième règle (div {margin:10px ; }) est supprimée ! Observez le rendu !

La hauteur de chaque boîte est ajustée automatiqument en fonction de son contenu !
Les boîtes flexibles sont désormais collées et c'est logique puisque j'ai supprimé les marges externes.

Combiner les deux modes de positionnement

Rien n'interdit de positionner selon un axe horizontal les boîtes parentes et selon un axe vertical les boîtes enfants ou vice-versa.
Dans l'exemple ci-dessous la page (body) contient les boîtes HEADER, SECTION, FOOTER et H2.
Il y a deux boîtes SECTION.
Chaque boîte SECTION contient plusieurs boîtes ARTICLE.

Le code CSS

#main {width : 90% ; margin :auto ; display : flex; flex-direction : column;} section {display : flex ; flex-direction : row ; margin :10px;} article {background : pink; margin : 5px ;} header, footer {background : lightgrey; }

Notez la règle flex-direction : column pour le sélecteur body et la règle flex-direction : row pour les sélecteurs section.

Ici il y a donc deux axes. L'axe principal est vertical et l'axe secondaire est horizontal.
Dans le cadre du "responsive web design" la largeur du conteneur principal (#main) est exprimée en % !

Le code HTML

<body> <div id ="main"> <header> <h2>En-tête de page</h2> </header> <h2>Première partie</h2> <section> <article> <p>Post hanc adclinis ... </article> <article> <p>Et quoniam mirari posse quosdam peregrinos ... </article> <article> <p>Nihil morati post haec militares avidi ... </article> </section> <h2>Deuxième partie</h2> <section> <article> <p>Post hanc adclinis Libano monti ... </article> <article> <p>Et quoniam mirari posse quosdam ... </article> </section> <footer> <h2>Pied de page</h2> </footer> </div> </body> Observez le rendu !

Donc rien n'interdit d'utiliser l'outil flexbox avec les nouvelles balises sémantiques HTML5 (HEADER, SECTION, NAV, FOOTER, etc.).

Le centrage d'une boîte flexible dans son conteneur

Vous savez qu'en CSS2 le centrage horizontal et vertical d'une boîte dans son conteneur est une opération délicate.
Pour le centrage horizontal il faut utiliser margin-left : auto et margin-right :auto mais ça ne marche plus en cas de positionnement absolu ... Allez savoir pourquoi ???
Pour le centrage vertical il faut utiliser le positionnement absolu et jouer sur deux propriétés : top :50% et margin-top = -moitié hauteur boîte.
Pour le centrage horizontal avec positionnement absolu il faut jouer sur deux propriétés : left :50% et margin-left = -moitié hauteur boîte.
Pour résumer le centrage d'une boîte dans son parent c'était jusqu'alors compliqué !

Avec l'outil flexbox le centrage d'une boîte dans son conteneur devient un jeu d'enfant.

Le code de l'exemple

... <style> #grande_boite{ display : flex; flex-direction : column; justify-content : center ; align-items : center; border : 1px solid red; height : 600px;} #petite_boite {background : pink ; width : 60% ; } div p{margin : 10px ; font-size : 14pt; text-align : justify; } ... <body> <h1>Centrage horizontal et vertical d'une boîte flexible dans son conteneur</h1> <div id ="grande_boite"> <div id ="petite_boite"> <p>Post hanc adclinis Libano monti Phoenice, ... </div> </div> ...

La largeur de grande_boite est implicite : 100% de BODY (qui lui même est fonction de la largeur de l'écran : 100% avec un maximum de 900 pixels pour les grands écrans).

La propriété justify-content gère l'alignement selon l'axe principal et la propriété align-items gère l'alignement selon l'axe secondaire.
Donc pour centrer selon les deux axes il suffit que ces deux propriétés aient la valeur :center. Observez le rendu !

Valeurs des propriétés justify-content et align-items

Positionner une boîte flexible dans un coin

Le code :

#grande_boite{ display : flex; flex-direction : column; justify-content : flex-start ; align-items : flex-end; border : 1px solid red; height : 600px ; } #petite_boite {background : pink ; width : 60% ; margin:10px ; } div p{margin : 10px ; font-size : 14pt; text-align : justify; }

Le code HTML :
Il est identique à celui de l'exemple précédent ! Le rendu !

La boîte flexible est positionnée en haut et à droite !
C'est parfaitement logique puisque l'axe principal est vertical (flex-direction : column) et que justify-content : flex-start alors que align-items : flex-end donc à la fin sur l'axe horizontal (axe secondaire ici).

Centrer plusieurs boîtes flexibles

Inutile de se prendre la tête !

Le code :

... <style> #grande_boite{ display : flex; flex-direction : column; justify-content : center ; align-items : center; border : 1px solid red; height : 600px ; } .petite_boite {background : pink ; width : 80% ; margin :10px; } ... <div id ="grande_boite"> <div class ="petite_boite"> <p>Post hanc adclinis Libano monti Phoenice, ... </div> <div class ="petite_boite"> <p>Post hanc adclinis Libano monti Phoenice, ... <p>Post hanc adclinis Libano monti Phoenice, ... </div> </div> ...

Les deux boîtes sont positionnées selon un axe vertical (flex-direction :column).

Le contenu de la deuxième boîte est le double de celui de la première ; la hauteur de chaque boîte est ajustée automatiquement en fonction du contenu et de la largeur (80% du conteneur).
Le rendu !

Les deux boîtes ne collent pas grâce à la règle margin :10px associée à la classe petite_boite.
Retour menu