Avant d’expliquer ce fameux « modèle de boîte », il est impératif d’aborder une notion essentielle en HTML concernant le flux d’éléments, avec la façon qu’a le navigateur de découvrir les éléments HTML placés dans une page et de les afficher.
Flux
Le navigateur lit et interprète un document HTML pour l’afficher selon des mécanismes bien précis, définis par la norme, que tout navigateur doit respecter. Dans la structure du document, il y a deux dispositions qui vont influencer le rendu visuel :
- l’imbrication des éléments avec un conteneur : un élément peut contenir plusieurs enfants, soit des éléments, soit du texte
- la succession des éléments dans un conteneur : les éléments se suivent et sont donc « frères » entre-eux et fils du même conteneur
C’est ce qu’on appelle le « flux HTML », qui fait que le navigateur se dit (s’il pouvait parler !) « tient je vois un conteneur » ou « tient ces éléments se suivent ».
Boîtes
Pour afficher ces éléments, le navigateur considère chacun d’eux dans une boîte rectangulaire selon deux modalités :
- les boîtes « en ligne » pour tout ce qui touche au texte ; sont concernées les balises que nous avons qualifiées de « caractères » :
b
,i
,u
, etc, mais aussi les balisesa
etimg
(comme toutes les balises d’insertion d’objet,video
par exemple) - les boîtes « bloc » pour le reste notamment les balises
p
,h*
,ul
,li
L’imbrication est logiquement réglementée :
Donc pas de p
dans un b
, l’inverse étant possible.
Ces deux types de balises conditionnent l’affichage sur deux aspects essentiels : le positionnement et la dimension d’une boîte. Les éléments sont lus dans l’ordre du flux HTML et positionné selon leur type bloc ou en ligne. L’imbrication des éléments joue simplement sur la dimension des boîtes : un conteneur a ses limites fixées par ses enfants.
C’est sur le placement des boîtes que joue le type « en ligne » ou « bloc », et indirectement sur les dimensions. Voyons cela en détail.
En ligne
Positionnement
Le positionnement des éléments en ligne est dicté par le caractère textuel de leur contenu.
Leur dimension, et surtout la largeur, ne dépend que du contenu textuel qui s’étire aux maximum, dans les limites bien sûr de la largeur du navigateur, auquel cas un retour à la ligne est provoqué.
Voici un exemple assez parlant, que nous avons déjà vu dans la leçon consacré à l’alignement vertical.
code |
<a href="#">Lien</a> <img src="tree-logo_opt.svg" width="100"/> <span style="font-size:50px">La grande maison dans la prairie</span> Petite en fait |
Dans le rendu visuel correspondant, les éléments sont bien alignés, verticalement centrés sur la ligne de base (sauf pour les images alignés sur le bas).
rendu visuel |
LienLa grande maison dans la prairie Petite en fait |
Rappelons ici, grâce à cet exemple, le rôle de la balise span
.
Dimensions
Pour la largeur, la règle est claire et logique, un élément en ligne a la largeur que son affichage lui donne, donc selon son contenu textuel. Pour la hauteur c’est un peu plus tordu. La hauteur déterminée par la taille de police qui s’applique à l’élément en ligne, c’est-à-dire la taille qui aura été définie dans un de ces ancêtres ou à défaut la taille paramétrée par l’utilisateur dans le navigateur. En voici un exemple très explicite :
code |
<span style="border: 2px solid red"> <a href="#">Lien</a> <span style="font-size:50px"> La grande maison dans la prairie </span> Petite en fait </span> |
La directive CSS border, que nous allons traiter dans le modèle de boîte juste après, permet d’encadrer l’élément de rouge pour visualiser sa boîte.
rendu visuel |
LienLa grande maison dans la prairiePetite en fait |
Explication : la police du conteneur span
est par défaut de 16px, fixée par le navigateur (on suppose qu’aucun de ces parents n’a changé la taille de police). C’est la même taille qui sera appliqué au lien à l’intérieur et au texte « Petite en fait ». En revanche, le span
intérieur voit ses caractères agrandis mais cela ne s’applique qu’à lui. La hauteur de l’élément en ligne conteneur n’est donc pas déterminée par son contenu.
C’est bon à savoir mais en pratique on ne va pas s’amuser à faire d’un élément en ligne un conteneur et à lui appliquer une bordure. Les éléments blocs sont là pour ça !
Blocs
Positionnement
Ces éléments là, comme un paragraphe ou un titre, prennent toute la largeur, peu importe leur contenu, et donc fort logiquement s’empilent sans jamais être côte-à-côte.
Notons que l’équivalent du span
en élément bloc s’appelle div
. Cette balise, très (trop !) utilisée permet d’avoir un conteneur de type bloc qui ne produit aucun effet visuel.
Dimensions
Les dimensions d’un bloc sont déterminées par son contenu. Pendant l’affichage de celui-ci, la boîte du bloc parent s’étire pour épouser les contours du contenu.
Je ne précise pas ce qui se passe lorsque l’on combine, soit par imbrication, soit pas succession, des éléments blocs et des éléments en ligne. C’est à vous d’essayer, en appliquant à cet exercice les principes que nous venons de voir.
Voici un exemple de façon de présenter la solution, avec ici des dispositions complètement fausses :
Modèle de boîte
Une fois muni de ce principe de boîte dans laquelle s’affiche chaque élément HTML, selon deux modalités en ligne ou bloc, il reste à décrire comment « décorer » chaque boîte par des directives CSS : marges, bordures et dimensions. La norme CSS 2 a défini clairement ce modèle résumé par le schéma suivant :
Il est possible d’influer sur l’aspect d’une boîte par les propriétés CSS résumées dans ce schéma que nous allons décrire en détail. Certaines de ces propriétés ont des modalités d’applications différentes selon le type d’élément en ligne ou bloc.
Marges
Nous avons déjà vu les marges dans le chapitre précédent concernant les paragraphes. En fait la propriété CSS margin
et ses dérivées s’appliquent à la boîte de tout élément. Elle permet d’espacer la boîte avec les boîtes qui seront disposées aux alentours, en désignant la distance minimale à respecter bord à bord.
propriété | description | valeur par défaut |
margin-top |
|
0 |
Il existe aussi la possibilité d’indiquer une « marge intérieure » entre le bord de la boîte et son contenu représenté par ses enfants, autres éléments ou bien texte. C’est une garantie d’espacement avec le contenu. La propriété est padding
et les formes sont les mêmes que pour margin
.
propriété | description | valeur par défaut |
padding-top |
|
0 |
Fusion des marges
La fusion des marges extérieures (margin
) fait que deux marges contiguës, dans le cas où deux éléments se suivent ou deux éléments sont imbriqués, s’affichent comme un espacement du maximum des deux marges. Les marges ne vont donc pas s’ajouter mais seule la plus grande des deux est retenue, la logique étant que l’espacement minimum demandé est assuré. Cette fusion obéit à des règles pas toujours simples à expliquer mais qui sont d’une logique implacable. Voyons des exemples à partir du code CSS suivant :
<style> body { margin: 0; border: 1px solid black; } header { margin: 40px; border: 1px solid blue; text-align: center; } article { margin: 20px; border: 1px solid red; text-align: center; } </style>
1er cas : les deux éléments se suivent
Voici le code et le résultat.
L’entête a bien 40 pixels tout autour et l’article suit immédiatement, c’est-à-dire que la marge haute de 20 pixels de l’article est absorbée par la marge basse de l’entête (on a pas 60 pixels d’écart).
2è cas : les deux éléments sont imbriqués
Voici le code et le résultat.
Ici, on voit bien les 40 pixels au-dessus de l’entête et les 20 pixels qui sépare le bord haut de l’entête du bord haut de l’article. La marge de l’article s’applique du fait de la présence d’une bordure pour les deux éléments.
Maintenant, copiez ce code, CSS et HTML dans une seule page et regarder le résultat dans le navigateur. Il est bien sûr conforme à ce qui est montré ici. Allez dans les outils du développeur et jouez sur l’invalidation (case à cocher dans la fenêtre des styles) des bordures pour observer le résultat.
Vous constaterez que les marges ne fusionnent plus si les deux bordures sont absentes.
Dernier petit test important. Dans le code précédent, remplacez article par h1 et supprimez les bordures et les marges. Vous remarquerez que la marge haute par défaut du titre h1 s’applique, même si celui-ci est placé dans un bloc (ici header
). C’est logique, la marge demandée est respectée. C’est un point qui pourra vous jouer des tours dans le développement.
Application selon le type d’élément
Ce tableau résume les modalités d’application selon que l’élément est de type en ligne ou bloc. A connaître pour éviter les mauvaises surprises.
propriété | en ligne | bloc |
marges hautes et basses | NON | OUI |
marges droites et gauches | OUI | OUI |
Bordures et couleurs de fond
Voici le résumé des propriétés de fond de boîte, pour remplir avec une couleur ou avec une image. Pour rappel, la couleur vert clair désigne les valeurs par défaut et une longueur en pourcentage est relative à la dimension du parent.
propriété | description | valeurs possibles | ||||||||||||
background-color |
Couleur de fond |
|
||||||||||||
background-image |
Image de fond | url donnée par le syntaxe url(adresse)
Par défaut l’image est placée dans le coin haut gauche et se répète, si la place est disponible, horizontalement et verticalement |
||||||||||||
background-position |
Emplacement de l’image de fond par rapport à la boîte.
Il y a un calcul assez savant pour aller de 0% qui désigne la distance bord-à-bord à gauche jusqu’à 100% à droite en passant par 50% qui centre l’image ! |
Les valeurs h et v donne respectivement la position horizontale et verticale. Si seule h est fournie, la valeur pour v est center. Valeurs possibles :
|
||||||||||||
background-size |
Taille de l’image de fond |
|
||||||||||||
background-repeat |
Défini si l’image est répétée pour remplir toute la boîte |
|
||||||||||||
background-attachment |
|
La norme CSS3 définit les propriétés background-clip et background-origin, moins utilisée, que vous pouvez découvrir sur W3school ou MDN.
A noter que background
est une propriété résumé qui prend à la suite les valeurs de background-color, background-image, background-position/background-size, background-repeat, background-origin background-clip background-attachment, seules une partie des premières valeurs pouvant être fournie, le reste prenant les valeurs par défaut.
Venons en aux bordures.
propriété | description | valeurs possibles | ||||||||||||||||||||
border-width |
Largeur de la bordure | Une valeur de longueur fixe ou en pourcentage | ||||||||||||||||||||
border-style |
Style du trait de bordure |
|
||||||||||||||||||||
border-color |
Couleur de la bordure |
|
||||||||||||||||||||
border | Résumé prenant les valeurs border-width border-style border-color à la suite |
ex : border: 2px solid black |
Toutes ces propriétés portent sur les quatre bordures. Il est possible d’en cibler une en particulier en ajoutant top
, bottom
, left
ou right
juste après border avec un tiret, par exemple border-bottom
ou border-bottom-width
.
Il est possible désormais de mettre une image en bordure grâce aux CSS 3 (consulter un site pour plus d’informations).
Largeur et hauteur
propriété | description | valeurs possibles | ||||
width |
Largeur de la boîte |
|
||||
height |
Hauteur de la boîte | idem |
Les dimensions d’une boîte, en largeur et hauteur, dépendent de son contenu et correspondent au comportement associé à la valeur par défaut auto
. Dans tous les cas la boîte s’étire pour épouser les formes de son contenu une fois celui-ci affiché. A noter que les éléments sans contenu ont des comportements de dimension particuliers, comme l’image par exemple qui possède une dimension intrinsèque.
Rappelons à présent quelle sont les dimensions automatiques d’une boîte (valeur auto
) et dans quel cas on peut les fixer par une valeur autre que auto
.
propriété | en ligne avec contenant | bloc |
largeur | Le contenu textuel s’étale au maximum vers la droite puis ver le bas, limité en général par une largeur fixée pour un parent bloc ou par la fenêtre du navigateur. Il n’est pas possible d’en fixer la valeur. |
En automatique, la boîte occupe toute la largeur (équivalent à width:100%) La largeur peut être fixée. |
hauteur | La hauteur est aussi déterminée par le contenu textuel qui s’étire vers le bas selon la largueur du parent (élément avec largeur fixé ou fenêtre du navigateur) et n’inclue pas les marges intérieures et les bordures. Il n’est pas possible d’en fixer la valeur. |
En automatique, la hauteur épouse le contenu de la boîte, y compris les marges et les bordures. La hauteur peut être fixée. |
Le point en gras pour la hauteur des éléments en ligne, peut s’avérer important pour la pagination. En voici l’illustration :
Que se passe-t-il si la largeur ou la hauteur fixé pour un élément est inférieure à celle de son contenu ?
Il y a débordement, le contenu est toujours affiché, débordant de sa boîte. Toutefois la boîte garde la taille qui lui est fixée, en particulier sa bordure s’affiche selon cette taille. Mais les éléments qui suivent la boîte dans le flux HTML seront poussés par le contenu qui déborde.
En voici un exemple plus parlant que toute explication.
<!DOCTYPE html> <html lang="fr"> <head> <title>Ma page</title> <meta charset="utf-8"> <style> div { width: 250px; height: 250px; border: 2px solid red; } div>div { border: 1px solid black; width: 100px; height: 100px; } </style> </head> <body> <div> <div></div> <div></div> <div></div> La suite </div> </body> </html>
Le résultat visuel est clair :
C’est la propriété CSS overflow
qui détermine le rendu visuel de ce débordement.
propriété | description | valeurs possibles | ||||||||
overflow |
Comportement si le contenu déborde de sa boîte |
|
En CSS 3, overflow-x
et overflow-y
ont été introduites pour cibler le débordement horizontal ou vertical.
C’est fini ! Leçon très longue mais essentielle pour la suite avec la mise en page, où nous verrons de nombreuses situations concrètes pour mettre en œuvre ces propriétés de boîte.
Terminons donc pas un bel exercice de synthèse.