Résoudre les problèmes de marges en CSS

Pascale Lambert

Les propriétés margin et padding ont bien été utilisées, et pourtant le rendu visuel est différent selon les navigateurs... ça part "en vrille", en particulier avec Internet Explorer. Pourquoi ?

Exposé des problèmes éventuels, précautions et solutions (non exhaustives...) pour avoir des marges similaires quelque soit le navigateur.

N'hésitez pas à nous faire part de votre avis sur cet article : Commentez

- Titre : Résoudre les problèmes de marges en CSS

- Auteur : Pascale Lambert

- Parution : 30 juin 2010

- Mise à jour : 24 novembre 2010

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 30/06/2010 Pascale Lambert. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Résoudre les problèmes de marges en CSS

- I-A. Le DocType

- I-B. Le Reset

- I-C. La fusion des marges

- I-D. Le "cas" Microsoft Internet Explorer (le HasLayout de MSIE)

I - Résoudre les problèmes de marges en CSS

Ce chapitre fait suite au tutoriel "Gérer les marges en CSS".

I-A - Le DocType

Sans DocType correctement déclaré, vous avez toutes les chances d'obtenir un mauvais rendu de vos pages (pas seulement des marges d'ailleurs...).

Pour une gestion correcte des marges, il faut donc impérativement avoir un DocType déclaré (si possible le même pour toutes les pages) et pas de prologue de XML (si vous ne codez pas en XHTML 1.1).

Sinon, vous irez à des déconvenues, en particulier le fameux passage en mode quirks qui rend fou les navigateurs !
Le modèle de boite, par exemple, ne fonctionnera plus... ou du moins fonctionnera de façon différente selon les navigateurs. Facheux non ?

Une page web conforme passe toujours par la déclaration d'un DocType. Donc si votre éditeur HTML n'en met par un par défaut, mieux vaut changer de logiciel tout de suite...

Pour mémoire, le DocType à déclarer pour coder en XHTML 1.0 Strict est :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

I-B - Le Reset

Par défaut, pratiquement tous les éléments possèdent des marges, même le body.

Si on déclare par exemple :

Code CSS

html {
border:1px solid blue;
}
body {
border:1px solid red;
}

On obtiendra un cadre rouge à l'intérieur d'un cadre bleu espacé de quelques pixels.

Pour mettre tout le monde d'accord et partir sur les meilleures bases possibles, on commence donc en général par faire un "reset" en début de feuille de style, ce qui permet de ne plus avoir d'espace entre les éléments html et body.

Pour cela, on affecte tout simplement 0 (sans unités) aux tailles de margin et padding.

html, body {
margin:0;
padding:0;
}

On peut même mettre tous les éléments à zéro avec le code suivant (c'est radical, voire même un peu brutal...) :

* {
margin:0;
padding:0;
}

A noter que des "reset" plus élaborés existent, le YUI(en) par exemple.

I-C - La fusion des marges

La gestion de margin paraît donc simple en théorie... En pratique, il y a quelques subtilités auxquelles il faut faire attention, comme celle de la fusion des marges.

En gros (mais que ça ne vous empêche pas d'aller lire l'article mentionné !), si on ne déclare ni padding, ni bordures (border), les marges hautes et basses (margin-top et margin-bottom) fusionnent mais ne s'ajoutent pas.

Code (X)HTML

<div>
<p>
Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Duis eget ligula quis libero mollis dapibus.
Suspendisse potenti. Nullam facilisis neque et sem.
Proin placerat adipiscing urna. Aenean sollicitudin.
</p>
<p>
Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Duis eget ligula quis libero mollis dapibus.
Suspendisse potenti. Nullam facilisis neque et sem.
Proin placerat adipiscing urna. Aenean sollicitudin.
</p>
</div>

Code CSS

div {
background:#C00000 url(images/quadrillage.png)
}
div p {
margin-top:5px;
margin-bottom:20px;
padding:10px;
background-color:#FFFAFA;
}

Non, non, vous n'avez pas la berlue : c'est comme si le margin-top de 5 pixels n'existait pas.

1. Entre les deux paragraphes (éléments frères) c'est la marge la plus importante qui l'emporte (soit le margin-bottom:20px, et non 20+5=25 pixels comme on pourrait s'y attendre) ;

2. Entre le div (l'élément parent) et les paragraphes (éléments enfants), aucune marge, ni haute, ni basse.

Rajoutons maintenant un tout petit padding-top et padding-bottom de 1 pixel dans le code CSS du div :

div {
padding:1px 0;
background:#C00000 url(images/quadrillage.png)
}

Cette fois les marges hautes (margin-top:5px) et basses (margin-bottom:20px) sont bien respectées entre les éléments parents et enfants. En revanche, rien à faire pour l'espace entre les deux éléments frères. Mais cette particularité est faite pour garder une homogénéité de présentation entre les différents éléments.

I-D - Le "cas" Microsoft Internet Explorer (le HasLayout de MSIE)

Heureusement, avec l'arrivée de MSIE8, ce problème n'est plus à l'ordre du jour. Mais MSIE6 et 7 ne sont pas encore complètements éteints, il faut donc bien en parler...

Vous trouverez sur le site d'Alsacréations un article très complet sur le fumeux HasLayout d'Internet Explorer. Donc là encore, je vous conseille très très vivement de le lire.

Ce phénomène se produit lorsque, par exemple, vous attribuez une taille (width ou height) à un bloc.

div {
background:#C00000 url(images/quadrillage.png);
padding:1px 0;
}
p {
background-color:#FFFAFA;
margin-top:5px;
margin-bottom:20px;
padding:10px;
width:200px;
}

On est bien d'accord ? Si vous avez bien compris ce qui a été dit ci-dessus, on devrait voir une marge de 5 pixels au dessus du paragraphe (margin-top:5px), et 20 pixels au dessous (margin-bottom:20px).

Et bien avec IE6 et IE7, que neni, c'est inopérant ! Les marges prisent en compte sont celles de l'élément parent, donc le padding de 1 pixel ! (prise de tête, hein ?)

Deux solutions éventuelles pour palier à ce problème :

1. Mettre un zoom:1 à l'élément parent ;

2. Ou faire une feuille de style spécifique MSIE que vous déclarerez dans un commentaire conditionnel, et que vous bidouillerez afin d'avoir le rendu souhaité.

div {
background-color:#808080;
padding:1px 0;
zoom:1;
}

Quoi qu'il en soit : bon courage ;-)