Fermer

mai 18, 2023

Comment créer un curseur de plage personnalisé à l’aide de CSS –

Comment créer un curseur de plage personnalisé à l’aide de CSS –


Dans cet article, je vais montrer comment utiliser les techniques CSS modernes pour créer un curseur de plage personnalisé accrocheur avec rien d’autre que le code HTML natif. <input> élément.

Curseurs de plage (<input type="range">) permettent aux utilisateurs de choisir une valeur dans une plage donnée, en fournissant des types d’entrée alternatifs tels que <input type="number">.

Les styles de curseur de plage par défaut ne sont pas très beaux. L’image ci-dessous donne une idée de la plage d’affichage par défaut des curseurs que nous allons styliser dans Chrome, Firefox et Safari.

Curseurs de plage par défaut dans Chrome, Firefox et Safari

Mais <input> les éléments sont difficiles à coiffer. La plupart des solutions en ligne pour les styliser reposent sur JavaScript et du code encombré. Pire encore, certaines de ces techniques brisent également l’accessibilité de l’élément.

Voyons donc comment mieux faire les choses, en utilisant uniquement CSS, et sans compromettre l’accessibilité. La démo CodePen ci-dessous montre ce que nous allons construire.

Voir le stylo
Curseurs de plage personnalisés CSS uniquement
par les Amis d’Afif (@t_afif)
sur CodePen.

Cool non ? Vous trouverez également des variations sur ces styles à la fin de l’article !

La structure de l’élément d’entrée Range

Commençons par disséquer la structure de l’élément d’entrée range. C’est un élément natif, et chaque navigateur a sa propre implémentation de ces éléments. Nous avons principalement deux implémentations différentes.

Il y en a un pour les navigateurs Webkit et Blink tels que Chrome, Edge, Safari et Opera :

<input type="range" min="0" max="100" step="1" value="20">
  <div>
    <div pseudo="-webkit-slider-runnable-track" id="track">
      <div id="thumb">
    </div>
   </div>
  </div>
</input>

Présentation de l'entrée Chrome

Et c’est celui pour Firefox :

<input type="range" min="0" max="100" step="1" value="20">
  <div></div>
  <div></div>
  <div></div>
</input>

Vue d'ensemble de l'entrée Firefox

Il existe une troisième implémentation pour IE, mais heureusement, ce navigateur est pratiquement mort et disparu maintenant !

Une telle incohérence entre les navigateurs est ce qui rend la tâche difficile, car nous devons fournir un style différent pour chaque implémentation. Je n’approfondirai pas cela, car l’article ne finirait jamais, mais je recommande fortement de lire Cet article par Ana Tudor pour une exploration plus approfondie.

La seule chose que vous devez garder à l’esprit est que, quelle que soit l’implémentation, nous avons toujours le « pouce » comme composant commun.

Affichage de l'élément pouce

Je vais seulement styliser cet élément, ce qui rendra mon curseur de plage personnalisé facile à personnaliser. Passons directement au code pour voir la magie en jeu.

Personnalisation de l’entrée

La première étape consiste à réinitialiser et à désactiver tous les styles par défaut du navigateur en utilisant appearance: none et quelques autres propriétés communes :

input {
  appearance :none;
  background: none;
  cursor: pointer;
}

Dans un scénario plus compliqué, nous devrons peut-être ajouter plus de code au cas où d’autres styles par défaut seraient appliqués à notre élément. Il suffit simplement de s’assurer que nous avons un élément « nu » sans aucun style visuel.

Définissons également quelques variables CSS afin de pouvoir facilement créer différentes variations pour le curseur de plage. Ne vous inquiétez pas si une partie du code ci-dessous semble complexe. Nous devons juste mettre à jour quelques variables pour contrôler notre curseur :

input {
  --c: orange; 
  --g: 8px; 
  --l: 5px; 
  --s: 30px; 

  width: 400px; 
  height: var(--s); 
  appearance :none;
  background: none;
  cursor: pointer;
}

À cette étape, seul le pouce est visible avec ses styles par défaut, comme le montre la démo CodePen ci-dessous.

Voir le stylo
Styles de saisie par défaut — par Temani Afif
par SitePoint (@SitePoint)
sur CodePen.

Styliser l’élément de pouce

Stylisons l’élément pouce. Nous allons commencer par la configuration de base :

<thumb selector> {
  height: var(--s);
  aspect-ratio: 1;
  border-radius: 50%;
  box-shadow: 0 0 0 var(--l) inset var(--c);
  appearance: none;
}

Le code doit être explicite. Rien d’extraordinaire jusqu’à présent, et nous obtiendrons le résultat ci-dessous.

Voir le stylo
Coiffer le pouce — par Temani Afif
par SitePoint (@SitePoint)
sur CodePen.

Notez l’utilisation de deux sélecteurs différents, comme nous l’avons expliqué dans la première section :


input[type="range" i]::-webkit-slider-thumb { }

input[type="range"]::-moz-range-thumb { }

Mais comment savez-vous le sélecteur à utiliser?

J’ai simplement inspecté le code de l’entrée à l’aide des outils de développement du navigateur pour voir le sélecteur que chaque navigateur utilise pour styliser le pouce. L’article que je partagé précédemment vous montre comment manipuler les outils de développement pour obtenir ces informations.

Ajouter de la magie avec border-image

Nous allons maintenant utiliser une astuce CSS magique pour compléter notre slider. Elle implique l’utilisation de border-image:

border-image: linear-gradient(90deg,var(--_c) 50%,#ababab 0) 1/0 100vw/0 calc(100vw + var(--g));

Je sais que ça a l’air effrayant, mais disséquons cette ligne et vous verrez que ce n’est pas si difficile. Ce qui précède est le raccourci pour ce qui suit :

border-image-source: linear-gradient(90deg,var(--c) 50%,#ababab 0); 
border-image-slice: 1;
border-image-width: 0 100vw;
border-image-outset: 0 calc(100vw + var(--g));

Du Page MDNnous lisons:

Le border-image La propriété CSS dessine une image autour d’un élément donné. Il remplace la bordure régulière de l’élément.

Notre image sera un dégradé ayant deux couleurs — la principale (définie par --c), et une couleur grise. Nous avons besoin que l’image de bordure couvre tout l’espace de l’entrée horizontalement, nous utilisons donc une grande valeur pour la largeur gauche et droite (100vw) tandis que nous gardons le haut et le bas à (0).

Mais le border-image-width est limité à la taille de l’élément. Pour surmonter cela, nous devons également utiliser une grande valeur pour le border-image-outset pour augmenter l’espace disponible pour l’image de bordure. Depuis MDN encore:

Le border-image-outset La propriété CSS définit la distance à laquelle l’image de bordure d’un élément est définie par rapport à sa boîte de bordure.

Les parties de l’image de bordure qui sont rendues à l’extérieur de la zone de bordure de l’élément avec border-image-outset ne déclenche pas les barres de défilement de débordement et ne capture pas les événements de la souris.

Lorsque vous voyez le curseur pour la première fois, il semble que nous augmentions la couleur principale sur la gauche, mais en réalité, nous glissons un dégradé fixe qui déborde de notre élément.

La démo suivante donne un aperçu de ce qui se passe sous le capot.

Voir le stylo
Vue d’ensemble de l’astuce de l’image de bordure
par SitePoint (@SitePoint)
sur CodePen.

Faites glisser le pouce et faites-le glisser pour voir comment les choses bougent. J’utilise une petite valeur pour la largeur et le début afin que nous puissions facilement comprendre l’astuce.

Notez également que le début doit être plus grand que la largeur pour avoir l’espace. Pour cette raison, il est défini comme étant égal à la largeur plus la valeur de l’écart.

En ajoutant overflow: hidden à l’élément d’entrée et en utilisant une grande valeur, l’illusion est parfaite, comme indiqué ci-dessous.

Voir le stylo
Curseur de plage — débordement : masqué
par SitePoint (@SitePoint)
sur CodePen.

Que dire de la border-image-slice? Pourquoi la valeur de 1?

Cette propriété est un peu délicate, mais obligatoire lors de l’utilisation border-image. Dans notre cas, cette valeur n’est pas très pertinente et une petite valeur positive fera l’affaire. j’ai un détail Réponse de débordement de pile si vous voulez en savoir plus.

La dernière étape consiste à réduire la taille de la barre pour qu’elle corresponde à la taille que nous avons définie par la variable --l. Pour cela, nous allons utiliser clip-path:

clip-path:
    polygon(
       0     calc(50% + var(--l)/2),
      -100vw calc(50% + var(--l)/2),
      -100vw calc(50% - var(--l)/2),
       0     calc(50% - var(--l)/2),
       0 0,100% 0,
       100%  calc(50% - var(--l)/2),
       100vw calc(50% - var(--l)/2),
       100vw calc(50% + var(--l)/2),
       100%  calc(50% + var(--l)/2),
       100% 100%,0 100%);

L’image ci-dessous donne un aperçu des différents points permettant de comprendre la forme du polygone.

Vue d'ensemble du polygone de chemin de détourage

C’est ça! Nous avons un curseur de plage personnalisé avec quelques lignes de code que vous pouvez facilement contrôler en ajustant quelques variables.

Voir le stylo
Curseur de plage finale — par Temani Afif
par SitePoint (@SitePoint)
sur CodePen.

Ajouter de l’animation

Qu’en est-il d’une animation subtile lorsque nous interagissons avec le curseur ? Il n’a pas besoin de beaucoup de code et cela améliorera l’UX du slider.

Tout d’abord, nous allons transformer le pouce d’un cercle à bordure uniquement en un cercle complet lorsque nous cliquons dessus. Pour cela, nous augmentons la valeur de propagation du box-shadow. Rappelez-vous que nous avons utilisé box-shadow pour définir la bordure du pouce :

box-shadow: 0 0 0 var(--l) inset var(--c);

Nous mettons à jour le var(--l) pour var(--s) en utilisant le :active sélecteur et le :focus-visible. Ce dernier est lié à la navigation au clavier et nous permet d’avoir le même effet que nous utilisions la souris ou le clavier.

Le code est comme suit:

input[type="range" i]::-webkit-slider-thumb {
  box-shadow: 0 0 0 var(--s) inset var(--c);
  transition: .3s;
}

input[type="range" i]::-moz-range-thumb {
  box-shadow: 0 0 0 var(--s) inset var(--c);
  transition: .3s;
}

input:active::-webkit-slider-thumb,
input:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 var(--s) inset var(--c);
}

input:active::-moz-range-thumb,
input:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 var(--s) inset var(--c);
}

C’est un peu long pour un box-shadow transition, non ? Nous pouvons l’optimiser en utilisant une variable CSS :

input[type="range" i]::-webkit-slider-thumb {
  box-shadow: 0 0 0 var(--_b,var(--s)) inset var(--c);
  transition: .3s;
}

input[type="range" i]::-moz-range-thumb {
  box-shadow: 0 0 0 var(--_b,var(--s)) inset var(--c);
  transition: .3s;
}

input:active,
input:focus-visible {
  --_b:  var(--s);
}

J’exprime la valeur de propagation à l’aide d’une variable, et je mets simplement à jour cette variable sur :active et :focus-visible.

Je vais aussi ajouter une petite animation à la couleur. Je vais le rendre un peu plus sombre :hover. Pour cela, je ne vais pas mettre à jour la couleur, mais plutôt la mélanger avec du noir en utilisant le nouveau color-mix() fonction. Cette astuce nous permet d’utiliser la couleur principale définie par --c plutôt que de définir manuellement une nouvelle couleur sombre pour chaque curseur :

--_c: color-mix(in srgb, var(--c), #000 var(--p,0%));

Je définis une nouvelle variable qui remplacera le --c dans le code. Puis en ajustant le pourcentage de la couleur noire (#000) en utilisant la variable --pje contrôle la « obscurité » de la couleur :

input:focus-visible,
input:hover{
  --p: 25%;
}

Cette fonctionnalité n’est pas encore prise en charge par tous les navigateurs. L’utilisation d’une alternative est donc fortement recommandée :

@supports not (color: color-mix(in srgb,red,red)) {
  input {
    --_c: var(--c); 
  }
}

Notre curseur de gamme est maintenant parfait !

Voir le stylo
Curseurs de plage personnalisés CSS uniquement
par SitePoint (@SitePoint)
sur CodePen.

Conclusion

Nous avons atteint la fin et n’avons eu à gérer aucune implémentation complexe liée au navigateur ! Nous avons identifié le sélecteur de l’élément pouce et, à l’aide de quelques astuces CSS, nous avons stylisé l’ensemble du curseur de plage avec celui-ci. N’oublions pas que nous avons fait cela en utilisant uniquement le <input> élément, nous n’avons donc pas à nous soucier des problèmes d’accessibilité, car nous avons conservé la fonctionnalité native. Le curseur prend en charge la navigation au clavier sans problème.

Voici d’autres exemples de curseurs utilisant la même technique. Je vous laisse disséquer leur code comme exercice.

Voir le stylo
Curseur de plage personnalisé — par Temani Afif
par SitePoint (@SitePoint)
sur CodePen.

Voir le stylo
Curseur de plage personnalisé — par Temani Afif
par SitePoint (@SitePoint)
sur CodePen.






Source link