Les dernières actualités d'Alsacreations.com
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.
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.)
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).
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;
}
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;
vaut inline
max-width: initial;
vaut none
width: initial;
vaut auto
position: initial;
vaut static
cursor: initial;
vaut auto
appearance: initial;
vaut none
color: initial;
vaut canvastext
(valeur récente, adaptée aux modes utilisateur Dark et Light).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 donc unset
vaut initial
qui vaut none
width: unset;
: non héritable donc unset
vaut initial
qui vaut auto
position: unset;
: non héritable donc unset
vaut initial
qui vaut static
font-size: unset;
: héritable donc récupère la valeur du parentcolor: unset;
: héritable donc récupère la valeur du parent (ici hotpink
)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}
vaut block
p {display: revert}
vaut block
span {display: revert}
vaut inline
td {display: revert}
vaut table-cell
input {display: revert}
vaut inline-block
Ces valeurs conférées par les navigateurs (User Agent Stylesheet) présentent parfois quelques différences selon les moteurs de rendu.
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 :
display
, nous souhaitons que la navigateur continue d'appliquer ses valeurs préférées (donc block
, 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 ?
Pour certaines personnes, la navigation au clavier est un moyen essentiel pour naviguer et interagir avec les éléments d’un site. Par exemple, certains handicaps moteurs sont incompatibles avec la souris, et nécessitent d'utiliser des claviers adaptés. Pour les personnes malvoyantes ayant une cécité sévère ou totale, l’accès au contenu se fait via un lecteur d’écran qui est pilotable exclusivement par un clavier. Ou bien encore, pour n'importe qui utilisant les raccourcis claviers pour son propre confort.
En bref, la navigation au clavier est un aspect important de l’accessibilité web. Elle permet de rendre son site utilisable pour tous et de manière équitable.
Si vous ne savez pas comment faire, c’est très simple. Il suffit de cliquer sur la page puis utiliser la touche tabulation Tab de votre clavier pour naviguer entre les éléments interactifs. Pour revenir en arrière, il faut combiner la touche Tab + Maj. La tabulation va alors se faire par rapport à l'endroit cliqué.
â¹ï¸ Si sur Mac cela ne fonctionne pas, il faut se rendre dans les "Préférences Système" > "Clavier" > “Raccourcis" et cocher *"Utiliser la navigation clavier pour déplacer la cible sur les différentes commandes"* (documentation Apple).
Faisons le test sur la page actuelle. Nous remarquons que :
La tabulation se fait sur tous les éléments interactifs : boutons, liens, champs de formulaire, sélecteur, etc.
Lorsque l’on tabule sur l’élément, on constate la plupart du temps la mise en valeur par un contour (sur la page actuelle : vert kiwi ð¥) qui correspond à la propriété outline
de l’élément. Et la tabulation correspond à déclencher, en CSS, la pseudo-classe :focus
de l’élément (à noter que le :focus
est également déclenché au clic, et au touch).
Il faut savoir que les navigateurs web ont un outline
par défaut :
Faisons un petit test : nous allons déclencher le focus en tabulant jusqu’au bouton ci-après et constater ce que l’on voit :
Vous y êtes parvenu ? Sûrement, mais vous ne l’avez pas vu car l’outline
a été retiré. Déroutant hein ? Imaginez-vous ce que ça serait si l’outline
était retiré sur tout un site... On n'aurait plus aucune indication sur la position du focus.
Cette indication est primordiale lors de la navigation au clavier, c'est ce qui va permettre à l'utilisateur de se repérer.
En résumé, il ne faut jamais retirer l’outline
(le fameux *:focus { outline: none; }
) ou bien utiliser une alternative comme la pseudo-classe CSS focus-visible
, compatible sur la majorité des navigateurs modernes, qui permet de ne faire apparaitre le focus qu’à la navigation clavier. Dans ce dernier cas et dans celui où l’apparence de l’outline
est modifiée il faut s’assurer qu’il soit assez contrasté par rapport à son milieu environnant.
Il existe d’ailleurs un critère RGAA à ce sujet :
Pourquoi est-ce important ?
Pour toutes personnes ayant une déficience visuelle ou ayant une basse vision, ce rapport de contraste permet de distinguer et de faciliter la lisibilité des contenus.
Faisons un autre test. Déclenchons le focus du "bouton 1" et du "bouton 2". Qu’observons-nous ?
Pour le bouton 1 : peut-être rien, ou sinon très légèrement. C’est normal car le lien a un outline
beaucoup trop clair par rapport à son fond environnant blanc. Son rapport de contraste est de 1,4:1 (testé sur Contrast finder) ce qui est très inférieur au 3:1 demandé par le RGAA.
En tabulant sur le bouton 2, le rapport de contraste est respecté, on peut distinguer l’état focus du bouton.
Si l'outline
natif des navigateurs n'est pas annulé ou modifié par votre feuille de styles, le RGAA précise que le critère 3.3 ci-dessus n’est pas concerné :
Les cas suivants sont non applicables pour ce critère : […] Composant d’interface pour lequel l’apparence est gérée par les styles natifs du navigateur sans aucune modification par l’auteur (par exemple, le style au focus natif dans Chrome ou Firefox) ;
Concernant l’ordre des éléments : la tabulation suit successivement les éléments interactifs de la page. En fait elle reprend l’ordre naturel du DOM. Lors de l’intégration de sa page HTML, il faut donc s’assurer que les éléments soient positionnés de manière cohérente et logique.
Par exemple, pour un élément details
lorsqu’il est ouvert, la tabulation doit être faite sur le premier élément interactif de la zone affichée.
Pourquoi est-ce important ?
Tout simplement pour ne pas perturber le lecteur et assurer une logique dans l’interactivité des éléments. Pour les personnes n’utilisant qu’un clavier, si la tabulation n’est pas cohérente, son utilisation sera complexifiée voire inutilisable. Voici un exemple :
Il existe un critère RGAA à ce sujet :
À noter qu'il est possible de modifier l'ordre de tabulation grâce à l'attribut tabindex : soit en rendant un élément interactif (tabindex="0"
) soit en modifiant l'ordre naturel (non conseillé). Je vous redirige vers cet article pour en savoir plus sur son utilisation.
Si un élément n’est pas correctement développé, il peut être totalement inutilisable au clavier.
Pour cela quelques principes sont à prendre en compte :
button
ou a href="#"
. Un bouton sert à déclencher une action sans changer de page (par exemple l'ouverture d'un menu, bloc caché ou d'une modale); un lien sert à naviguer vers une nouvelle page (interne ou externe).Nous l’avons vu dans notre premier test : 3 liens cachés sont apparus à la tabulation lors de notre arrivée sur le site. Mais pourquoi ? Car ces liens permettent de se rendre directement au contenu souhaité. C’est un accès rapide à différentes zones d’un site (contenu principal, menu, recherche, pied de page, etc.) qui permet de faciliter la navigation au clavier ! Bien sûr, la page doit être correctement structurée en zones claires et sémantiques (Régions landmarks) dans un premier temps.
Il faut savoir que le RGAA préconise d’en avoir un à minima correspondant à l’accès rapide du contenu principal :
Ce lien d'accès rapide doit être le premier élément interactif du site, et peut-être masqué de manière accessible (donc visible pour les lecteurs d’écran (en utilisant la classe sr-only de Tailwind par exemple)) et visible pour tous au focus.
Ces quelques points représentent les actions importantes à mettre en place pour assurer la navigation au clavier sur son site web. Bien sûr, il existe d’autres critères à mettre en place (hiérarchie des titres, structuration de la page, etc.) mais nous ne pouvons tout voir dans un seul article. Si vous êtes curieux·euses d’en savoir plus n’hésitez pas à le dire. Bonne lecture !