Création d’une mise en page fluide à l’aide des marges négatives
Par Ryan Brill
Récemment, j'ai dû créer une maquette fluide de deux colonnes comprenant un en-tête, un pied de page, et un contenu devant être placé avant la barre latérale dans le code source. Pour ce faire, j'ai saisi l'opportunité de démontrer un aspect sous-utilisé des CSS : les marges négatives. Les marges négatives permettent d'écarter la zone de contenu des bords du navigateur, laissant ainsi une place pour la barre latérale.
Démarrons simplement
Afin de montrer de quelle façon les marges négatives peuvent être utiles dans la création de mises en page fluides, commençons par la création d'une mise en page fluide de deux colonnes comprenant un en-tête et un pied de page. La zone de contenu principale sera sur la gauche et la barre latérale sur la droite. Cela devrait normalement être très simple à mettre en oeuvre, mais nous allons corser un peu les choses car nous souhaitons que notre code source soit structuré d'une certaine manière.
Connaissant le mode de fonctionnement des blocs flottants, il serait plus aisé de placer la barre latérale avant la zone de contenu dans le code source, ce qui lui permettrait de flotter à droite du contenu. Cependant, puisqu'il est préférable d'avoir le contenu de la page avant la barre latérale dans les navigateurs en mode texte, les lecteurs d'écrans et autres navigateurs ancestraux qui n'interprèteront pas nos styles, nous allons proposer une solution permettant au contenu d'être placé en premier dans le code source et fonctionnant dans une grande majorité de navigateurs.
Le code source que nous voulons
Voyons à quoi ressemble notre code source :
<div id="en-tete">En-tête</div>
<div id="conteneur">
<h1>Contenu</h1>
<p>Lorem ipsum dolor sit amet,
consectetuer adipiscing elit.
Phasellus varius eleifend.</p>
<p class="dernier">Donec euismod.
Praesent mauris mi, adipiscing non,
mollis eget, adipiscing ac, erat.
Integer nonummy mauris sit.</p>
</div>
<div id="barre-laterale">
<h1>Barre latérale</h1>
<ul>
<li>Lien N°1</li>
<li>Lien N°2</li>
</ul>
</div>
<div id="pied-de-page">Pied de page</div>
L'exemple 1 montre comment nous souhaitons que le code non stylé soit affiché. Les navigateurs qui n'interprètent pas correctement les CSS afficheront le même résultat, voila pourquoi il est important de placer le contenu avant la barre latérale.
Nous savons que nous avons besoin d'une zone de contenu prenant toute la largeur disponible, moins la largeur requise par la barre latérale de droite. Aussi, pourquoi ne pourrions nous pas spécifier une largeur de 100% - 200px ? Eh bien nous pouvons le faire en utilisant les marges négatives !
Le style dont nous aurons besoin
Voyons comment utiliser les CSS pour arriver à nos fins. Comme promis, nous allons mettre la largeur de notre <div> « conteneur » à 100%, lui ajouter la propriété float:left
, et lui donner une marge négative à droite de -200px. Il est très important que cet élément soit un flottant, car les marges, et donc les marges négatives, sont gérées différemment pour les éléments flottants et ceux en ligne que pour les éléments non-flottants et ceux de type bloc.
La marge négative de droite permet plus à la barre latérale de flotter en haut de l'espace laissé par cet élément qu'elle ne permet d'agir sur le positionnement ou l'apparence de l'élément lui-même, comme on peut le voir plus bas, dans l'exemple 2. Nous avons positionné notre barre latérale de manière flottante à droite et mis sa largeur à 200px. Puis nous allons ajouter à notre <div> « pied-de-page » la règle clear:both
pour s'assurer qu'elle se place toujours sous le reste de notre contenu, quelle que soit la longueur de ce dernier. Nous allons également donner à notre en-tête et à notre pied de page des couleurs de fond pour les distinguer du reste de la page.
#en-tete {
background: #d7dabd;
}
#conteneur {
width: 100%;
float: left;
margin-right: -200px;
}
#barre-laterale {
width: 200px;
float: right;
}
#pied-de-page {
background: #d7dabd;
clear: both;
}
Cette feuille de style nous donnera les résultats montrés par l'exemple 2. Comme vous pouvez le voir, nous avons maintenant besoin d'écarter la zone de contenu du côté droit du document. Pour ce faire, nous avons choisi d'utiliser une autre <div> car cette méthode sera mieux supportée par l'ensemble des navigateurs que certaines autres méthodes alternatives. Nous allons donc modifier notre XHTML pour qu'il ressemble à ceci :
<div id="conteneur">
<div id="contenu">
<h1>contenu</h1>
<p>Lorem ipsum dolor sit amet,
consectetuer adipiscing elit.
Phasellus varius eleifend.</p>
<p class="dernier">Donec euismod.
Praesent mauris mi, adipiscing non,
mollis eget, adipiscing ac, erat.
Integer nonummy mauris sit.</p>
</div>
</div>
Maintenant nous allons ajouter une couleur de fond et une marge à droite au <div> « contenu », ce qui devrait le séparer de la barre latérale et le placer juste où nous en avons besoin.
#contenu {
background: #f1f2ea;
margin-right: 200px;
}
Evitons les problèmes
Avant de passer aux exemples visuels attardons-nous un peu sur un autre problème. Nous avons besoin de placer le premier et le dernier élément dans notre <div> « contenu » de façon à ne pas avoir de marge supérieure, ni de marge inférieure. Dans notre cas, nous allons simplement mettre la règle margin-top de l'élément <h1> à 0, et ajouter un attribut class au dernier paragraphe de notre <div> « contenu », ce qui permettra de fixer sa marge inférieure à 0. Maintenant que nous avons fait cela, l'exemple 3 est prêt à être vu.
C'est mieux, mais bien sûr vous aurez remarqué que la barre latérale de droite ne se prolonge pas vers le bas. Grâce à la petite astuce des images de fond, exposée par les « Colonnes factices » de Dan Cederholm, nous pouvons facilement résoudre ce problème.
Premièrement, nous allons créer l'image ci-dessous. C'est une image de 200 pixels de large car sa largeur doit correspondre à la largeur de notre barre latérale.
Pour mettre en oeuvre l'astuce de Dan, nous devons ajouter une <div> qui englobe les <div> « conteneur » et « barre-laterale », ainsi qu'une autre <div> avec une propriété clear:both
que l'on placera juste sous la <div> « barre-laterale ». Notre XHTML ressemblera alors à ceci :
<div id="enveloppe">
<div id="conteneur">
<div id="contenu">
<h1>contenu</h1>
<p>Lorem ipsum dolor sit amet,
consectetuer adipiscing elit.
Phasellus varius eleifend.</p>
<p class="dernier">Donec euismod.
Praesent mauris mi, adipiscing non,
mollis eget, adipiscing ac, erat.
Integer nonummy mauris sit.</p>
</div>
</div>
<div id="barre-laterale">
<h1>Barre latérale</h1>
<ul>
<li>Lien N°1</li>
<li>Lien N°2</li>
</ul>
</div>
<div class="deblayage"> </div>
</div>
Une fois ceci fait, nous pouvons ajouter le fond à la <div> « enveloppe », en spécifier l'effet de répétition : repeat-y;
puis le positionner à droite. Pour éviter un bug d'Internet Explorer, nous devons également ajouter le même fond à notre <div> « conteneur ».
#enveloppe {
background:
#f1f2ea url(background.gif) repeat-y right;
}
#conteneur {
width: 100%;
background:
#f1f2ea url(background.gif) repeat-y right;
float: left;
margin-right: -200px;
}
Nous devrions aussi définir les styles pour notre <div> de « deblayage » afin de s'assurer que le pied de page tombera bien sous les deux colonnes et que ces dernières seront correctement affichées.
.deblayage {
height: 0;
clear: both;
}
Cela nous donnera une très belle mise en page fluide de deux colonnes qui se dégrade très bien en l'absence de CSS. Jetez un oeil à l'exemple 4. En ajoutant simplement quelques bordures et un peu de remplissage (padding) aux éléments, cela peut vous donner un très bon point de départ pour ce type de mise en page. Bien sûr, si nous avions voulu que la barre latérale soit du côté gauche, nous aurions simplement inversé les valeurs des propriétés float
et margin
. Il aurait donc fallu remplacer float:left
par float:right
et au lieu de spécifier margin-right:200px
nous aurions dû spécifier margin-left:200px
, et ainsi de suite.
Plus astucieux : la version trois colonnes
Pourquoi ne pas utiliser cette technique pour aller encore plus loin et essayer une mise en page trois colonnes avec un contenu fluide ? Non seulement nous pouvons le faire, mais en plus c'est très facile. Pour cela, nous allons modifier légèrement notre XHTML en ajoutant quelques <div> supplémentaires, et peaufiner un peu notre feuille de style.
<div id="enveloppe-exterieure">
<div id="enveloppe">
<div id="conteneur">
<div id="contenu">
<div id="gauche">
<h1>Barre de navigation</h1>
<ul>
<li>Lien N°1</li>
<li>Lien N°2</li>
</ul>
</div>
<div id="principal">
<h1>Contenu</h1>
<p>Lorem ipsum dolor sit amet,
consectetuer adipiscing elit.
Phasellus varius eleifend.</p>
<p class="dernier">Donec euismod.
Praesent mauris mi, adipiscing non,
mollis eget, adipiscing ac, erat.
Integer nonummy mauris sit.</p>
</div>
</div>
</div>
<div id="barre-laterale">
<h1>Barre latérale</h1>
<p>Voici votre barre latérale.
Ajoutez le contenu que vous souhaitez.</p>
</div>
<div class="deblayage"> </div>
</div>
</div>
Ré-implémentation des colonnes factices
Encore une fois, puisque nous souhaitons que toutes nos colonnes aient une hauteur identique, nous allons mettre en place d'autres colonnes factices. Nous avons donc créé les deux images suivantes :
Comme vous pouvez le voir dans le code XHTML ci-dessus, nous avons ajouté une <div> « enveloppe-exterieure » en plus de la <div> « gauche » destinée à la barre latérale de gauche, puis une autre <div> englobant le contenu du milieu. Notre nouvelle <div> « enveloppe-exterieure » contient l'image de fond de notre nouvelle colonne. Cette image de fond est positionnée à gauche et répétée vers le bas de la <div>. Nous avons aussi retiré le fond de la <div> « contenu » et nous allons ajouter la couleur de fond désirée à notre <div> « enveloppe-exterieure ».
#enveloppe-exterieure {
background: #fff url(background_3.gif) repeat-y left;
}
#enveloppe {
background: url(background_2.gif) repeat-y right;
}
Le fond blanc apparaîtra là où aucune image ne sera affichée, coloriant ainsi la colonne du milieu. Nous allons également ajouter des fonds à nos éléments intérieurs afin d'éviter les espaces désagréables qui apparaissent dans la plupart des versions d'Internet Explorer.
#conteneur {
width: 100%;
float: left;
margin-right: -200px;
background: url(background_2.gif) repeat-y right;
}
#contenu {
margin-right: 200px;
background: url(background_3.gif) repeat-y left;
}
Puis nous allons ajouter ces simples styles et utiliser encore les marges afin de positionner nos colonnes gauche et centrale où nous en avons besoin.
#principal {
margin-left: 150px;
}
#gauche {
width: 150px;
float: left;
}
Pour finir, nous allons ajouter les propriétés suivantes à nos <div> « en-tete » et « pied-de-page » afin de finaliser l'aspect de notre mise en page :
border: 1px solid #cecea5;
Jetez un oeil à l'exemple 5 et ne vous gênez pas pour en afficher le code source afin de le voir en entier.
Bien sûr, l'utilisation de la règle @import sur vos sites serait une bonne idée pour leur assurer un affichage convenable dans les anciens navigateurs.
En conclusion
Comme vous vous en êtes aperçu, les marges négatives sont un aspect sous-utilisé des CSS. Pourtant, cette technique permet une autre approche de la mise en page pour ceux qui veulent contrôler l'ordre des éléments dans le code source, sans avoir à rajouter un div conteneur non sémantique pour le faire.
Cet article est traduit avec la permission de A List Apart Magazine et de l'auteur.
http://alistapart.com/articles/negativemargins/