Un Reset CSS c'est quoi ? Pour quoi ?
Les navigateurs web sont tenus d'appliquer des styles par défaut (User Agent Stylesheet) à chaque page HTML, sinon le document afficherait une page blanche (source : specifications CSS).
Chaque navigateur applique ses propres styles par défaut pouvant se révéler différents les uns des autres, sinon ce serait trop facile pour nous autres développeuses et développeurs !
Deux méthodes permettent de contourner ces différences d'affichages entre les navigateurs : le Reset CSS et le Normalize CSS.
Reset ou Normalize ?
Un "Reset CSS" (réinitialisation) est une technique qui consiste à repasser toutes les valeurs des propriétés CSS à leur état initial afin repartir de zéro et d'une base vierge avant d'appliquer nos propres styles.
Un "Normalize CSS" (harmonisation) consiste à appliquer des styles de base cohérents identiques sur chaque navigateur. Cette méthode corrige également les différences d'interprétation des spécifications et d'affichage sur l'ensemble des navigateurs et produit une base de travail suffisante (typographie, interlignages, marges, etc.)
Cela dépend bien évidemment de vos besoins, mais dans la plupart des projets il est suffisant d'appliquer une couche de Normalisation, car un Reset vous forcera à redéfinir toutes les propriétés une à une pour votre projet.
L'article (en anglais) Normalize CSS or CSS Reset?! de Elad Shechter résume bien cette dualité d'outils.
L'article (en anglais aussi) A tale of CSS Resets and Everything You Need to Know About Them. Revisited. de Margo Roi est extrêmement riche en informations sur l'évolution des techniques de Reset / Normalize, leur intérêt dans le détail et propose une liste très complète de l'ensemble des solutions existantes actuellement (Eric Meyer, Yahoo!, Normalize, Sanitize, Reboot, Remedy, etc.)
Comprendre et provoquer l'héritage des propriétés
Une propriété héritable est une propriété qui récupère automatiquement la valeur de son parent. C'est le cas par exemple des propriétés typographiques ou des listes (ex. font-size
, color
, list-style
, etc.).
Une propriété non héritable adoptera par défaut la valeur initial
telle que définie dans les Spécifications. Par exemple une bordure, une largeur de boîte ou une couleur de fond n'est pas transmise par héritage aux descendants. La majorité des propriétés CSS ne sont pas héritables.
Voici une liste des propriétés CSS héritables courantes :
color
cursor
direction
font-family
font-size
font-style
font-variant
font-weight
font
letter-spacing
line-height
list-style-image
list-style-position
list-style-type
list-style
text-align
text-indent
text-transform
visibility
white-space
word-spacing
Il est possible de forcer l'héritage d'une propriété en lui appliquant la valeur inherit
. Elle prendra alors la valeur de la propriété du parent (c'est à dire son ancêtre direct).
Il est également possible de contrôler l'héritage de toutes les propriétés grâce à la propriété raccourcie all
afin d'appliquer la valeur indiquée sur toutes les propriétés (source : MDN : Héritage).
Cibler toutes les propriétés via all
La propriété all
est un super-raccourci de toutes les propriétés appliquables à un élément, ce qui lui permet d'hériter ou de réinitialiser toutes les valeurs à la fois.
Les valeurs possibles sont inherit
, initial
, unset
et revert
.
Exemple :
.parent {
display: grid;
margin: 2rem;
color: hotpink;
}
.enfant {
all: inherit;
}
Dans cet exemple, all
cible toutes les propriétés de .enfant
et inherit
les rend héritables, donc cela est équivalent au code suivant (pour les propriétés concernées) :
.enfant {
display: grid;
margin: 2rem;
color: hotpink;
}
Appliquer les valeurs par défaut via initial
La valeur initial
appliquée à une propriété lui confère sa valeur par défaut telle que prévue par les Spécifications CSS.
Exemple :
.parent {
display: grid;
margin: 2rem;
color: hotpink;
}
.enfant {
all: initial;
}
Cet exemple est équivalent au code suivant (pour les propriétés concernées) :
.enfant {
display: inline;
margin: 0;
color: canvastext;
}
Ce résultat peut surprendre dans la mesure où l'on s'attend généralement à la valeur block
pour la propriété display
(surtout si l'enfant est un élément tel que <div>
ou <p>
) ou black
pour la propriété color
, or il n'en est rien.
Il faut comprendre que toutes les propriétés CSS ont une valeur initiale définie dans les Spécifications (exemple display
vaut inline
). Puis elle est parfois écrasée par le navigateur au cas par cas selon les éléments (exemple div {display: block}
)
Quelques exemples de valeurs initial
surprenantes :
display: initial;
vautinline
max-width: initial;
vautnone
width: initial;
vautauto
position: initial;
vautstatic
cursor: initial;
vautauto
appearance: initial;
vautnone
color: initial;
vautcanvastext
(valeur récente, adaptée aux modes utilisateur Dark et Light).
Réinitialiser ou hériter via unset
La valeur unset
appliquée à une propriété lui confère la valeur du parent si la propriété peut être héritée ou la valeur initiale dans le cas contraire.
Exemple :
.parent {
display: grid;
margin: 2rem;
color: hotpink;
}
.enfant {
all: unset;
}
Cet exemple est équivalent au code suivant (pour les propriétés concernées) :
.enfant {
display: inline;
margin: 0;
color: hotpink;
}
Dans cet exemple, display
et margin
ne sont pas héritables donc leur valeur est calculée à initial
, mais la couleur, héritable, est transmise.
Quelques exemples de valeurs unset
:
max-width: unset;
: non héritable doncunset
vautinitial
qui vautnone
width: unset;
: non héritable doncunset
vautinitial
qui vautauto
position: unset;
: non héritable doncunset
vautinitial
qui vautstatic
font-size: unset;
: héritable donc récupère la valeur du parentcolor: unset;
: héritable donc récupère la valeur du parent (icihotpink
)
Récupérer la valeur du navigateur via revert
La valeur revert
récupère la valeur appliquée par l'Agent Utilisateur.
S'il n'y en a pas, revert
devient unset
(qui lui-même vaut inherit
ou initial
selon le cas 🤯)
Exemple :
.parent {
display: grid;
margin: 2rem;
color: hotpink;
}
.enfant {
all: revert;
}
Cet exemple est équivalent au code suivant (pour les propriétés concernées) :
.enfant {
display: block;
margin: 0;
color: hotpink;
}
Dans cet exemple, display
vaudra block
puisque c'est la valeur attribuée par le navigateur sur l'élément <div>
. Le navigateur n'applique pas de valeurs spécifiques au propriétés margin
et color
donc elles deviendront respectivement initial
et inherit
.
Quelques exemples de valeurs revert
selon l'élément appliqué :
div {display: revert}
vautblock
p {display: revert}
vautblock
-
span {display: revert}
vautinline
td {display: revert}
vauttable-cell
input {display: revert}
vautinline-block
Ces valeurs conférées par les navigateurs (User Agent Stylesheet) présentent parfois quelques différences selon les moteurs de rendu.
- Chromium UA stylesheet : concerne Google Chrome et Opera
- Mozilla UA stylesheet : concerne Firefox
- WebKit UA stylesheet : Safari
Vers le Reset / Normalize parfait ?
L'ensemble des propriétés et valeurs décrites au sein de cet article (all
, inherit
, initial
, unset
et revert
) offre une très large panoplie de possibilités de réinitialisation en CSS lorsque cela vous est nécessaire.
Un Reset CSS proche de la perfection ressemblerait à ces deux simples lignes :
* {
all: unset;
display: revert;
}
Ces deux lignes résument à elles seules les consignes suivantes :
- Toutes les propriétés appliquables à tous les éléments doivent être remises à zéro, sauf pour les propriétés héritables qui sont conservées, cela évite de devoir tout re-styler notamment pour les propriétés typographiques.
- Concernant la propriété
display
, nous souhaitons que la navigateur continue d'appliquer ses valeurs préférées (doncblock
,inline
, etc. selon l'élément).
Si la perfection existait, nous serions en présence du Reset ultime. Mais dans la vraie vie il y a aussi des images, des vidéos, des iframes, des tableaux, des SVG, etc.
Voilà pourquoi je ne saurais que vous conseiller de vous intéresser au projet "The New CSS Reset" maintenu sur Github par l'excellent Ahmad Shadeed et qui apporte les quelques affinages nécessaires.
Et vous, quelle est votre position par rapport à ces problématiques d'héritages, de cascades et de reset CSS ?
Avez-vous des solutions à tout faire que vous nous recommanderiez ?
Commentaires
C'est assez sympa comme reset ce "New CSS reset", mais si on a des soucis de compatibilité avec de vieux navigateurs, ça casse vite vu les sélecteurs utilisés :)
D'expérience, je dirais que c'est vraiment selon le besoin : pour du site simple avec peu de contraintes de compatibilité, du reset/normalize léger et simple, ça suffit amplement. Je mixe même les deux dans mes projets simples.
Sur des apps destinées à des parcs plus conséquents, c'est en général plus riche et surtout plus étendu. Genre j'ai remarqué que -webkit-appearance: none faisait planter la vocalization sur des inputs de type radio/checkboxes... des joyeusetés dans le genre ! Donc là on doit être beaucoup plus prudent dans les resets. Exemple : https://github.com/ProtonMail/WebClients/blob/main/packages/styles/scss/base/_reset.scss