Icône Le positionnement en CSS

Lire cette page et à la fin faire le QCM et l'exercice. L'objectif est de connaître les balises permettant de réaliser un positionnement flottant du menu.


    Voici venu le moment tant attendu : nous allons apprendre à modifier la position des éléments sur notre page. La théorie que nous allons voir ici nous sera indispensable dans le prochain chapitre, dans lequel nous réaliserons le design de notre premier site ensemble pas à pas !

    Vous allez voir, il existe plusieurs techniques permettant d'effectuer la mise en page de son site. Chacune a ses avantages et ses défauts, ce sera à vous de sélectionner celle qui vous semble la meilleure selon votre cas.

Le positionnement flottant

La technique présentée ici l'est à titre d'information. Elle est utilisée par la majorité des sites à l'heure actuelle mais comporte un certain nombre de défauts. Une meilleure technique sera présentée un peu plus loin, le positionnement inline-block, que je vous encourage à utiliser autant que possible.


Vous vous souvenez de la propriété float ? Nous l'avons utilisée pour faire flotter une image autour du texte :

Image utilisateur


Il se trouve que cette propriété est aujourd'hui utilisée par la majorité des sites web pour... faire la mise en page ! En effet, si on veut placer son menu à gauche et le contenu de sa page à droite, c'est a priori un bon moyen. Je dis bien a priori, car cette propriété n'a pas été conçue pour faire la mise en page à la base et nous allons voir qu'elle a quelques petits défauts.

Reprenons le code HTML structuré que nous avons réalisé il y a quelques chapitres :

Code : HTML - Sélectionner
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Zozor - Le Site Web</title>
    </head>

    <body>
        <header>
            <h1>Zozor</h1>
            <h2>Carnets de voyage</h2>
        </header>
        
        <nav>
            <ul>
                <li><a href="#">Accueil</a></li>
                <li><a href="#">Blog</a></li>
                <li><a href="#">CV</a></li>
            </ul>
        </nav>
        
        <section>
            <aside>
                <h1>A propos de l'auteur</h1>
                <p>C'est moi, Zozor ! Je suis né un 23 novembre 2005.</p>
            </aside>
            <article>                
                <h1>Je suis un grand voyageur</h1>
                <p>Bla bla bla bla (texte de l'article)</p>
            </article>
        </section>
        
        <footer>
            <p>Copyright Zozor - Tous droits réservés

            <a href="#">Me contacter !</a></p>
        </footer>
        
    </body>
</html>


Je rappelle que, sans CSS, la mise en page ressemble à ceci :

Image utilisateur


Nous allons essayer de placer le menu à gauche, et le reste du texte à droite. Pour cela, nous allons faire flotter le menu à gauche, et laisser le reste du texte se placer à sa droite.

Nous voulons que le menu occupe 150 pixels de large. Nous allons aussi rajouter une bordure noire au menu et une bordure bleue au corps (à la <section>) pour bien les distinguer :

Code : CSS - Sélectionner
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
nav
{
    float: left;
    width: 150px;
    border: 1px solid black;
}

section
{
    border: 1px solid blue;
}


Voici le résultat :

Le menu est bien positionné, mais collé au texte


Ca n'est pas encore tout à fait ça.

Il y a deux défauts (mis à part le fait que c'est encore bien moche) :

  • Le texte du corps de la page touche la bordure du menu. Il manque une petite marge...
  • Plus embêtant encore : la suite du texte passe... sous le menu !


On veut bien que le pied de page ("Copyright Zozor") soit placé en bas sous le menu, mais par contre on aimerait que tout le corps de page soit constitué comme un seul bloc à droite.

Pour résoudre ces deux problèmes d'un seul coup, il faut ajouter une marge extérieure à gauche de notre <section> supérieure à la largeur du menu. Si notre menu fait 150px, nous allons par exemple donner une marge extérieure gauche de 170px à notre section de page.

Code : CSS - Sélectionner
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
nav
{
    float: left;
    width: 150px;
    border: 1px solid black;
}

section
{
    margin-left: 170px;
    border: 1px solid blue;
}


Le corps de page est bien aligné à droite du menu


Voilà, le contenu de la page est maintenant correctement aligné. :)

A l'inverse, il se peut que vous souhaitiez qu'un élément se place obligatoirement sous le menu. Dans ce cas, il faudra utiliser... clear: both;, que nous avions déjà découvert, qui oblige la suite du texte à se positionner sous l'élément flottant.

Transformez vos éléments avec display

Je vais vous apprendre ici à repousser les lois de la physique à modifier les lois du CSS (brrr...). Accrochez-vous !

Il existe en CSS une propriété très puissante : display. Elle est capable de transformer n'importe quel élément de votre page d'un type vers un autre. Avec cette propriété magique, je peux par exemple transformer mes liens (originellement de type inline) sous forme de blocs :

Code : CSS - Sélectionner
1
2
3
4
a
{
    display: block;
}


A ce moment-là, les liens vont se positionner les uns en-dessous des autres (comme des blocs normaux) et il devient possible de modifier leurs dimensions !

Voici quelques-unes des principales valeurs que peut prendre la propriété display en CSS (il y en a encore d'autres) :

Valeur Exemples Description
inline <a>, <em>, <span>... Eléments d'une ligne. Se placent les uns à côté des autres.
block <p>, <div>, <section>... Eléments en forme de blocs. Se placent les uns en-dessous des autres et peuvent être redimensionnés.
inline-block <select>, <input> Eléments positionnés les uns à côté des autres (comme les inline) mais qui peuvent être redimensionnés (comme les blocs).
none <head> Eléments non affichés.


On peut donc décider de masquer complètement un élément de la page avec cette propriété. Par exemple, si je veux masquer les éléments qui ont la classe "secret", je vais écrire :

Code : CSS - Sélectionner
1
2
3
4
.secret
{
    display: none;
}


Et quel est ce nouveau type bizarre, inline-block ? C'est un mélange ? o_O


Oui, ce type d'élément est en fait une combinaison des inline et des blocks. C'est un peu le meilleur des deux mondes : ils s'affichent côte à côte et peuvent être redimensionnés.

Peu de balises sont affichées comme cela par défaut, c'est surtout le cas des éléments de formulaire (comme <input>) que nous découvrirons un peu plus tard. Par contre, avec la propriété display, nous allons pouvoir transformer d'autres balises en inline-block, ce qui va nous aider pour réaliser notre design. :)

Le positionnement inline-block

Les manipulations que demande le positionnement flottant se révèlent parfois un peu délicates sur des sites complexes. Dès qu'il y a un peu plus qu'un simple menu à mettre en page, on risque d'avoir à recourir à des clear: both; qui complexifient rapidement le code de la page.

Si le positionnement flottant reste, de loin, le mode de positionnement le plus utilisé sur le Web à l'heure actuelle, d'autres techniques existent et bien peu de webmasters le savent. L'une d'elles, étonnamment puissante, est passée sous les yeux des concepteurs de sites web alors qu'elle existe depuis CSS 2.1, c'est-à-dire depuis plus de 10 ans ! Elle consiste à transformer vos éléments en inline-block avec la propriété display.

Quelques petits rappels sur les éléments de type inline-block :

  • Ils se positionnent les uns à côté des autres (exactement ce qu'on veut pour placer notre menu et le corps de notre page !).
  • On peut leur donner des dimensions précises (là encore, exactement ce qu'on veut !).


Nous allons transformer en inline-block les deux éléments que nous voulons placer côte à côte : le menu de navigation et la section du centre de la page.

Code : CSS - Sélectionner
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
nav
{
    display: inline-block;
    width: 150px;
    border: 1px solid black;
}

section
{
    display: inline-block;    
    border: 1px solid blue;
}


Le menu et le corps sont côte à côte... mais positionnés en bas !


Argh ! :(
Ca n'est pas tout à fait ce qu'on voulait là encore. Et en fait, c'est normal : les éléments inline-block se positionnent sur une même ligne de base (appelée baseline), en bas.

Heureusement, le fait d'avoir transformé les éléments en inline-block nous permet d'utiliser une nouvelle propriété, normalement réservée aux tableaux : vertical-align. Cette propriété permet de modifier l’alignement vertical des éléments. Voici quelques-unes des valeurs possibles pour cette propriété :

  • baseline : aligne la base de l'élément avec celle de l'élément parent (par défaut)
  • top : aligne en haut
  • middle : aligne au milieu
  • bottom : aligne en bas
  • (valeur en px ou %) : aligne à une certaine distance de la ligne de base (baseline)

Il ne nous reste plus qu'à aligner nos éléments en haut, et le tour est joué !

Code : CSS - Sélectionner
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
nav
{
    display: inline-block;
    width: 150px;
    border: 1px solid black;
    vertical-align: top;
}

section
{
    display: inline-block;    
    border: 1px solid blue;
    vertical-align: top;
}


Le menu et le corps sont alignés en haut côte à côte


Vous noterez que le corps (la <section>) ne prend pas toute la largeur. En effet, ce n'est plus un bloc ! La section occupe seulement la place dont elle a besoin.
Si cela ne vous convient pas pour votre design, modifiez la taille de la section avec width.


Et voilà ! Pas besoin de s'embêter avec les marges, aucun risque que le texte passe sous le menu... Bref, c'est parfait ! :D

... Quoi ? Pardon, on me signale dans l'oreillette qu'un certain navigateur vient jouer les trouble-fêtes...

inline-block et compatibilité Internet Explorer



Le positionnement inline-block est parfaitement compris par Internet Explorer à partir de IE8.

Pour les anciennes versions, IE6 et IE7 en particulier, le positionnement inline-block fonctionne... mais uniquement sur les éléments qui étaient des inline à la base !


Code : HTML - Sélectionner
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="style.css" />
        <!--[if lte IE 7]>
        <link rel="stylesheet" href="style_ie.css" />
        <![endif]-->

        <title>Zozor - Le Site Web</title>
    </head>


Dans style_ie.css, rajoutez simplement le code suivant :

Code : CSS - Sélectionner
1
2
3
4
5
nav, section
{
    display: inline;
    zoom: 1;
}


Les positionnements absolu, fixe et relatif

Il existe d'autres techniques un peu particulières permettant de positionner avec précision des éléments sur la page :
  • Le positionnement absolu : il nous permet de placer un élément n'importe où sur la page (en haut à gauche, en bas à droite, tout au centre, etc..)
  • Le positionnement fixe : identique au positionnement absolu, mais cette fois l'élément reste toujours visible, même si on descend plus bas dans la page. C'est un peu comme le même principe que background-attachment: fixed; (si vous vous en souvenez encore).
  • Le positionnement relatif : permet de décaler l'élément par rapport à sa position normale.


Comme pour les flottants, le positionnement absolu, fixé et relatif fonctionne aussi sur des balises de type inline.
Toutefois, vous verrez qu'on l'utilise bien plus souvent sur des balises block que sur des balises inline.


Il faut d'abord faire son choix entre les 3 modes de positionnement disponibles. Pour cela, on utilise la propriété CSS position à laquelle on donne une de ces valeurs :

  • absolute : positionnement absolu.
  • fixed : positionnement fixe.
  • relative : positionnement relatif.


Nous allons étudier chacun de ces positionnements un à un.

Le positionnement absolu



Le positionnement absolu permet de placer un élément (réellement) n'importe où sur la page. Pour effectuer un positionnement absolu, on doit écrire :

Code : CSS - Sélectionner
1
2
3
4
element
{
    position: absolute;
}


Mais ça ne suffit pas ! On a dit qu'on voulait un positionnement absolu, mais encore faut-il dire où on veut que le bloc soit positionné sur la page.
Pour ce faire, on va utiliser 4 propriétés CSS :

  • left : position par rapport à la gauche de la page.
  • right : position par rapport à la droite de la page.
  • top : position par rapport au haut de la page.
  • bottom : position par rapport au bas de la page.


On peut leur donner une valeur en pixels, comme "14px", ou bien une valeur en pourcentage, comme "50%".

Si ce n'est pas très clair pour certains d'entre vous, ce schéma devrait vous aider à comprendre :

Positionnement de l'élément sur la page


Avec ça, vous devriez être capables de positionner correctement votre bloc. :)

Il faut donc utiliser la propriété position et au moins une des 4 propriétés ci-dessus (top, left, right ou bottom). Si on écrit par exemple :

Code : CSS - Sélectionner
1
2
3
4
5
6
element
{
    position: absolute;
    right: 0px;
    bottom: 0px;
}


... cela signifie que le bloc doit être positionné tout en bas à droite (0 pixels par rapport à la droite de la page, 0 par rapport au bas de la page).

Si on essaye de placer notre bloc <nav> en bas à droite de la page, on obtient ce résultat :

Le menu est positionné en bas à droite de l'écran


On peut bien entendu ajouter une marge intérieure (padding) au menu pour qu'il soit moins collé à sa bordure.

Les éléments positionnés en absolu sont placés par-dessus le reste des éléments de la page ! Par ailleurs, si vous placez deux éléments en absolu vers le même endroit, ils risquent de se chevaucher. Dans ce cas, utilisez la propriété z-index pour indiquer quel élément doit apparaître par-dessus les autres :

Code : CSS - Sélectionner
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
element
{
    position: absolute;
    right: 0px;
    bottom: 0px;
    z-index: 1;
}
element2
{
    position: absolute;
    right: 30px;
    bottom: 30px;
    z-index: 2;
}


L'élément ayant la valeur de z-index la plus élevée sera placé par-dessus les autres, comme le montre ce schéma :

Positionnement des éléments absolus


Une petite précision technique qui a son importance : le positionnement absolu ne se fait pas toujours forcément par rapport au coin en haut à gauche de la fenêtre ! Si vous positionnez en absolu un bloc A qui se trouve dans un autre bloc B lui-même positionné en absolu (ou fixe ou relatif), alors votre bloc A se positionnera par rapport au coin en haut à gauche du bloc B. Faites le test, vous verrez !


Le positionnement fixe



Le principe est exactement le même que pour le positionnement absolu, sauf que cette fois le bloc reste fixe à sa position, même si on descend plus bas dans la page.

Code : CSS - Sélectionner
1
2
3
4
5
6
element
{
    position: fixed;
    right: 0px;
    bottom: 0px;
}


Essayez le résultat, vous verrez que le menu reste dans le cas présent affiché en bas à droite même si on descend plus bas dans la page.



Le positionnement relatif



Le positionnement relatif est un petit peu plus délicat à utiliser. Ce positionnement permet d'effectuer des "ajustements" : l'élément est décalé par rapport à sa position initiale.

Prenons par exemple un texte important, situé entre 2 balises <strong>. Pour commencer, je le mets sur fond rouge pour qu'on puisse mieux le repérer :

Code : CSS - Sélectionner
1
2
3
4
5
strong
{
   background-color: red; /* Fond rouge */
   color: yellow; /* Texte de couleur jaune */
}


Cette fois, le schéma que je vous ai montré tout à l'heure pour les positions absolue et fixe ne marche plus. Pourquoi ? Parce que l'origine a changé : le point de coordonnées (0, 0) ne se trouve plus en haut à gauche de votre fenêtre comme c'était le cas tout à l'heure. Non, cette fois l'origine se trouve en haut à gauche... de la position actuelle de votre élément.

Tordu n'est-ce pas ? C'est le principe de la position relative. Ce schéma devrait vous aider à comprendre où se trouve l'origine des points :

Image utilisateur


Donc, si vous faites un position: relative; et que vous appliquez une des propriétés top, left, right ou bottom, le texte sur fond rouge va se déplacer par rapport à la position où il se trouve.

Prenons un exemple : je veux que mon texte se décale de 55 pixels vers la droite et de 10 pixels vers le bas. Je vais donc demander à ce qu'il soit décalé de 55 pixels par rapport au "bord gauche", et de 10 pixels par rapport au "bord haut" :

Code : CSS - Sélectionner
1
2
3
4
5
6
7
8
9
strong
{
   background-color: red;
   color: yellow;
   
   position: relative;
   left: 55px;
   top: 10px;
}


Le texte s'est alors décalé par rapport à sa position initiale, comme ceci :

Image utilisateur