5 Reset CSS à la loupe pour une remise à zéro des valeurs par défaut des navigateurs

Vous n’utilisez pas de styles CSS pour votre page web ? Ce n’est pas grave : les navigateurs le font pour vous. Ils utilisent chacun leur feuille de style par défaut pour obtenir un rendu visuel minimal. C’est pourquoi les tableaux possèdent des bordures, et les paragraphes des espaces avant et après. Le problème ? Si des balises comme strong ou em sont traitées de la même manière par les agents utilisateurs, l’immense majorité présente des différences plus ou moins importantes. Ce fameux manque de « consistance » décrié par les webdesigners anglo-saxons concerne principalement les propriétés margin et padding. Avec une pensée particulière pour le retrait des listes ol et ul : si IE applique bien le margin-left: 40px préconisé, Firefox utilise quant à lui un padding-left: 40px pour le même rendu. Dans ces conditions, il est tentant de vouloir mettre tous ces agents utilisateurs au garde-à-vous…

Dans leur grande sagesse les concepteurs du HTML ont fourni un exemple de feuille de style pour uniformiser le rendu visuel des pages web ; dans leur précipitation à sortir leur produit avant la concurrence, les concepteurs des navigateurs ont fait ce qu’ils ont voulu. Enfin, il est aussi possible que les spécifications – parfois sibyllines – du monde joyeux des recommandations puissent être interprétées de diverses manières…

Prudence est mère de sûreté…

Il ne faut pas confondre ces différences de rendu entre les navigateurs avec les nombreux bugs qui affectent particulièrement IE comme le calcul de la largeur d’une boite. Gardez également à l’esprit que l’on peut très bien travailler avec ces valeurs par défaut au lieu de les éliminer, et que faire reset, ce n’est pas toujours rigolo : il s’agit d’une technique à manier avec précaution.

D’autant plus que la majorité des problèmes rencontrés est souvent liée à la transmission de l’héritage entre parents et enfants. Faire table rase, d’accord, encore faut-il savoir de quoi ^__^ Une autre notion indispensable : avoir une idée des possibilités d’imbrication des balises.

Voici un récapitulatif de qui contient quoi, ainsi qu’une référence complète sur les attributs et relations de parenté des éléments XHTML 1.1.

La Cascade (le C de CSS) est une autre source de confusion. Openweb a consacré un article intéressant qui explique comment sont « priorisés » les différents styles qui peuvent s’appliquer à un élément.

Pour faire simple : si vous débutez l’apprentissage des CSS, je vous déconseille fortement de mettre un reset dans votre moteur, même s’il semble ronronner affectueusement au début. Nul doute que dès que vous aurez le dos tourné… Enfin maintenant si vous insistez, je vous ai préparé un mini dossier sur le sujet :

Remise à zéro du margin et du padding avec le sélecteur universel *

Cette méthode a le mérite de la concision et de la simplicité :

* {
  margin: 0;
  padding: 0;
}

Ici, le sélecteur universel met toutes les balises html d’accord sur les marges et les retraits : il n’y en aura pas ! La propriété margin correspond à l’espace laissé ou pas entre deux éléments. La propriété padding concerne l’espace à l’intérieur d’un élément entre la bordure et les éléments qu’il contient. Pour s’éclaircir les idées, je vous propose de jeter un œil sur la représentation visuelle du modèle de boite (box model).

Et border: 0 ?

Oui, il est possible d’ajouter border: 0 pour s’assurer que les éléments n’auront pas de bordures indésirables. Comme cette dernière déclaration est de plus en plus utilisée, voici la liste des éléments qu’elle concerne afin que vous jugiez de sa pertinence :

  • input
  • textarea
  • select
  • button
  • table
  • fieldset
  • abbr
  • hr
  • img et object (si lien)
  • iframe

Redonner des couleurs à vos balises

Reste à redonner à ces balises un rendu plus agréable en regroupant, par exemple, les éléments qui partagent les mêmes valeurs tout au long du site web :

  • Différents niveaux de titre h1h6,
  • Conteneurs de texte comme p, blockquote, pre, code, address, hr, form,
  • Listes avec dl, ul, ol,
  • Eléments en ligne tels que strong, cite, em, var, samp,
  • Etc.

Selon le document, il pourrait être tout aussi judicieux de regrouper les éléments suivants :

  • Balises ul et ol dans la sidebar
  • Balises identiques dans la zone de contenu principal
  • etc.

Une autre méthode inspirée par le billet paru sur pixenjoy est de reprendre la feuille de style proposée par le W3C qui peut avantageusement servir de modèle pour avoir la liste des éléments HTML concernés par cette remise à zéro des marges et retraits.

Une technique obsolète ?

Malgré son apparente simplicité et efficacité, cette méthode n’est pas la panacée : un navigateur comme Firefox consomme de précieuses ressources à boucler sur toutes les balises. Par ailleurs, un travail important reste à faire pour restyler les balises (même si ce travail n’est pas à refaire complètement à chaque nouveau projet). Quoiqu’il en soit, je vous propose de mettre cette technique de côté pour tester d’autres méthodes.

Reset CSS Reloaded d’Eric Meyer

Vous aurez peut-être remarqué que si l’ajout de border: 0 peut apporter un plus dans la remise à zéro des éléments, d’autres propriétés pourraient elles aussi gagner à être réinitialisées. C’est sûrement ce que c’est dit Eric Meyer lorsqu’il s’est penché sur son Reset CSS. (

L’exemple suivant est la version 2.0 du 26/01/2011, cf. http://meyerweb.com/eric/tools/css/reset :

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

L’idée est à la fois d’aller plus loin dans les propriétés à inclure tout en étant plus sélectif en tenant compte de certaines spécificités.

Reset again

Dans un premier temps, pas de surprise, nous retrouvons la remise des margin, padding et border à zéro, suivie de près par un outline: 0 qui sert généralemement à afficher un cadre pointillé lorsqu’on maintient le bouton de la souris appuyé sur un lien (:active, quoi 😉 ). Ne pas confondre avec le même cadre qui apparait quand le lien a le focus, via la touche TAB, même s’il s’agit de la même déclaration outline: 1px dotted invert. La pseudo-classe :focus est également remise à zéro pour l’ensemble des éléments via :focus { outline: 0 }.

Héritez, qu’y disait…

Viennent ensuite les propriétés relatives à font : on s’assure qu’elles seront bien héritées par les éléments parfois récalcitrants (certains éléments de formulaire). La taille 100% sert à la fois à obtenir une valeur « héritable » par les balises filles et avoir une taille par défaut pour l’ensemble de la page web. Si vous préférez partir avec un corps inférieur, rien ne vous empêche de spécifier 62.5% pour avoir une taille par défaut de 10px env. ou 75% pour obtenir 12px. Sachant que si vous pouvez vous débrouiller pour fournir une taille de texte généreuse à vos lecteurs, ils vous le rendront bien.

Je ne veux voir qu’une tête !

Nous terminons cette première partie avec vertical-align: baseline qui permet d’harmoniser l’alignement des éléments en ligne au sein d’une boite. Il s’agit de la valeur par défaut pour aligner la ligne de base du texte avec le bas d’une image placée à côté.

Avez-vous la quote ?

Les dernières règles s’appliquent aux éléments blockquote et q dont on supprime préventivement le contenu « éventuellement » généré avant ou après, puis dans un second temps, on supprime les guillemets ouvrants et fermants. Tout ce que vous avez toujours voulu savoir sur ces éléments se trouve sur la page web de yoyodesign consacrée au contenu généré, au numérotage automatique et aux listes.

Y a pas un problème avec la valeur de line-height ?

La curiosité de cette feuille de style, est la présence d’une valeur sans unité de mesure (line-height: 1) qui mérite quelques explications. Pour ceux qui ne sont pas à l’aise avec l’anglais, j’ai repris les exemples donnés sur la page citée précédemment qui parlent d’eux-mêmes :

En utilisant line-height: 1em

La règle CSS suivante…

ul {
  font-size: 15px;
  line-height: 1em;
}
li {
  font-size: 10px;
}
small {
  font-size: 80%;
}

… est équivalente à…

ul {
  font-size: 15px;
  line-height: 1em;
}
li {
  font-size: 10px;
  line-height: 15px;
}
small {
  font-size: 80%;
  line-height: 15px;
}

… appliquée sur l’exemple html suivant :

<ul>
  <li>I'm a list item with <small>small text</small>.</li>
</ul>

En utilisant line-height: 1

Appliquée sur l’exemple html précédent, la règle CSS suivante…

ul {
  font-size: 15px;
  line-height: 1;
}
li {
  font-size: 10px;
}
small {
  font-size: 80%;
}

… est équivalente à :

ul {
  font-size: 15px;
  line-height: 1;
}
li {
  font-size: 10px;
  line-height: 10px;
}
small {
  font-size: 80%;
  line-height: 8px;
}

Grosso modo : lorsque l’on ne précise pas l’unité de mesure après line-height (ce qui est parfaitement conforme aux spécifications, même si les validateurs ne le savent pas toujours) la valeur fonctionne comme un facteur multiplicateur, contrairement à l’unité em qui produit une valeur calculée qui se répercute ensuite sur les balises enfants par le jeu de la cascade.

C’est une spécificité de la propriété line-height qui est la seule à accepter une valeur brute. Car, vous l’avez sans doute remarqué, mais spécifier 2em sur une taille de police a bien un effet multiplicateur par rapport à la valeur dont elle hérite au départ :

body {
  font-size: 12px;
}
h1 {
  font-size: 2em;
}

Dans cette exemple, l’élément h1 a bien une taille de 24px.

En finir avec le reset-reloaded ?

Le défaut essentiel de ce reset est aussi sa principale qualité : il déshabille carrément les balises de leurs attributs les plus usuels, jusqu’à ceux dont on n’avait pas vraiment conscience (:focus, :before, :after, quotes, etc.). Ceci permet de prendre conscience que le fonctionnement « naturel » de nos chères balises html ne l’est pas tant que ça…

Par ailleurs, à force de lire un peu partout qu’il ne faut pas mélanger la sémantique des balises html avec leur rendu visuel, je me dis que le full monty proposé par Eric Meyer va dans le bon sens en nous obligeant à en apprendre un peu plus sur le HTML et les CSS (trollinou inside) ^_^v.

Eric Meyer considère toute utilisation des styles par défaut comme une béquille qui nous rend dépendant du bon vouloir des navigateurs (ce qui n’est pas totalement faux). Toutefois, comme le précise, Laurent Denis, a-t’on vraiment besoin de vouloir garder la maitrise des éléments à ce point-là ou lieu de lâcher prise ? Pour finir de vous détendre, méditez cette phrase extraite de l’excellent article le tao du design web :

accepte le flot et le cours des choses,
les entoure, mais ne les possède pas,

En attendant d’arriver à ce degré de sagesse dont il faudrait que nos bien-aimés clients et patrons soient aussi imprégnés, revenons vers le côté obscur de la force avec un autre reset à nous mettre sous le clavier 😉

INITIAL de Christian Montoya

Cette remise à zéro est proposée par Faruk Ates, amendée par Robert Nyman et Christian Montoya. Plus qu’un reset radical, il s’agit plutôt d’un feuille de style minimale située entre la remise des marges à zéro et le reset-reloaded. Mais jugez plutôt :

// =INITIAL   v2.1,
// by Faruk Ates - www.kurafire.net
// Addendum by Robert Nyman - www.robertnyman.com
// Addition by Christian Montoya - www.christianmontoya.net

// Neutralize styling:   Elements we want to clean out entirely:
html, body, form, fieldset {
   margin: 0;
   padding: 0;
   font: 100%/120% Verdana, Arial, Helvetica, sans-serif;
 }

// Neutralize styling:   Elements with a vertical margin:
h1, h2, h3, h4, h5, h6, p, pre, blockquote, ul, ol, dl, address {
   margin: 1em 0;
   padding: 0;
 }

// Apply left margin:   Only to the few elements that need it:
li, dd, blockquote {
   margin-left: 1em;
 }

// Miscellaneous conveniences:
form label {
   cursor: pointer;
}
fieldset {
   border: none;
}
input, select, textarea {
   font-size: 100%;
   font-family: inherit;
}

Ici, le reset est plus sélectif : dans un premier temps, seuls certains éléments de type blocs sont touchés par la remise à zéro des marges et retraits. Ensuite, les éléments sont regroupés en fonction des marges qu’ils ont en commun : d’une part, ceux qui partagent les mêmes espaces avant et après, et d’autre part, ceux qui sont généralement représentés avec un retrait à gauche. Ces derniers héritent des valeurs margin: 1em 0 et padding: 0 spécifiées juste avant.

Un autre avantage d’INITIAL sur le Reset-Reloaded, est que les éléments en ligne ne sont pas affectés, ce qui est une bonne chose, vu le peu de différences de rendu qu’ils présentent d’un navigateur à l’autre.

Personnellement, je trouve cette approche plus élégante que le reset reloaded : plus « lisible » donc plus maniable, notamment en ce qui concerne son « extensibilité » car on peut même lui ajouter certaines trouvailles d’Eric Meyer comme :

  • spécifier une valeur brute pour line-height : 1.4 à la place de la valeur « INITIAL » de 120%,
  • prendre en compte les éléments table, tr ,td ou caption,
  • enlever les puces des listes,
  • etc…

… afin de construire une feuille de style de base reprenant par exemple le reset de Faruk, puis en ajoutant certains éléments prélevés dans le Reset-Reloaded (Ex. 1) ou encore d’autres règles CSS récurrentes (Ex. 2). L’idée est d’obtenir une sorte de tableau de bord CSS où la modification de certaines valeurs-clés permet de gérer des maquettes différentes. Je précise qu’il s’agit juste d’un exemple pour insister sur le fait que c’est au reset de s’adapter à vos besoins, et non le contraire 😉

Ex. 1
ol, ul {
  list-style: none;
}

// tables still need 'cellspacing="0"' in the markup
// j'ai modifié les valeurs, car il est bon que les tableaux soient visibles !
table {
  border-collapse: collapse;
  border-spacing: 1px;
}
caption, th, td {
  text-align: left;
  font-weight: normal;
}
Ex. 2
// Couleurs à adapter selon votre charte
a {text-decoration: none;}
a:link {color: #000;}
a:visited {color: #000;}
a:hover {color: #000;}
a:active {color: #000;}
img, iframe, object {border: 0 none;}
input, textarea, select, button, {border: 1px solid #000;
}

Dans les styles de cet Ex. 2, j’ai spécifié des valeurs pour les différents états des liens conformément à l’ordre LoVe(F)HAte, et redéfini en deux fois les bordures pour les éléments qui en possèdent par défaut. Par ailleurs, je rajouterais bien la balise div à la suite de l’élément body car – même si cet élément n’est pas censé avoir de marge -, force est de constater que lorsque deux images doivent se raccorder, il reste souvent un décalage d’un pixel qui disparait comme par magie avec margin: 0.

YUI Reset CSS de Yahoo! UI Library

Parmi les Reset CSS existants, on trouve la contribution de Yahoo! qui propose dans son pack Yahoo! UI Library une technique pour réinitialiser les éléments html qui manquent de « consistance » d’un navigateur à l’autre.

body, div, dl, dt, dd, ul, ol, li, h1,
h2, h3, h4, h5, h6, pre,
form, fieldset, input, textarea,
p, blockquote, th, td {
  margin: 0;
  padding: 0;
 }
table {
  border-collapse: collapse;
  border-spacing: 0;
 }
fieldset, img {
  border: 0;
 }
address, caption, cite, code, dfn, em, strong, th, var {
  font-style: normal;
  font-weight: normal;
 }
ol, ul {
  list-style: none;
 }
caption, th {
  text-align: left;
 }
h1, h2, h3, h4, h5, h6 {
  font-size: 100%;
  font-weight: normal;
}
q:before,
q:after {
  content: '';
}
abbr, acronym {
  border: 0;
}

Les choix en matière de remise à zéro sont discutables (il faut redéfinir jusqu’à la mise en gras pour strong et définir les tailles des polices pour les éléments hn), mais ce reset est accompagné d’une proposition de mise en forme pour les autres éléments html dont on peut s’inspirer en fonction du reset choisi (pour des raisons de lisibilité j’ai revu la mise en forme de départ et supprimé la plupart des commentaires) :

base.css

// base.css, part of YUI's CSS Foundation

h1 {font-size: 138.5%; /* 18px via YUI Fonts CSS foundation */}
h2 {font-size: 123.1%; /* 16px via YUI Fonts CSS foundation */}
h3 {font-size: 108%; /* 14px via YUI Fonts CSS foundation */}
h1, h2, h3 {margin: 1em 0;}
h1, h2, h3, h4, h5, h6, strong {font-weight: bold;}
abbr, acronym {
  border-bottom: 1px dotted #000;
  cursor: help;
}
em {font-style: italic;}
blockquote, ul, ol, dl {margin: 1em;}
ol, ul, dl {margin-left: 2em;}
ol li {list-style: decimal outside;}
ul li {list-style: disc outside;}
dl dd {margin-left: 1em;}
th, td {
  border: 1px solid #000;
  padding: 0.5em;
}
th {
  font-weight: bold;
  text-align: center;
}
caption {
  margin-bottom: 0.5em;
  text-align: center;
}
p, fieldset, table {margin-bottom: 1em;
}

Le site de Yahoo! pour les développeurs web propose des informations complémentaires sur la gestion d’une grille de mise en page et des polices de caractère.

undohtml.css de Tantek Celik

Peut-être le plus ancien Reset CSS. Pour des raisons de lisibilité, j’ai revu l’organisation visuelle des commentaires.

// undohtml.css (CC) 2004 Tantek Celik.
// Some Rights Reserved. http://creativecommons.org/licenses/by/2.0
// This style sheet is licensed under a Creative Commons License.
// Purpose: undo some of the default styling of common (X)HTML browsers *//

// link underlines tend to make hypertext less readable,
// because underlines obscure the shapes of the lower halves of words
:link, :visited {text-decoration: none;}

// no list-markers by default, since lists are used more often for semantics
ul, ol {list-style: none;}

// avoid browser default inconsistent heading font-sizes and pre/code too
h1, h2, h3, h4, h5, h6, pre, code {font-size: 1em;}

// remove the inconsistent (among browsers)
// default ul,ol padding or margin the default spacing on headings
// does not match nor align with normal interline spacing at all,
// so let's get rid of it. zero out the spacing around pre, form, body, html, p, blockquote
// as well form elements are oddly inconsistent, and not quite CSS emulatable. nonetheless
// strip their margin and padding as well
ul, ol, li, h1, h2, h3, h4, h5, h6, pre,
form, body, html, p, blockquote, fieldset, input {
  margin: 0;
  padding: 0;
}

// whoever thought blue linked image borders were a good idea?
a img, :link img, :visited img {border: none }

// de-italicize address
address {font-style: normal;}

// more varnish stripping as necessary...

C’est reparti pour un tour ?

Pour conclure

Ni liste exhaustive ni comparatif point par point, j’ai essayé de faire le tour des Reset CSS les plus utilisés en espérant avoir fourni quelques informations utiles sur les techniques existantes et leur fonctionnement. J’espère surtout que ce billet vous aura donné des éléments de réflexion pour vous en passer lorsque ce n’est pas nécessaire 😉 Ce billet pose certainement plus de questions qu’il n’apporte de réponses car un Reset ne dispense pas de réfléchir à l’organisation de ses CSS, bien au contraire !

Stay tuned and mind the gap!