Création d'une entrée de plage personnalisée qui semble cohérente dans tous les navigateurs
Publié: 2022-03-10En tant que l'un des mainteneurs d'une bibliothèque de composants d'interface utilisateur, j'ai implémenté et stylisé des myriades d'éléments d'entrée. Un jour, on m'a confié la tâche d'ajouter une entrée de plage à la bibliothèque et j'ai pensé que ce serait un processus similaire aux autres entrées que j'avais implémentées dans le passé. Cette hypothèse était correcte jusqu'à ce que je commence à tester l'entrée de plage sur plusieurs navigateurs et que je réalise rapidement que j'avais beaucoup plus de travail à faire.
Après de nombreuses recherches, j'ai finalement pu identifier suffisamment d'articles de blog, d'articles et de didacticiels approfondis pour m'aider à styliser l'entrée de la plage afin qu'elle s'affiche de manière cohérente. Au lieu d'avoir à rechercher plusieurs ressources, l'objectif de cet article de blog est de fournir un guichet unique pour apprendre à styliser correctement une entrée de plage qui sera cohérente sur tous les navigateurs. C'est l'article que j'aurais aimé avoir quand j'ai dû le faire moi-même et j'espère qu'il contribuera à rendre ce processus plus rapide et plus fluide pour vous.
Anatomie d'une entrée de plage
L'entrée de plage se compose de deux parties principales :
- Pister
Il s'agit de la partie du curseur sur laquelle passe le pouce. Autrement dit, c'est l'élément long qui représente les plages de valeurs pouvant être sélectionnées. - Pouce
Il s'agit d'un élément sur la piste que l'utilisateur peut déplacer pour sélectionner différentes valeurs de plage.
Si c'était une équation mathématique :
entrée de gamme = piste + pouce
L'entrée de plage est parfois appelée "curseur" et dans le reste de cet article, j'utiliserai ces termes de manière interchangeable.
Incohérences du navigateur
Pour démontrer pourquoi nous avons même besoin d'un didacticiel sur le style des entrées de plage en premier lieu, nous allons jeter un œil à quelques captures d'écran de l'entrée de plage HTML par défaut et comment elle est rendue sur les quatre principaux navigateurs (Chrome, Firefox, Safari et Bord). Ou, si vous préférez, vous pouvez voir cette démo CodeSandbox dans chacun des navigateurs respectifs pour voir les incohérences du navigateur dans toute leur splendeur.
Remarque : ces captures d'écran ont été prises en septembre 2021 et peuvent être modifiées à mesure que les navigateurs respectifs sont mis à jour.
Commençons par regarder Chrome qui, à mon avis, rend la version la plus conviviale de l'entrée par défaut.
Firefox est le suivant et semble différent de l'entrée rendue par Chrome. Dans Firefox, la hauteur de la piste est légèrement plus courte. En revanche, la hauteur et la largeur du pouce sont plus grandes et n'ont pas la même couleur de fond bleu que la version Chrome.
Le curseur Safari est le plus proche de la version Firefox mais, encore une fois, il est toujours différent. Cette fois-ci, la piste semble avoir un effet d'ombre et la hauteur et la largeur du pouce sont plus petites que les rendus de Chrome et Firefox. Si vous regardez attentivement, vous pouvez également voir que le pouce n'est pas centré directement sur la piste, ce qui lui donne un aspect et une sensation non polis.
Le dernier mais non le moindre est Edge qui, maintenant que Microsoft Edge est construit à partir de Chromium, est bien plus aligné avec les trois autres navigateurs que son prédécesseur pré-Chromium. Cependant, nous pouvons voir qu'il est toujours rendu différemment des trois autres navigateurs. Le rendu d'Edge de son entrée de gamme ressemble beaucoup à la version Chrome, sauf qu'il a une couleur de fond gris plus foncé pour le pouce et le côté gauche de la piste avant le pouce.
Maintenant que nous avons vu à quel point chaque navigateur rend l'entrée de plage terriblement incohérente, nous allons voir comment nous pouvons utiliser CSS pour les uniformiser.
Réinitialisation de la plage (styles de base)
Étant donné que les incohérences des navigateurs varient considérablement, nous devons commencer sur un pied d'égalité. Une fois que les styles par défaut appliqués par chaque navigateur ont été supprimés, nous pouvons commencer à travailler pour créer une entrée plus uniforme. Nous utiliserons le sélecteur d'attribut d'élément input[type="range"]
et les styles appliqués ici agiront comme une réinitialisation CSS pour l'entrée.
Pour appliquer les styles de ligne de base, nous avons besoin de quatre propriétés :
-
-webkit-appearance: none;
Cette propriété est un préfixe de fournisseur qui s'applique à tous les principaux navigateurs. En lui donnant la valeurnone
, cela indique à chaque navigateur respectif d'effacer tous les styles par défaut. Cela nous permet de pouvoir repartir de zéro et de créer l'apparence de l'entrée à partir de ce point. -
background: transparent;
Cela efface l'arrière-plan par défaut appliqué à l'entrée. -
cursor: pointer;
-
width
Définit la largeur globale de l'entrée.
input[type="range"] { -webkit-appearance: none; appearance: none; background: transparent; cursor: pointer; width: 15rem; }
Styliser la piste
Lors du style de la piste (et du pouce), nous devrons cibler les différents préfixes de fournisseur spécifiques aux navigateurs afin d'appliquer les styles appropriés dans l'élément concerné. À l'avenir, tout pseudo-élément préfixé par -webkit
sera appliqué aux navigateurs Chrome, Safari, Opera et Edge (post-Chromium). Tout ce qui est préfixé par -moz
appartient à Firefox.
Voici les pseudo-éléments que nous utiliserons pour cibler la piste :
-
::-webkit-slider-runnable-track
Cible la piste dans Chrome, Safari et Edge Chromium. -
::-moz-range-track
Cible la piste dans Firefox.
/***** Track Styles *****/ /***** Chrome, Safari, Opera, and Edge Chromium *****/ input[type="range"]::-webkit-slider-runnable-track { background: #053a5f; height: 0.5rem; } /******** Firefox ********/ input[type="range"]::-moz-range-track { background: #053a5f; height: 0.5rem; }
Les seules propriétés requises pour la piste sont la height
et l'arrière- background
. Cependant, il est courant de voir un border-radius
appliqué afin d'arrondir les bords.
Styliser le pouce
Le style du pouce (le bouton du milieu que l'utilisateur déplace) a plus de nuances qui doivent être prises en compte car il y a plus d'incohérences entre les navigateurs sur cette partie de la plage d'entrée.
Ci-dessous les pseudo-éléments que nous allons utiliser pour cibler le pouce :
-
::-webkit-slider-thumb
Cible le pouce dans Chrome, Safari et Edge Chromium. -
::-moz-range-thumb
Cible le pouce dans Firefox.
Étant donné que Firefox et les navigateurs Webkit ont des problèmes de style différents, je vais aborder chaque problème individuellement et montrer comment gérer chacune des valeurs par défaut bizarres qui s'appliquent au pouce.
Chrome, Safari, Bord Chrome (Webkit)
Le premier style que nous devons appliquer au pseudo-élément ::-webkit-slider-thumb
est le -webkit-appearance: none;
préfixe du fournisseur. Nous avons utilisé cette propriété dans la section "Styles de base" pour remplacer les styles généraux par défaut appliqués par le navigateur et elle sert un objectif similaire sur le pouce.
Une fois les styles par défaut supprimés, nous pouvons ensuite appliquer nos propres styles personnalisés. En supposant que nous appliquions une height
, une width
et background-color
au pouce, voici un exemple de ce que nous aurions jusqu'à présent :
Par défaut, les navigateurs WebKit restituent le pouce afin qu'il ne soit pas centré sur la piste.
Afin de centrer correctement le pouce sur la piste, nous pouvons utiliser la formule suivante et l'appliquer à la propriété margin-top
:
margin-top = (hauteur de la piste en pixels / 2) - (hauteur du pouce en pixels / 2)
En prenant les styles que nous avons appliqués dans les sections précédentes et en convertissant les rems
en pixels, nous aurions une hauteur de piste de 8px et une hauteur de pouce de 32px. Cela signifierait que :
marge-haut = (8/2) - (32/2) = 4 - 16 = -12px
Sur cette base, nos styles finalisés pour les navigateurs webkit ressembleraient au bloc de code suivant :
/***** Thumb Styles *****/ /***** Chrome, Safari, Opera, and Edge Chromium *****/ input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; /* Override default look */ appearance: none; margin-top: -12px; /* Centers thumb on the track */ background-color: #5cd5eb; height: 2rem; width: 1rem; }
Firefox
Lors de l'application de styles au pouce dans Firefox, vous devrez tirer parti du pseudo-élément ::-moz-range-thumb
. Heureusement, Firefox ne souffre pas du même problème de centrage que les navigateurs Webkit. Cependant, c'est un piège autour du rayon de bordure par défaut et de la bordure grise qu'il applique au pouce.
Afin de corriger la bordure grise par défaut, nous pouvons ajouter la border: none;
biens. Pour supprimer le border-radius par défaut qui est appliqué, nous pouvons ajouter la propriété border-radius: 0
et maintenant le pouce aura l'air cohérent sur tous les navigateurs.
Sur cette base, nos styles finalisés pour le navigateur Firefox ressembleraient à ceci :
/***** Thumb Styles *****/ /***** Firefox *****/ input[type="range"]::-moz-range-thumb { border: none; /*Removes extra border that FF applies*/ border-radius: 0; /*Removes default border-radius that FF applies*/ background-color: #5cd5eb; height: 2rem; width: 1rem; }
Remarque : Les navigateurs Webkit n'appliquent pas automatiquement ce rayon à la bordure, donc si vous constatez que vous souhaitez appliquer une forme de rayon de bordure au pouce, au lieu de l'annuler comme nous l'avons fait ci-dessus, vous aurez besoin pour appliquer les dimensions de border-radius
souhaitées aux pseudo-éléments -webkit-slider-thumb
et ::-moz-range-thumb
.
Styles de mise au point
Étant donné que l'entrée de plage est un élément interactif, il est impératif d'ajouter des styles de focus pour se conformer aux meilleures pratiques et normes d'accessibilité. Lorsque des styles de focus sont appliqués, ils fournissent un indicateur visuel aux utilisateurs et sont particulièrement importants pour ceux qui utilisent un clavier pour naviguer sur une page.
Selon la documentation WAI-ARIA : Slider, il est recommandé que :
Le focus est placé sur le curseur (l'objet visuel que l'utilisateur de la souris déplacerait, également appelé pouce).
La première chose que nous voudrons faire est de supprimer les styles de focus par défaut afin de pouvoir les remplacer par des styles personnalisés. Afin de cibler les styles de focus des pouces, nous pouvons tirer parti des pseudo-éléments ::-webkit ::-webkit-slider-thumb
et ::-moz-range-thumb
que nous avons utilisés dans la section précédente et les combiner avec la pseudo-classe :focus
. Nous pouvons ensuite utiliser les propriétés CSS outline et outline-offset pour le styler comme nous le souhaitons.
/***** Focus Styles *****/ /* Removes default focus */ input[type="range"]:focus { outline: none; } /***** Chrome, Safari, Opera, and Edge Chromium *****/ input[type="range"]:focus::-webkit-slider-thumb { border: 1px solid #053a5f; outline: 3px solid #053a5f; outline-offset: 0.125rem; } /******** Firefox ********/ input[type="range"]:focus::-moz-range-thumb { border: 1px solid #053a5f; outline: 3px solid #053a5f; outline-offset: 0.125rem; }
Note : Si un border-radius
est appliqué au pouce, Firefox restitue un contour en forme de pouce alors que les autres navigateurs affichent un contour en blocs. Malheureusement, il n'y a pas de solution CSS simple pour cela et c'est la seule incohérence qui sera présente. Cependant, l'objectif principal de l'ajout de ces styles est à des fins d'accessibilité et l'objectif principal, fournir un indicateur visuel lorsque l'élément est ciblé, est toujours atteint.
Mettre tous ensemble
Maintenant que nous avons couvert tous les styles nécessaires pour uniformiser l'entrée de plage, voici à quoi ressemblera la feuille de style CSS finale :
/********** Range Input Styles **********/ /*Range Reset*/ input[type="range"] { -webkit-appearance: none; appearance: none; background: transparent; cursor: pointer; width: 15rem; } /* Removes default focus */ input[type="range"]:focus { outline: none; } /***** Chrome, Safari, Opera and Edge Chromium styles *****/ /* slider track */ input[type="range"]::-webkit-slider-runnable-track { background-color: #053a5f; border-radius: 0.5rem; height: 0.5rem; } /* slider thumb */ input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; /* Override default look */ appearance: none; margin-top: -12px; /* Centers thumb on the track */ /*custom styles*/ background-color: #5cd5eb; height: 2rem; width: 1rem; } input[type="range"]:focus::-webkit-slider-thumb { border: 1px solid #053a5f; outline: 3px solid #053a5f; outline-offset: 0.125rem; } /******** Firefox styles ********/ /* slider track */ input[type="range"]::-moz-range-track { background-color: #053a5f; border-radius: 0.5rem; height: 0.5rem; } /* slider thumb */ input[type="range"]::-moz-range-thumb { border: none; /*Removes extra border that FF applies*/ border-radius: 0; /*Removes default border-radius that FF applies*/ /*custom styles*/ background-color: #5cd5eb; height: 2rem; width: 1rem; } input[type="range"]:focus::-moz-range-thumb { border: 1px solid #053a5f; outline: 3px solid #053a5f; outline-offset: 0.125rem; }
Conclusion
En plus des méthodes décrites tout au long de l'article, vous pouvez également tirer parti du générateur CSS d'entrée de plage que j'ai créé et appelé range-input.css . Le cœur de ce projet était de créer un outil qui simplifie ce processus pour les développeurs. Le générateur CSS vous permet de styliser rapidement les propriétés CSS courantes et fournit un curseur de démonstration qui affiche un aperçu en temps réel des styles que vous souhaitez appliquer.
Espérons que les entrées de gamme de style seront plus simples à l'avenir. Cependant, jusqu'à ce jour, savoir quels pseudo-éléments et préfixes de fournisseur cibler vous aidera à bien styliser les curseurs en fonction de vos besoins.
Autres ressources sur Smashing Magazine
- Générateurs CSS
- Simplification des styles de formulaire avec
accent-color
- Solutions CSS intelligentes pour les défis courants de l'interface utilisateur
- Une plongée profonde dans
object-fit
etbackground-size
en CSS