Positionner des éléments avec précision se révèle une tâche difficile, voir impossible avec HTML. Les feuilles de style permettent de passer outre ces limitations et apportent de nouvelles possibilités pour disposer les divers éléments d'une page comme nous l'entendons.

Nous commencerons pas étudier de quelle manière le contenu de la page est disposé en fonction de deux types de tags HTML : les tags de type bloc (block) et les tags de type en ligne (inline).

Boîtes bloc ou boîtes en ligne ?

Les tags HTML peuvent être séparés en deux grands types : les tags de type bloc et les tags de type en ligne (ou inline, en ligne). Du type du tag va dépendre le comportement de la boîte utilisée par CSS pour gérer le positionnements, l'affichage, les imbrications, etc.

Rappel : nous avons vue dans la leçon sur les boîtes que TOUS les tags compris entre body et body inclus sont affichés à l'intérieur d'une boîte.

Les éléments de bloc définissent la structure des informations : paragraphes de textes, tableaux, listes, formulaires, etc.

Les éléments en ligne définissent l'enrichissement de l'information : renforcement, liens, zones de saisie, etc.

Le détail des boîtes de bloc ou en ligne se trouve dans les éléments HTML

Les boîtes de type bloc sont disposées les unes sous les autres, alignées sur leur bord gauche (disposition verticale). Par défaut, une boîte de type bloc ne peut pas être à côté d'une autre boîte à sa droite ou à sa gauche : elle est précédée et suivie d'une sorte de saut de ligne.

Les boîtes de type en ligne sont disposées les unes à côté des autres, alignées sur leur bord inférieur (disposition horizontale). Par défaut, une boîte en ligne n'est ni précédée, ni suivie d'un saut de ligne.

L'exemple suivant affiche une page où toutes les boîtes des tags sont entourées d'une bordure verte, à part pour la boîte du tag body entouré en rouge.

Exemple : positionnement
Fichier CSS : styles.css

Blocs conteneurs

Un document HTML est composé de blocs conteneurs : les boîtes de type bloc sont des conteneurs pour les boites qu'elles contiennent (blocs ou en ligne).

Les boîtes de type bloc peuvent contenir d'autres boîtes de type bloc et/ou en ligne. Elles peuvent avoir des dimensions définies (hauteur, largeur), posséder des marges externes (margin) et en ligne (padding), des bords (border) et être positionnées pour définir la mise en page du document. Par défaut, la plupart des éléments bloc possèdent des marges internes et externes non nulles, souvent différentes selon les navigateurs.

Les boîtes de type en ligne ne peuvent contenir que d'autres boites de type en ligne. Seules les boîtes les éléments img, input, textarea et select peuvent avoir des dimensions définies. Les boîtes des autres tags en ligne occupent la place minimum nécessaire à leur contenu. Les boîtes en ligne ont des marges en ligne et externes nulles par défaut. Bien que l'on puisse les positionner, on ne devrait pas utiliser cette possibilité puisque ces boîtes affichent des éléments dans le flot normal du texte.

L'imbrication des balises HTML est traduite par des relations ancêtre / descendants, parent / enfants et fréres :

Le code suivant met en évidence les différentes boîtes en coloriant leur fond.

Exemple : positionnement
Fichier CSS : styles.css

Dans les spécifications CSS, un bloc conteneur est défini de la façon suivante :

Le bloc conteneur sert à déterminer le positionnement et éventuellement les dimensions des boîtes qu'il contient. Les propriétés de style avec une valeur relative (pourcentage, em, etc.) sont calculées à partir de la valeur correspondante du bloc conteneur. Dans l'exemple suivant nous définissons la police des tags p avec une taille de 16 pixels de haut. Nous définissons aussi une classe avec une police de taille relative de 70% et une autre classe avec une police relative de 130%.

Exemple : positionnement
Fichier CSS : styles.css

Héritage (rappel). Certaines propriétés sont transmises d'un élément parent à ses éléments enfants (héritage). Il y a relativement peu de propriétés d'héritage et un grand nombre d'entre elles sont des propriétés peu utilisées. Les propriétés qui héritent, les plus souvent utilisées sont les suivantes : voir les propriétés de style

Comment se fait le positionnement

Il existe 4 modes de positionnement CSS : normal, relatif, flottant et absolu.

Positionnement normal

Le positionnement normal, ou flux normal, est le mode de positionnement par défaut.

Les boîtes de type bloc sont placées les unes en dessous des autres à partir du haut de leur bloc conteneur.

Les boîtes de type en ligne sont placées les unes à côté des autres, de gauche à droite.

Dans l'exemple suivant, le conteneur avec un fond jaune contient deux blocs paragraphes, positionnés normalement l'un en dessous de l'autre.

Exemple : positionnement
Fichier CSS : styles.css

Si 2 boîtes de type bloc se suivent, la marge inférieure de la première et la marge supérieure de la seconde ne s'ajoutent pas : seule la marge la plus grande est conservée.

Les marges horizontales (gauche et droite) ne sont jamais imbriquées.

Dans l'exemple suivant, la marge séparant les deux boîtes n'est pas de 60 pixels (30 + 30) mais seulement de 30 pixels.

Exemple : positionnement
Fichier CSS : styles.css

Les boîtes de type en ligne sont placées les une à côté des autres, de gauche à droite et peuvent déborder sur la ligne suivante, si leur longueur est plus grande que l'espace disponible.

Exemple : positionnement
Fichier CSS : styles.css

Le positionnement relatif

Pour qu'une boîte soit positionnée de façon relative, il faut définir la propriété position avec la valeur relative.

La boîte est d'abord positionnée selon les règles du flux normal qui s'appliquent à son type (bloc ou en ligne). La boîte est ensuite repositionnée suivant la valeur de ses propriétés left, top, right et bottom. Les unités utilisables sont le pouce (in), le centimètre (cm), le millimètre (mm), le point (pt), le picas (pc), le pixel (px) et la distance (em). Le contenu suivant n'est pas affecté par ce déplacement, qui peut donc entraîner des chevauchements.

Remarque : pour que les propriétés left et top soient prises en compte, la propriété position (quelque soit sa valeur) doit être explicitement définie dans la règle de style.

L'exemple suivant affiche trois paragraphes. le deuxième est affichée relativement au premier, avec un décalage de 50 pixels à gauche et 30 pixel en haut.

Exemple : positionnement
Fichier CSS : styles.css

Le positionnement initial peut générer une imbrication des marges verticales. Le repositionnement en fonction des propriétés de décalage peut faire en sorte que des éléments soient superposés.

Le positionnement flottant

Pour faire flotter une boîte, il faut utiliser la propriété float et lui assigner une des deux valeurs possibles : left ou right.

La boîte est d'abord placée normallement dans le flux. Elle est ensuite poussée le plus à gauche possible des on conteneur (float: left) ou le plus à droite possible de son conteneur (float: right). Les éléments qui suivent la boîte flottante dans le conteneur se placent ensuite autour d'elle.

Une boîte flottante doit posséder une propriété width, indiquant sa largeur, sinon la boîte occupera toute la largeur de son conteneur. Une boîte flottante est toujours considérée comme une boîte de type bloc même si son contenu est de type en ligne.

Les marges verticales d'une boîte flottante ne sont jamais combinées avec celles les boîtes supérieure ou inférieure comme dans le flux normal.

L'exemple suivant affiche un paragraphe contenant une boîte flottante à droite.

Exemple : positionnement
Fichier CSS : styles.css

Comme une boîte flottante sort du flux normal, sa hauteur n'est pas comptée dans le calcul de la hauteur du conteneur. Une boîte flottante peut donc déborder en hauteur et s'étendre sur plusieurs boîtes comme dans l'exemple suivant. Les règles de styles sont les mêmes que dans l'exemple précédent, nous enlevons simplement du texte dans le paragraphe et en ajoutons dans la boîte flottante. Un second paragraphe est affiché en dessous du premier pour bien montrer le chevauchement.

Exemple : positionnement
Fichier CSS : styles.css

Pour éviter le débordement, la propriété clear peut être utilisée dans la boîte suivant la boîte flottante.

La propriété clear a pour effet d'agrandir la marge du haut de la boîte suivant la boîte flottante, pour qu'elle se positionne juste sous la boîte flottante. Cette propriété peut prendre les valeurs left (pour les boîtes avec float: left), right (pour les boîtes avec float: right), both (les deux côtés), none (aucun) ou inherit (hérite).

Nous pouvons modifier le code de la façon suivante :

p {border: 1px solid;
    margin: 20px;
    padding: 10px;
    background-color: #cfc;
    clear: right; }
Exemple : positionnement
Fichier CSS : styles.css

Boîtes flottantes adjacentes

Lorsque 2 boîtes adjacentes (côte à côte) ou plus sont flottantes, leur bord haut est positionné sur la même ligne si il y a assez de place. Si il n'y a pas assez de place, la ou les dernières boîtes flottantes sont déplacées plus bas dans la première position où il y a assez de place.

Exemple : positionnement
Fichier CSS : styles.css

Pour forcer les boîtes flottantes à s'afficher les unes en dessous des autres, il faut utiliser la propriété clear :

Exemple : positionnement
Fichier CSS : styles.css

Le positionnement flottant de plusieurs boîte adjacentes peut être utilisé pour réaliser des mises en page avec des colonnes.

Exemple : positionnement
Fichier CSS : styles.css

Le positionnement absolu

Pour qu'une boîte ait un positionnement absolu, il faut utiliser la propriété position avec la valeur absolute ou fixed.

Quand une boîte est positionnée en absolu, elle est retirée du flux normal qui n'en tient pas compte pour gérer son affichage. La position de la boîte à l'écran sera la même, quelle que soit l'emplacement de la balise dans le code HTML. Les boîtes positionnées en absolu sont toujours considérées comme des boîtes de type bloc et sont le conteneur de leurs éléments descendants.

La position d'une boîte absolue à l'intérieur de son conteneur est déterminée par les propriétés top, right, bottom et left. Les unités utilisables sont le pouce (in), le centimètre (cm), le millimètre (mm), le point (pt), le picas (pc), le pixel (px) et la distance (em). La position est calculée en référence au point supérieur gauche du bloc conteneur de la boîte (à la différence du positionnement relatif où le décalage est caclulé par rapport au flux normal). La marge interne (padding) éventuelle du bloc conteneur n'est pas prise en compte.

Le bloc conteneur d'un élément en positionnement absolu est défini par son parent le plus proche :

Remarque : quand le conteneur est en flux normal ou en float, il suffit de lui donner une propriété position: relative sans préciser de top et de left pour le positionner. Il sera placé là où il est déjà, mais pourra servir de conteneur à un bloc en positionnement absolu.

Exemple : positionnement
Fichier CSS : styles.css

Les blocs en positionnement absolu peuvent se superposer à d'autres blocs (non positionnés ou aussi en positionnement absolu). Chaque bloc en positionnement absolu appartient à un contexte de superposition. Le contexte de superposition initial est défini par le bloc conteneur initial (la fenêtre du navigateur) et ensuite chaque bloc conteneur définit son contexte de superposition. Pour gérer l'ordre de superposition à l'intérieur d'un contexte on utilise la propriété z-index dont la valeur est un nombre. Plus le nombre est élevé, plus le bloc est mis au dessus de la superposition. Si dans un même contexte, plusieurs blocs en positionnement absolu n'ont pas de z-index, c'est leur ordre d'apparition dans le code HTML qui détermine leur ordre de superposition.

Exemple : positionnement
Fichier CSS : styles.css

L'affichage montre que l'élément ""L'Hagard des Etoiles"" est affiché au dessus de l'élément suivant bien qu'il apparaissent avant dans le code HTML.

Le positionnement absolu peut être utilisé comme le positionnement flottant pour réaliser des mises en page avec des colonnes.

Exemple : positionnement
Fichier CSS : styles.css

Pour laisser de la place au bloc de menu de 150 pixels de large, il faut créer une marge externe gauche dans le bloc de contenu :

La propriété display

La propriété display permet de forcer une boîte à se comporter en boîte de type bloc (display: block) ou en boîte de type en ligne (display: inline). La propriété display permet aussi à une boîte d'être retirée du flot, c'est à dire de na pas être affichée (display: none). Cette dernière valeur est surtout utilisée en conjonction avec JavaScript pour réaliser des éléments d'interface comme des menus déroulants.

La transformation d'une boîte bloc en boîte ligne est intéressante avec les listes. Par défaut chaque ligne d'une liste est considérée comme une boîte de type bloc, ce qui fait que les lignes de la liste sont affichées les une en dessous des autres.

Soit la liste :

Vaisseaux
<ul>
<li>X-Wing</li>
<li>Y-Wing</li>
<li>Tie Def</li>
<li>Tie Adv</li>
</ul>

Attention, ça devient très technique. Les X-Wing et autres Tie Adv sont des chasseurs utilisés dans les épisodes 4, 5 et 6 de la Guerre des Etoiles (les chasseurs n'étant pas des gugusses avec des fusils et un ouahouah, mais des vaisseaux spaciaux - un peu de sérieux siouplait).

Pour que les boîtes des lignes de la liste soient bien visibles, appliquons les règles suivantes :

li {border: 1px solid;
    margin: 2px;
    padding: 2px;
    background-color: #cfc;}

En utilisant la propriété display avec la valeur inline nous transformons la liste verticale en liste horizontale.

li {display: inline;
    border: 1px solid;
    margin: 2px;
    padding: 2px;
    background-color: #cfc;} 
Exemple : positionnement
Fichier CSS : styles.css

Nous pouvons aussi utiliser la propriété display avec la valeur inline sur l'élément ul pour que le libellé menu soit sur la même ligne que les choix, et nous pouvons donner la même dimension aux boîtes.

ul {display: inline;
    margin: 0px;}
li {width: 70px;
    display: inline;
    border: 1px solid;
    margin: 2px;
    padding: 2px;
    background-color: #cfc;} 

La transformation d'une boîte en ligne en boîte bloc peut être fait par exemple pour un lien. Reprenons le menu précédent en mettant des liens sur les divers éléments de la liste.

Exemple : positionnement
Fichier CSS : styles.css

En testant nous voyons que la zone réactive du lien s'arrête avec le texte. Si nous changeons le type de la boîte d'un lien, qui est de type en ligne par défaut, en type bloc et que nous lui donnons une largeur, c'est tout le bloc qui deviendra réactif et qui se comportera alors comme un bouton.

a {display: block;
   width: 70px;
   text-decoration: none;
   text-align: center; } 

Pour montrer une utilisation de la propriété display avec la valeur none nous prendrons l'exemple de bulle d'aide affichée au passage de la souris sur un lien.

Attention, un peu de concentration, et rendez-vous après le test pour les explications.

Exemple : positionnement
Fichier CSS : styles.css

D'abord le code HTML pour le lien :

Je n'reconnais plus personne en <a class="bulle" href="page.htm">Faucon Millenium<span>Pour ceux qui dormaient au cours des 30 dernières années, le Faucon Millenium est le vaisseau de Han Solo</span></a>

On voit que le texte de la bulle d'aide est entouré de tag <span> et imbriqué dans un lien stylé avec la classe bulle.

Commençons donc par la règle pour les liens de classe "bulle" :

a.bulle {position: relative;}

Nous forçons une position relative pour que la bulle puisse être affichée de façon absolue par rapport au lien (rappel : le parent d'un élément affiché en absolu doit avoir une propriété position explicitement définie).

Nous définissons ensuite une règle pour les tags span contenu dans des tags a de classe "bulle"

a.bulle span {display: none;}

Cette règle spécifie que le contenu du tag span n'est pas affiché, et pas pris en compte dans les calculs de positionnement des boîte de contenu.

Nous définissons ensuite ce qui se passe quand la souris survole un lien de classe "bulle".

a.bulle:hover { background: none;
                z-index: 9999;}

La propriété background-color est là uniquement pour résoudre un bug de Internet Explorer. La propriété z-index garanti que le texte du lien sera toujours au premier plan.

Finalement tout se passe dans les règles concernant l'affichage du tag span (contenant le texte de la bulle d'aide) quand la souris survole un lien de classe "bulle".

a.bulle:hover span { display: inline;
                     position: absolute;
                     top: 2em;
                     left: 1em;
                     width: 10em;
                     background: yellow;
                     text-align: center;
                     border: 1px solid;
                     padding: 2px;
                     text-decoration: none;
                     color: black;}

Nous changeons le type de la boîte de aucun à en ligne. Nous définissons une position absolue par rapport à son parent (le lien), en utilisant un déclage de 2 em en bas et 1 em à droite. Avec l'unité em, proportionnelle à la taille de la police, nous sommes sûrs de toujours bien positionner la bulle d'aide. Le reste des règles ne pose pas de problème. Il ne faut pas oublier d'enlever le soulignement du texte (text-decoration: none;) et de lui donner une couleur noire (color: black;) car la bulle d'aide est imbriquée dans un lien, et donc son texte sera souligné et bleu.

Et encore plus fort (si c'est possible !)

Exemple : positionnement
Fichier CSS : styles.css