Les positionnements CSS

La mise en page Web nécessite une bonne compréhension des langages HTML et CSS. Il existe beaucoup de méthodes très différentes pour positionner des éléments sur une page. Je conseille d'en maîtriser une ou deux, plutôt que d'essayer d'effleurer l'ensemble des techniques de positionnement.

Le flux normal : étude du positionnement sans CSS

Nous savons que le navigateur lit le code HTML de haut en bas, et de gauche à droite sur chaque ligne. A chaque fois que le navigateur va positionner une balise, cette dernière comporte naturellement des réglages qui influent sur son positionnement : des marges extérieures et intérieures (margin et padding), des alignements (text-align), des hauteurs de ligne (line-height), etc. Rien n'est neutre, même quand on écrit du texte normal avec <p>, le navigateur impose un choix de couleurs de premier plan (noir) et d'arrière plan (transparent), une taille de police (16px), un espacement avant et après chaque ligne, et des dizaines d'autres réglages qu'on ne remarque pas.

Pour bien positionner des textes, des images, et tout autre élément composant une page, je conseille aux débutants de démarrer d'une page blanche et de s'entrainer avec quelques balises. Il ne faut surtout pas copier coller du code tout prêt pour apprendre.

Essai sans CSS, 100% HTML

Positionnons pour l'exemple, un titre, un texte, une image et deux liens.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
	</head>
	<body>
		<h1>Mon blog</h1>
		<p>Un texte vraiment intéressant.</p>
		<img src="perroquet.jpg" alt="perroquet">
		<a href="#">Un lien</a>
		<a href="#">Un autre lien</a>
	</body> 
</html>

Ce qui donne :

positionnement1

Le flux normal représente ici l'ordre naturel de chaque balise, sans spécifier la moindre feuille de style. Les balises se positionnement par rapport à leur ordre de lecture et par rapport à leur caractéristique.

<h1>

La création d'un titre <h1> implique un retour à la ligne et un espacement vertical. Le Consortium (w3.org) qui donne les spécifications du HTML, s'appuie sur des siècles de règles typographiques émanant des livres et des journaux. L'espacement vertical avant et après le titre servent à bien séparer le titre du texte qui suit. Le titre est également gras. Tout est fait pour mettre en exergue le contenu de la balise <h1>. N'est-ce pas le but d'un titre ?

<p>

La balise <p> crée également un espacement vertical de manière à isoler des blocs de texte. En théorie, chaque paragraphe exprime une idée. Si l'on veut revenir à la ligne au sein d'un paragraphe, il faudra recourir à la balise <br> qui reviendra à la ligne sans produire d'espacement vertical. Tout ceci est logique.

<a>

Les liens sont sur la même ligne, car dans le fondement du web, un lien hypertexte doit être au cœur d'un texte sans forcément produire un retour à la ligne. Observez Wikipedia et vous comprendrez qu'il est bien pratique qu'un texte se poursuive sans retour à la ligne à chaque lien ajouté.

Les espaces entre les liens sont causés par le retour à la ligne suivant chaque lien dans le code. Cela peut paraître étrange, mais la manière dont sont positionnées les lignes dans le code source peut influer sur l'affichage. Pour éliminer certains espaces, il faut parfois écrire un code sur une même ligne dans votre éditeur préféré.

<img>

Les images peuvent être habillées de texte ou apparaissent parfois en vignettes alignées sur une même ligne, ce qui explique leur affichage naturel en ligne. Là aussi, le Consortium a opté pour l'affichage de chaque balise en rapport à son usage le plus fréquent et le plus traditionnel dans le web et l'imprimé.

Cette constatation nous amène à classer les balises en 2 grandes catégories : les balises de type boite et les balises en ligne.

Les balises en ligne

Ces balises ne produisent pas de retour à la ligne et prennent la largeur de leur contenu. En voici quelques unes :

  • <span>
  • <a>
  • <img>
  • <i>, <em>
  • <b>, <strong>
  • <q>

Les balises de type boite ou bloc

Ces balises produisent un retour à la ligne et prennent la largeur de leur conteneur. En voici quelques unes :

  • <h1>, <h2>, <h3>, <h4>, <h5>, <h6>
  • <p>
  • <ul>, <ol>, <li>
  • <br>, <hr>
  • <div>
  • <pre>

La propriété position

Pour positionner des balises, une technique consiste à utilise la propriété CSS position avec les valeurs relative ou absolute.

Si nous voulons positionner l'image en haut à droite, à côté du titre, on peut utiliser la technique suivante :

position:relative

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<style>
			img {
				position:relative;
				top:-85px;
				left:200px;
			}
		</style>
	</head>
	<body>
		<h1>Mon blog</h1>
		<p>Un texte vraiment intéressant.</p>
		<img src="perroquet.jpg" alt="perroquet">
		<a href="#">Un lien</a>
		<a href="#">Un autre lien</a>
	</body> 
</html>

Ce qui donne :

position2

L'image est positionnée relativement à sa position initiale. Sans CSS, dans le flux normal, le perroquet était situé dans la page à 114 pixels du haut de la fenêtre et à 8 pixels de la gauche de la fenêtre (marge de <body>). Pour remonter l'image depuis sa position d'origine, nous utilisons position:relative, puis left:200px, ce qui décale l'image de 200 pixels vers la droite, puis top:-85px, ce qui remonte l'image au même niveau que le titre. Il faut parfois tâtonner pour arriver à ce résultat. On remarque que les liens restent décalés par rapport à la position d'origine de l'image ce qui n'est pas très élégant.

position:absolute

On peut positionner ce perroquet de la même manière avec position:absolute. Il faut savoir que la valeur absolute va positionner l'image par rapport au premier conteneur en position:relative qui est par défaut <html> et donc représenté par le bord de la fenêtre du navigateur.

img {
	position:absolute;
	top:30px;
	left:208px;
}

position3

La propriété top:30px correspond à la marge de 8px ajoutée à l'espacement vertical du titre. La propriété left s'est vu augmentée de 8px également à cause de la marge gauche de <body>

Notez que les liens ont repris leur place, car l'image est positionnée relativement par rapport à la balise <html>, premier conteneur en position relative.

La propriété float

Une autre technique de positionnement est l'usage de la propriété CSS float qui va permettre d'aligner à gauche ou à droite une balise en partant du haut, et si il y a la place (largeur) pour loger l'élément. C'est un peu comme un remplissage de la fenêtre par le haut et en partant de la gauche ou de la droite selon la valeur choisie left ou right.

Positionnons maintenant notre perroquet avec la technique float:right :

img {
	float:right;
}

Ce qui donne :

position4

C'est pas mal, mais le perroquet se cale sur la droite de la fenêtre du navigateur et il est positionné sous le texte, sa position d'origine. Le conteneur de l'image étant <body>, elle devrait se positionner en haut à droite de body et non pas sous le texte, mais contrairement aux apparences, il n'y a pas la place.

Écrivons ceci dans la feuille de style interne :

img {
	float:right;
}
			
h1, p {
	background-color:#AAA;
}

Ce qui donne à l'écran :

position5

On voit ici très clairement que l'image ne peut pas se positionner en haut à droite de son conteneur <body> car elle n'a pas la place, étant donné que les balises de type boite <h1> et <p> occupent toute la largeur de leur conteneur <body>.

Pour positionner le perroquet à la même hauteur que le titre, plusieurs solutions :

  • utiliser la propriété position:relative ou absolute avec la propriété top pour remonter l'image
  • utiliser une marge haute négative (bidouillage)
  • réduire la largeur du titre et du texte

Optons pour cette dernière solution :

img {
	float:right;
}	

h1, p {
	background-color:#AAA;
	width:200px;
}

Ce qui affiche :

position5bis

La place est faite, mais ça ne fonctionne toujours pas. C'est parce que les éléments à gauche doivent flotter aussi. Rectifions :

img {
	float:right;
}

h1, p {
	background-color:#AAA;
	float:left;
}

Ce qui donne :

position6

A présent tout flotte, mais c'est désorganisé.

Je vais utiliser un conteneur <div> pour contenir le bloc de gauche. Et ce <div> flottera à gauche. Je vais donc modifier le code HTML et CSS :

<html>
	<head>
		<meta charset="utf-8">
		<style>
			div {
				float:left;
				border:solid;
			}
			
			h1, p {
				background-color:#AAA;
			}
			
			img {
				float:right;
			}
		</style>
	</head>
	<body>
		<div>
			<h1>Mon blog</h1>
			<p>Un texte vraiment intéressant.</p>
			<a href="#">Un lien</a>
			<a href="#">Un autre lien</a>
		</div>
		<img src="perroquet.jpg" alt="perroquet">
	</body> 
</html>

La bordure du <div>, ainsi que le fond gris pour les titres et textes sont ajoutés à des fins pédagogiques. Il ne sont évidemment pas nécessaires pour le fonctionnement du code.

position7

Le résultat est presque correct, mais il faudrait que l'image soit un peu plus à gauche pour ressembler à notre premier positionnement avec position:relative. Ceci sera résolu en mettant float:left sur l'image au lieu de float:right. Ainsi, l'image s'empilera à gauche du conteneur <div>. Il faudra également une marge haute pour caler l'image par rapport au titre.

Voici le résultat final :

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<style>
			div {
				float:left;
				width:200px;
			}
			
			img {
				margin-top:30px;
				float:left;
			}
		</style>
	</head>
	<body>
		<div>
			<h1>Mon blog</h1>
			<p>Un texte vraiment intéressant.</p>
			<a href="#">Un lien</a>
			<a href="#">Un autre lien</a>
		</div>
		<img src="perroquet.jpg" alt="perroquet">
	</body> 
</html>

Ce qui donne  :

position8

Tout ça pour ça. Oui je sais. Ainsi va la vie du webmaster...

La propriété display:inline-block

La propriété float étant parfois compliquée à manier, il faudrait pouvoir utiliser un affichage en ligne, tout en conservant les propriétés avantageuses des boites. cette propriété CSS existe : display:inline-block.

En réutilisant le code ci-dessus, voici une alternative à float.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<style>
			div {
				width:200px;
				display:inline-block;
				border:solid;
			}
			
			img {
				margin-top:30px;
			}
		</style>
	</head>
	<body>
		<div>
			<h1>Mon blog</h1>
			<p>Un texte vraiment intéressant.</p>
			<a href="#">Un lien</a>
			<a href="#">Un autre lien</a>
		</div>
		<img src="perroquet.jpg" alt="perroquet">
	</body> 
</html>

Ce qui affiche avec la bordure "pédagogique" :

position9

Pour positionner la boite <div> en haut, nous allons utiliser la propriété vertical-align qui fonctionne très bien avec display:inline-block :

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<style>
			div {
				width:200px;
				display:inline-block;
				vertical-align:top;
			}
			
			img {
				margin-top:30px;
			}
		</style>
	</head>
	<body>
		<div>
			<h1>Mon blog</h1>
			<p>Un texte vraiment intéressant.</p>
			<a href="#">Un lien</a>
			<a href="#">Un autre lien</a>
		</div>
		<img src="perroquet.jpg" alt="perroquet">
	</body> 
</html>

Ce qui donne :

position10

Cette dernière solution est efficace et élégante, mais encore trop méconnue des développeurs qui lui préfèrent la technique float.

Articles connexes