CSS : révisions sur les boites dans la version 2

Principes

Des erreurs à ne pas faire

Exemple

Le code HTML

<body> <h2>Première boite</h2> <article> <p>As a single parent for nearly ... ... </p> </article> <h2>Deuxième boite</h2> <article class ="h100"> <p>Hearing Breidbart's anecdote retold elicits ... ... </p> </article> <h2>Troisième boite</h2> <article id ="boite3" style ="background : url(../images/anglais.jpg;" > </article> </body>

La page (BODY) comprend trois boites ARTICLE.
Notez les règles en ligne associées au deuxième et troisième boites ARTICLE.
Cela n'apparait pas dans l'extrait mais sachez que le texte de la deuxième boite est très volumineux !

Feuille de style ... fausse

	* {margin :0 ; padding : 0; font-size : 14pt;}
	body {width : 90% ; margin : 10px auto 10px auto ;}
	article {border : 1px solid black; background : pink; 
		padding : 5px; margin-top : 10px; }
	h1,h2 {font-size : 18pt;text-align : center ; 
		line-height : 50px; background : gray ; 
		color : white ; margin-top : 10px; }
	.h100 {height : 100px ; }

Il faut supprimer toutes les marges par défaut associées à certains éléments HTML : margin :0 ; padding : 0;
Notez que dans le cadre d'un "responsive" basique la largeur de la page est exprimée en % !

Le rendu

Testez ce code !

C'est la "cata" ! Le texte de la deuxième boite déborde ; l'image contenue dans la troisième boite n'apparait pas !
Explications : la deuxième boite fait 90% de large sur 100 pixels de haut (du fait de la classe "h100". Même sur un écran de PC de bureau c'est insuffisant pour afficher tout le contenu donc il y a débordement en effet par défaut overflow : visible.
La troisième boite ne contient aucun texte donc sa hauteur est seulement de 10px (les marges internes haute et basse) ; taille insuffisante pour afficher l'image contenue.

La solution

Il suffit de modifier la feuille de style en rajoutant deux règles.

	article {overflow : auto; }
	#boite3 {width : 780px ; height : 360px; margin : 10px auto 10px auto ;}

Avec overflow : auto une barre de défilement est rajoutée si nécessaire à chaque élément ARTICLE.

L'image "anglais.jpg" fait 260px par 180px donc pour qu'elle soit répétée 6 fois il faut régler la boite ayant l'ID "boite3" à 780 par 360.

Je rappelle que lorsqu'une image est le "background" d'une boite, elle est par défaut répétée pour occuper toute la boite ; en effet la valeur par défaut de backgrond-repeat est "repeat" !
Le rendu correct

Pour la deuxième boite le surplus de texte est désormais masqué mais on peut le lire en utilisant la barre de défilement vertical qui est ajoutée si nécessaire.

Solution alternative

Il y a une autre solution : masquer le texte qui déborde avec la règle :overflow :hidden mais si survol de la boite alors ajustement de la hauteur en fonction du contenu.
Notez bien le sélecteur (article:hover) qui veut dire sur survol d'un élément ARTICLE.

...
	.h100 {height : 100px ; overflow : hidden; }
	.h100:hover {height : auto ; }


Le rendu de cette solution alternative

Survolez le deuxième bloc, sa hauteur s'ajuste au contenu et le bloc identifié "boite3" est alors poussé vers le bas ...

Disposer les boites de front

Thématique :

Dans un site toutes les pages ont la même structure : trois grandes divisions : HEADER, SECTION, FOOTER.
La division SECTION comprend à son tour trois boites (NAV, ARTICLE, ASIDE) qui doivent être côte à côte !

Le code HTML

En utilisant les nouvelles balises structurantes de HTML5 :

<body> <header> <h2>En-tête de page </h2> <!--Ici le texte --> </header> <section> <nav> <h2>Menu </h2> <!--Ici les liens--> </nav> <article> <h2>Contenu</h2> <!--Ici le texte et images--> </article> <aside> <h2>Publicité</h2> <!--Ici la pub du jour--> </aside> </section> <footer> <h2>Pied de page</h2> <!--Ici le texte --> </footer> </body>

Les trois boites qui doivent être de front sont les enfants de SECTION : NAV, ARTICLE, ASIDE.

Première solution

Dans le chapitre précédent (voir version 5 de la page) j'ai réussi à mettre deux boites de front via CSS avec la propriété float.

Mais la propriété float ne prend que deux valeurs left / right.
Donc pour positionner de front deux boites ça marche très bien avec "float" mais pour trois c'est devient un peu délicat ...

La feuille de style

	*{margin :0 ; padding : 0;}
	body {width : 90% ; margin : 10px auto 10px auto ;}
	header, footer {height : 100px; }
	header, nav, article, aside, footer {background : pink ; }
	header, footer, section {width : 100% ; margin-top : 10px ; }
	
	nav{float : left ; width : 29% ;height : 300px ;}
	aside {float : right ; width : 18% ; height : 350px ;}
	article {margin-left :30%; margin-right : 19%; height : 400px ; }       
	...

Notez que la largeur de la page est exprimée en % !

La première colonne (MENU) doit flotter à gauche dans son conteneur (SECTION)
La troisième colonne (ASIDE) doit flotter à droite dans son conteneur.
La deuxième colonne (ARTICLE) doit s'insérer entre les deux donc il faut régler margin-left & margin-right en fonction des largeurs respectives de MENU et ASIDE
Le rendu !

Les trois "enfants" de SECTION sont bien côte à côté.

Deuxième solution

Une autre technique est plus simple et consiste à transformer les éléments NAV, ARTICLE, ASIDE en "inline-block" c'est à dire des boites qui par défaut se positionnent côte à côte tant qu'il y a de la place naturellement.

Attention si les éléments "inline-block" n'ont pas la même hauteur alors ils s'alignent verticalement par rapport à la base ; il faut donc forcer l'alignement vertical par le haut avec la règle vertical-align : top.

La feuille de style (extraits)

	*{margin :0 ; padding : 0;}
	body {width : 90% ; margin : 10px auto 10px auto ;}
	header, footer {height : 100px; }
	header, nav, article, aside, footer {background : pink ; }
	nav, article, aside {display : inline-block; vertical-align : top;}
	header, footer, section {width : 100% ; margin-top : 10px ; }
	nav{width : 29% ; height : 300px ; margin-right :1%;}
	article {width : 49% ; height : 400px ; margin-right :1%;}
	aside {width : 19% ; height : 350px ;}

La règle la plus importante : nav, article, aside {display : inline-block; vertical-align : top;}
Ces trois éléments sont donc retirés du flux normal !

Pensez à annuler toutes les marges par défaut attribuées à certaines balises "block" avec la règle "reset" : *{margin :0 ; padding : 0;}. Vous éviterez ainsi de mauvaises surprises. Le rendu !

Les trois "enfants" de SECTION sont bien côte à côté et alignés par verticalement par le haut.

Attention on ne peut pas dire ici que la mise en page est responsive. En effet sur un petit écran il devient maladroit d'avoir des boites côte à côte !
Une solution complète consisterait à structurer la feuille de style avec les media queries. Media queries pour responsive design

CSS dans sa version 3 propose de nouveaux outils beaucoup plus performents : CSS3 : révolution dans le positionnement des blocs

La propriété POSITION

Paradoxalement la propriété position : fixed / relative / absolute est dans la pratique peu utilisée pour retirer les boites du flux normal.

Il faut utiliser conjointement avec position : fixed /absolute / relative les propriétés top (ou bottom) et left (ou right).
Pour ces quatre propriétés la valeur peut être exprimée en pixels ou en % !

Positionnement fixe

Attribuer position : fixed et z-index : grande valeur à la boite de navigationn permet à celle-ci d'être affichée en permanence même lorque le visiteur fait défiler vers le bas.
Cette mise en page est très adaptée aux petits écrans. C'est ce que nous faisons dans l'exemple qui suit.

Le code HTML (extrait)

... <body> <nav> <h2>Titre du site</h2> <a href ="#" >Lien 1</a> <a href ="#" >Lien 2</a> <a href ="#" >Lien 3</a> <a href ="#" >Lien 4</a> <a href ="#" >Lien 5</a> </nav> <section> <p>Alii nullo quaerente vultus severitate ... <!--beaucoup de contenu--> ... </section> ...

La boite NAV contient le titre du site et la zone de navigation.
Le contenu de chaque page est dans la boite SECTION ; ce contenu peut être très important.

La feuille de style

	* {margin : 0px ; padding : 0px ; font-size : 20px; }
	body {width : 100%; }
	nav {background : lime; width : 100%; height : 100px ; 
		position : fixed; z-index : 999 ; top : 0px ; left :0px ;}
	section {background : aqua ; width : 900px ;  
		position : relative ; top : 120px ; 
		margin-left : auto ; margin-right : auto ; z-index : 1 ; }
	...

La position de la boite NAV est fixe par rapport à l'angle haut gauche de l'écran !
Grâce à un positionnement fixe de la boite NAV combiné à un z-index : 999 ce bloc reste toujours affiché même lorsque vous faites défiler la page vers le bas.
En effet lorsque vous faites remonter le bloc SECTION ce dernier glisse sous la boite NAV. puisque son z-index est inférieur à celui de la zone de navigation.

Pour pouvoir donner un top initial à SECTION il faut positionner cette boite en "relatif" (voir paragraphe suivant).

Le rendu

Essayez ce code !

Surtout utilisez la barre de défilement vertical pour bien constater que la zone de navigation est affichée en permanence ; lorsque vous défilez vers le bas alors le contenu de SECTION glisse sous NAV !

Positionnement relatif

L'objet est décalé en fonction des valeurs de top et de left par rapport à la position qu'il aurait du avoir normalement.
Donc si vous utilisez position : relative sans préciser top et left l'élément est positionné normalement !

Conseil : prenez l'habitude d'attribuer la propriété relative à body. Ainsi vous êtes sûr que pour les éléments enfants qui sont positionnés en absolu le seront par rapport à la page (et non pas par rapport à l'écran).

Tant que les propriétés text-shadow et box-shadow n'existaient pas on utilisait beaucoup le positionnement relatif pour créer un effet d'ombre sur un élément.

Thème : on veut afficher une image qui fait 400 par 300 avec un effet d'ombre sans utiliser la propriété box-shadow.
C'est ce qu'on appelle être "sado maso" (lol).

Le code

... <style> div {width : 400px ; height : 300px ; margin : 20px auto 20px auto ; background : gray ; } .decale {position : relative ; top : -10px ; left : -10px ; } ... <p>L'image insérée fait 400 par 300 (comme la boite DIV). <h2>Première solution : fausse</h2> <div> <img src ="../images/nautile.jpg" /> </div> ... <h2>Deuxième solution : correcte</h2> <div> <img src ="../images/nautile.jpg" class ="decale"/> </div> ...

Le rendu

Le rendu de ce code !

L'image du nautile fait 400 par 300 comme la boîte DIV.

Dans la deuxième solution (la bonne) l'image ne recouvre pas complètement la boîte DIV.
Du fait de l'appel de la classe decale l'image est en effet décalée de 10 pixels par rapport à la position qu'elle aurait du avoir normalement.

Positionnement absolu

Si vous voulez superposer des boites ou centrer verticalement une boite dans son conteneur il faut utiliser le positionnement absolu.

Pour positionner en absolu une boite il faut utiliser trois propriétés : position, left (ou right) top (ou bottom).
Attention si la boite parente n'est pas elle-même positionnée (en absolu ou fixe ou relatif) les coordonnées de la boite "enfant" sont déterminées par rapport à l'angle haut gauche de la fenêtre et non pas par rapport au coin haut gauche du conteneur parent.

Exemple 1

Thématique : les boites de couleur se superposent partiellement. La boite survolée passe au premier plan.
Le code :

... <style> #conteneur {position : relative; width : 90% ; height : 400px ; margin :auto ; border : 1px solid black;} #boite1, #boite2, #boite3 {position :absolute ;width : 40% ; height : 100px;} #boite1 {background : yellow ; top : 50px ; left : 10% ; } #boite2 {background : green ; top : 100px ; left : 20% ; } #boite3 {background : red ; top : 150px ; left : 40% ; } div:hover {z-index : 999 ; } ... <body> <div id ="conteneur"> <div id ="boite1"></div> <div id ="boite2"></div> <div id ="boite3"></div> </div> ...

Notez bien que le bloc "conteneur" est positionné (ici en relatif) afin que les "top" et "left" des "descendants" soient calculés par rapport au coin haut-gauche du conteneur "parent".

Si un DIV est survolé son "z-index" devient très important !

Le rendu :

Testez ce code !

La boite survolée passe au premier plan.

Exemple 2

Pour centre verticalement une boite dans son conteneur il faut utiliser le positionnement absolu.

Il faut impérativement que la boite "enfant" ait une hauteur et une largeur et soit positionnée en absolu.
Dès qu'une boite est positionnée en absolu le centrage horizontal via margin:auto n'est plus pris en compte.

La feuille de style :

	#grande_boite{ position : relative ; width : 90% ;
		border : 1px solid red; height : 400px ; margin : auto ; }
	#petite_boite {position : absolute ; width : 60% ;  height : 200px ;
		top : 50% ; margin-top :-100px ;  
		left : 50% ; margin-left : -30%; 
		background : pink ; } 
	div p{margin : 10px ; font-size : 14pt; text-align : justify; }

Le rendu :

Testez le code !

Exercice :
Et si la boite enfant à centrer H & V faisait 50% de large 150px de haut, quels seraient les règlages ?

Les nouveaux outils de positionnement

CSS3 introduit deux nouveaux outils de positionnement : positionnement en grille (grid layout) et les boites flexibles (flexbox).
Par ailleurs ces deux techniques se complètent parfaitement : grid layout pour positionner les grandes divisions de la page et flexbox pour disposer les "enfants" de chaque grande division selon un axe (avec éventuels saut de ligne/coionne).
Le centrage horizontal et vertical d'un "enfant" dans son conteneur parent devient très facile avec "display flex". Les outils grid-layout & flexbox
Retour menu