CSS : la propriété position

Dans la page précédente je vous ai montré que pour mettre de front plusieurs éléments de type "blocs" on utilisait float : left / right ou display : inline-block. Alors à quoi sert la propriété position ?

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 : 999 à 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 adsimulata patrimonia sua in inmensum extollunt, cultorum ut puta feracium multiplicantes annuos fructus, ... </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 ; } h2 {font-size : 1.5em ; text-align : center ; } p {font-size : 1em ; text-align : justify ; } a {display : inline-block ; width : 15% ; margin :1%; font-size : 1.2em; }

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 pouvoire donner un top initial à SECTION il faut positionner cette boite en "relatif" ; voir paragraphe suivant.
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 !

Nous venons de voir dans le premier exemple de cette page que la zone de navigation était positonnée en fixe et la zone de contenu en relatif.

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 de l'exemple

... <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 boîte 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.

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.

Superposer les boites

Si vous voulez superposer des boites il faut utiliser le positionnement absolu. L'ordre d'empilement des boites est gérée par la propriété z-index.
Dans l'exemple ci-dessous de couleur se superposent partiellement. La boite survolée passe au premier plan.

Le code de l'exemple

... <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> ...
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 donné par le code HTML (3 sur 2 et 2 sur 1).
Si une boite en couleurs est survolée elle passe en premier plan (z-index passe à 999).

Centrage horizontal et vertical d'un boite dans son conteneur

Le centrage horizontal d'une boite dans son conteneur n'a jamais posé de difficulté. Il suffit d'appliquer à l'élément "block" enfant les propriétés margin-left : auto & margin-right : auto.
Par contre le centrage vertical était un casse-tête en CSS 2. En effet margin-top : auto & margin-bottom : auto ça marche pas !!!
La seule solution est de positionner la boite "enfant" en absolu (position : absolute) et alors margin-left : auto & margin-right : auto ça marche plus !

Le code HTML de l'exemple

<div id ="conteneur"> <div id ="enfant"> <p>Post hanc adclinis Libano monti Phoenice, regio plena gratiarum et venustatis, urbibus decorata magnis et pulchris; in quibus amoenitate celebritateque nominum Tyros excellit, Sidon et Berytus isdemque pares Emissa et Damascus saeculis condita priscis. </div> </div>

La boite identifiée "enfant" est contenue dans la boite identifiée "conteneur".

Le code CSS de l'exemple

		#conteneur{ position : relative ; width : 900px ;border : 1px solid red; height : 400px ; margin : auto ; }
		#enfant {position : absolute ; width : 60% ;  height : 200px ;
		top : 50% ; margin-top :-100px ;  
		left : 50% ; margin-left : -30%; 
		background : pink ; }
		...

C'est assez subtil.
Pour que les left & top soient calculés par rapport au coin supérieur gauche du conteneur (et non pas le coin supérieur gauche de la fenêtre) le conteneur doit lui même être positionné en absolu (ou relatif ou fixe).
Pour le centrage horizontal il faut régler left à 50% & margin-left à - la moitié de la largeur de l'enfant donc ici à "-30%".
Pour le centrage vertical il faut régler top à 50% & margin-top à - la moitié de la hauteur de l'enfant donc ici à "-100px".
Testez le code !

Positionnement dans le futur

Tout ce bidouillage est un mauvais souvenir. CSS3 introduit l'outil flexbox (ou boites flexibles).
Maintenant il faut un peu de temps pour que les développeurs web changent leurs habitudes sinon les navigateurs récents ont bien implémenté ce nouvel outil. Positionner avec l'outil flexbox
Retour menu