CSS2 et les boites

Principes

Par défaut les boites (éléments "block" ) se positionnent les unes en dessous des autres.
Par défaut une boite enfant a la même largeur que sa boite parente.
Par défaut la hauteur de boite est "auto" c'est à dire ajustée au texte contenu ; donc si pas de texte hauteur boite = hauteur des marges internes et externes hautes et basses éventuelles !

Les bêtises à ne pas faire

Exemple

Le code de la partie BODY d'une page est le suivant :

<body> <h2>Première boite</h2> <article> <p>As a single parent for nearly a decade-she and Richard's father, Daniel Stallman, were married in 1948, divorced in 1958, and ... </p> </article> <h2>Deuxième boite</h2> <article style = "height : 100px;"> <p>Hearing Breidbart's anecdote retold elicits a wry smile from Stallman. "I may have been a bit of a jerk sometimes," he admits. "But ... </p> </article> <h2>Troisième boite</h2> <article style ="background : url(../images/anglais.jpg;" > </article> </body>

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

Les bêtises sont faites !

Imaginons que le code de la feuille de style interne soit le suivant

* {margin :0 ; padding : 0; font-size : 14pt;} body {width : 900px ; 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; }

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 900 pixels par 100 ; c'est insuffisant par rapport au volume de texte donc par défaut le surplus déborde (oveflow : 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.

Rajouts

article {overflow : auto; } .boite3 {width : 780px ; height : 360px; }

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 la classe "boite3" à 780 par 360.

Je rappelle que lorsque une image est le fond 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 !

Évidemment il faut amender un peu le HTML ; ajouter la classe "boite3" au 3ième ARTICLE : ...article class ="boite3" ...

Le rendu

Testez ce code !

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 (overflow : auto).

Sur les petits écrans (tablette et smartphone) il n'y a pas de barre de défilement; il suffit d'utiliser le doigt sur la boite pour faire glisser le texte vers le bas.

Pour éviter le débordement 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. Il faut alors rajouter la règle : article:hover {height : auto;}

Disposer les boites de front

Exemple

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 qui doivent être côte à côte !

Le code de la partie BODY (extraits)

<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 grandes divisions : HEADER, SECTION, FOOTER

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

Oui, j'utilise les nouvelles balises structurantes de HTML5.

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 mais pour trois c'est une autre affaire ...
Je ne dis pas que c'est impossible mais ça devient un "gros bricolage CSS". A éviter !!!

Deuxième solution

Une autre technique beaucoup plus simple consiste à transformer les éléments NAV et ARTICLE 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 ils s'alignent verticalement par rapport à la base. Il faut donc forcer l'alignement vertical par le haut avec vertical-align : top.

La feuille de style (extraits)

*{margin :0 ; padding : 0;} body {width : 900px ; 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 retirés du flux normal !

Pensez à annuler toutes les marges par défaut : *{margin :0 ; padding : 0;} pour éviter de mauvaises surprises ...

Le rendu

Testez ce code !

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

La propriété POSITION

Paradoxalement la propriété position : fixed / relative / absolute est dans la pratique très 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

Exemple

La boite d'en-tête (HEADER) qui fait toute la largeur de l'écran est ancrée par rapport à ce dernier.
Le bloc du dessous (SECTION) glisse sous la boite HEADER lorsqu'on la fait remonter.

Le code :

* {margin : 0px ; padding : 0px ; } body {width : 100%; } header {background : aqua; width : 100%; height : 200px ; position : fixed; z-index : 2 ;top : 0px ; left :0px ;} section {width : 1000px ; position : relative ; margin : 220px auto 20px auto; z-index :1; } nav, article{ background : skyblue ; height : 600px; } nav { width : 28% ; float : left ; } article { width : 70% ; float : right ; } ... <body> <header> ... </header> <section> <nav> ... </nav> <article> ... </article> </section> ... Essayez ce code !

La position de la boite est fixe par rapport à l'angle haut gauche de l'écran !

Grâce à un positionnement fixe pour la boite HEADER et un z-index ayant une valeur supérieure à celle des autres boites, cette boite reste toujours affichée même lorsque vous faites défiler la page vers le bas.
En effet lorsque vous faites remonter le bloc SECTION (contenant les boites NAV et ARTICLE) ce dernier glisse sous le bloc HEADER puisque son z-index est inférieur à celui du bloc HEADER.

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 l'écran et non pas par rapport au coin haut gauche du conteneur parent.

Exemple 1

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 : 2 ; } ... <body> <div id ="conteneur"> <div id ="boite1"></div> <div id ="boite2"></div> <div id ="boite3"></div> </div> ...
Testez ce code !

Ici les coordonnées de left et top des boites "enfants" sont calculées par rapport à l'arête supérieure gauche de la boite conteneur car cette dernière est positionnée en relatif (#conteneur {position :relative;... }

Les boites en couleurs se superposent partiellement dans l'ordre d'appel par le code HTML.
Si une boite en couleurs est survolée elle passe en premier plan (z-index passe à 2).

Exemple 2

Pour centre verticalement une boite dans son conteneur il faut utiliser le positionnement absolu.
En effet margin : auto auto auto auto; ça marche pas !


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 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; }
Rendu de la page avec le code CSS ci-dessus

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.

Exemple

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 ; } ... <h1>Effet d'ombre</h1> <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 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.
Retour menu