Crearea unui interval personalizat de intrare care să pară consecvent în toate browserele

Publicat: 2022-03-10
Rezumat rapid ↬ Intrările de interval au fost în mod notoriu o durere de stil. Fiecare browser redă intrarea în mod diferit, solicitând să utilizați prefixe de furnizor pentru a crea un aspect coeziv. În acest articol, vom arunca o privire asupra caracterului ciudat al introducerii în intervalul HTML și vom demonstra cum să stilăm intrarea astfel încât să pară consecventă în toate browserele majore.

Fiind unul dintre menținătorii unei biblioteci de componente UI, am implementat și stilat nenumărate elemente de intrare. Într-o zi, mi s-a atribuit sarcina de a adăuga o intrare în bibliotecă și m-am gândit că va fi un proces similar cu celelalte intrări pe care le implementasem în trecut. Această presupunere a fost corectă până când am început să testez intervalul de intrare în mai multe browsere și mi-am dat seama rapid că aveam mult mai mult de lucru.

După multe cercetări, am reușit în sfârșit să identific suficiente postări de blog, articole și tutoriale aprofundate care să mă ajute să stilizez intrarea intervalului pentru a reda consecvent. În loc să trebuiască să căutați mai multe resurse, scopul din spatele acestei postări de blog este de a oferi un ghișeu unic pentru a învăța cum să stilați corect o intrare de gamă care va arăta consecventă în toate browserele. Este articolul pe care mi-aș fi dorit să îl am când a trebuit să fac asta și, sper că va ajuta să faceți acest proces mai rapid și mai ușor pentru dvs.

Anatomia unui interval de intrare

Intervalul de intrare constă din două părți principale:

  1. Urmări
    Aceasta este partea cursorului pe care o parcurge degetul mare. Sau altfel spus, este elementul lung care reprezintă intervalele de valori care pot fi selectate.
  2. Deget mare
    Acesta este un element de pe pistă pe care utilizatorul se poate deplasa pentru a selecta diferite valori ale intervalului.
O intrare de gamă este compusă dintr-o pistă și degetul mare.
O intrare de gamă este compusă dintr-o pistă și degetul mare. (Previzualizare mare)

Dacă ar fi o ecuație matematică:

intrare interval = track + degetul mare

Introducerea intervalului este uneori denumită „glisor” și în restul acestui articol, voi folosi acești termeni în mod interschimbabil.

Incoerențe ale browserului

Pentru a demonstra de ce avem nevoie chiar de un tutorial despre intrările în intervalul de stiluri, în primul rând, vom arunca o privire la câteva capturi de ecran ale introducerii implicite a intervalului HTML și la modul în care este redată în cele patru browsere majore (Chrome, Firefox, Safari și Margine). Sau, dacă preferați, puteți vizualiza acest demo CodeSandbox în fiecare dintre browserele respective pentru a vedea inconsecvențele browserului în toată gloria lor.

Notă: Aceste capturi de ecran au fost făcute din septembrie 2021 și pot fi supuse modificărilor pe măsură ce browserele respective se actualizează.

Să începem prin a ne uita la Chrome, care, în opinia mea, redă cea mai ușor de utilizat versiunea de intrare în mod implicit.

Demo Chrome pentru introducerea implicită a intervalului HTML
Demo Chrome pentru introducerea implicită a intervalului HTML. (Previzualizare mare)

Firefox este următorul și arată diferit de intrarea redată de Chrome. În Firefox, înălțimea pistei este puțin mai mică. Pe de altă parte, înălțimea și lățimea degetului mare sunt mai mari și nu au aceeași culoare de fundal albastru pe care o are versiunea Chrome.

Demo Firefox pentru introducerea implicită a intervalului HTML
Demo Firefox pentru introducerea implicită a intervalului HTML. (Previzualizare mare)

Glisorul Safari este cel mai apropiat în aspect de versiunea Firefox, dar este, din nou, încă diferit. De data aceasta, piesa pare să aibă un efect de umbră, iar înălțimea degetului mare și lățimea sunt mai mici decât versiunile Chrome și Firefox. Dacă te uiți cu atenție, poți vedea, de asemenea, că degetul mare nu este centrat direct pe pistă, dându-i un aspect și o senzație nelustruită.

Demo Safari pentru introducerea implicită a intervalului HTML
Demo Safari pentru introducerea implicită a intervalului HTML. (Previzualizare mare)

Nu în ultimul rând este Edge care, acum că Microsoft Edge este construit din Chromium, este mult mai aliniat cu celelalte trei browsere decât predecesorul său pre-Chromium. Cu toate acestea, putem vedea că se redă în continuare diferit față de celelalte trei browsere. Redarea de către Edge a intrării în intervalul său arată foarte asemănătoare cu versiunea Chrome, cu excepția faptului că are o culoare de fundal gri mai închis pentru degetul mare și partea stângă a piesei înainte de degetul mare.

Demo Edge a introducerii implicite a intervalului HTML
Demo Edge a introducerii implicite a intervalului HTML. (Previzualizare mare)

Acum că am văzut cât de îngrozitor de inconsecvent redă fiecare browser intrarea în interval, vom arunca o privire la modul în care putem folosi CSS pentru a le uniformiza.

Mai multe după săritură! Continuați să citiți mai jos ↓

Resetarea intervalului (stiluri de bază)

Deoarece inconsecvențele browserului variază atât de mult, trebuie să începem de la condiții echitabile. Odată ce stilurile implicite pe care le aplică fiecare browser au fost eliminate, putem începe să lucrăm pentru a face o intrare mai uniformă. Vom folosi selectorul de atribut element de input[type="range"] și stilurile aplicate aici vor acționa ca o resetare CSS pentru intrare.

Pentru a aplica stilurile de bază avem nevoie de patru proprietăți:

  1. -webkit-appearance: none;
    Această proprietate este un prefix de furnizor care se aplică tuturor browserelor majore. Dându-i valoarea none , acest lucru îi spune fiecărui browser respectiv să șterge orice stil implicit. Acest lucru ne permite să putem începe de la zero și să construim aspectul intrării din acel punct.
  2. background: transparent;
    Aceasta șterge fundalul implicit care este aplicat intrării.
  3. cursor: pointer;
  4. width
    Setează lățimea totală a intrării.
 input[type="range"] { -webkit-appearance: none; appearance: none; background: transparent; cursor: pointer; width: 15rem; }
Introducerea intervalului în Chrome înainte de fundal: se aplică transparent.
Introducerea intervalului în Chrome înainte de fundal: se aplică transparent. (Previzualizare mare)
Introducerea intervalului în Chrome după ce au fost aplicate toate stilurile de resetare.
Introducerea intervalului în Chrome după ce au fost aplicate toate stilurile de resetare. (Previzualizare mare)

Stilizarea piesei

La stilizarea piesei (și a degetului mare) va trebui să țintăm prefixele furnizorilor specifice diferitelor browsere pentru a aplica stilurile adecvate în elementul relevant. În continuare, orice pseudo-element prefixat cu -webkit va fi aplicat browserelor Chrome, Safari, Opera și Edge (post-Chromium). Orice prefix cu -moz se referă la Firefox.

Mai jos sunt pseudo-elementele pe care le vom folosi pentru a viza pista:

  • ::-webkit-slider-runnable-track
    Vizează piesa în Chrome, Safari și Edge Chromium.
  • ::-moz-range-track
    Vizează piesa în 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; }

Singurele proprietăți necesare pentru pistă sunt height și background . Cu toate acestea, este obișnuit să vedeți o border-radius aplicată pentru a rotunji marginile.

Introducerea intervalului în Firefox după ce au fost aplicate stilurile de urmărire.
Introducerea intervalului în Firefox după ce au fost aplicate stilurile de urmărire. (Previzualizare mare)

Coafarea degetului mare

Stilizarea degetului mare (butonul din mijloc pe care îl mișcă utilizatorul) are mai multe nuanțe care trebuie luate în considerare, deoarece există mai multe inconsecvențe între browsere în acea parte a intervalului de intrare.

Mai jos sunt pseudo-elementele pe care le vom folosi pentru a viza degetul mare:

  • ::-webkit-slider-thumb
    Vizează degetul mare în Chrome, Safari și Edge Chromium.
  • ::-moz-range-thumb
    Vizează degetul mare în Firefox.

Deoarece browserele Firefox și Webkit au probleme de stil diferite, voi aborda fiecare problemă în mod individual și voi demonstra cum să gestionez fiecare dintre setările implicite ciudate care se aplică degetului mare.

Chrome, Safari, Edge Chromium (Webkit)

Primul stil pe care trebuie să-l aplicăm pseudo-elementului ::-webkit-slider-thumb este -webkit-appearance: none; prefix de furnizor. Am folosit această proprietate în secțiunea „Stiluri de bază” pentru a înlocui stilurile implicite generale care sunt aplicate de browser și servește un scop similar pentru degetul mare.

Introducerea intervalului în Chrome după ce se aplică <code>-webkit-appearance: none;</code>
Interval de intrare în Chrome după -webkit-appearance: none; este aplicat. (Previzualizare mare)

Odată ce stilurile implicite sunt eliminate, ne putem aplica propriile stiluri personalizate. Presupunând că aplicăm o height , width și background-color degetului mare, iată un exemplu de ceea ce am avea până acum:

Introducere interval în Chrome cu stiluri personalizate pentru degetul mare.
Introducere interval în Chrome cu stiluri personalizate pentru degetul mare. (Previzualizare mare)

În mod implicit, browserele WebKit redă degetul mare astfel încât să nu fie centrat pe pistă.

Pentru a centra corect degetul mare pe pistă, putem folosi următoarea formulă și o aplicăm proprietății margin-top :

margin-top = (înălțimea melodiei în pixeli / 2) - (înălțimea degetului mare în pixeli /2)

Luând stilurile pe care le-am aplicat în secțiunile anterioare și transformând rems în pixeli, am avea o înălțime a pistei de 8px și o înălțime a degetului mare de 32px. Aceasta ar însemna că:

margin-top = (8/2) - (32/2) = 4 - 16 = -12px

Pe baza acestui fapt, stilurile noastre finalizate pentru browserele webkit ar arăta ca următorul bloc de cod:

 /***** 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; }
Introducerea intervalului în Chrome după ce au fost aplicate toate stilurile.
Introducerea intervalului în Chrome după ce au fost aplicate toate stilurile. (Previzualizare mare)

Firefox

Când aplicați stiluri degetului mare în Firefox, va trebui să utilizați pseudo-elementul ::-moz-range-thumb . Din fericire, Firefox nu suferă de aceeași problemă de centrare ca browserele Webkit. Cu toate acestea, este o problemă care se află în jurul razei de margine și a marginii gri implicite pe care se aplică degetului mare.

Introducerea intervalului în Firefox cu marginea gri și raza marginii aplicate implicit.
(Previzualizare mare)

Pentru a remedia chenarul gri implicit putem adăuga border: none; proprietate. Pentru a elimina raza-chenar implicită care este aplicată, putem adăuga proprietatea border-radius: 0 și acum degetul mare va arăta consecvent în toate browserele.

Pe baza acestui fapt, stilurile noastre finalizate pentru browserul Firefox ar arăta astfel:

 /***** 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; }

Notă: Browserele Webkit nu aplică automat această rază la chenar, așa că dacă descoperiți că doriți să aplicați o anumită formă de rază a chenarului degetului mare, spre deosebire de anularea acesteia așa cum am făcut mai sus, va trebui să pentru a aplica dimensiunile border-radius dorite atât la pseudo-elementele -webkit-slider-thumb , cât și la ::-moz-range-thumb .

Stiluri de focalizare

Deoarece intrarea intervalului este un element interactiv, este imperativ să adăugați stiluri de focalizare pentru a respecta cele mai bune practici și standarde de accesibilitate. Când sunt aplicate stiluri de focalizare, acesta oferă un indicator vizual pentru utilizatori și este deosebit de important pentru cei care folosesc o tastatură pentru a naviga pe o pagină.

Conform documentației WAI-ARIA: Slider, se recomandă ca:

Focalizarea este plasată pe glisor (obiectul vizual pe care l-ar muta utilizatorul mouse-ului, cunoscut și sub denumirea de degetul mare).

Primul lucru pe care vom dori să-l facem este să eliminăm stilurile de focalizare implicite, astfel încât să le putem suprascrie cu stiluri personalizate. Pentru a viza stilurile de focalizare pentru degetele mari, putem folosi pseudo-elementele ::-webkit-slider-thumb și ::-moz-range-thumb pe care le-am folosit în secțiunea anterioară și le putem combina cu :focus psuedo-class . Putem apoi folosi proprietățile de contur CSS și de offset pentru a le stila așa cum ne dorim.

 /***** 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; }

Notă : Dacă degetului mare se aplică o border-radius de margine, Firefox redă un contur în forma degetului mare , în timp ce celelalte browsere afișează un contur blocat. Din păcate, nu există o soluție CSS simplă pentru aceasta și este singura inconsecvență care va fi prezentă. Cu toate acestea, scopul principal al adăugarii acestor stiluri este în scopuri de accesibilitate, iar scopul principal, oferirea unui indicator vizual atunci când elementul este focalizat, este încă atins.

Interval de intrare în Chrome cu stiluri de focalizare personalizate aplicate.
Interval de intrare în Chrome cu stiluri de focalizare personalizate aplicate. (Previzualizare mare)

Punând totul laolaltă

Acum că am acoperit toate stilurile necesare pentru a uniformiza intrarea intervalului, iată cum va arăta foaia de stil CSS finală:

 /********** 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; }

Concluzie

În plus față de metodele prezentate în articol, puteți profita și de generatorul CSS de intrare range pe care l-am creat, numit range-input.css . Cheia acestui proiect a fost crearea unui instrument care simplifică acest proces pentru dezvoltatori. Generatorul CSS vă permite să stilați rapid proprietățile CSS comune și oferă un glisor demonstrativ care afișează o previzualizare în timp real a stilurilor pe care doriți să le aplicați.

Sperăm că intrările în gama de stiluri vor fi mai simple în viitor. Cu toate acestea, până când va veni acea zi, știind ce pseudo-elemente și prefixele de furnizor să vizați, vă va ajuta să vă îndreptați bine spre stilarea glisoarelor pentru a se potrivi nevoilor dvs.

Alte resurse despre Smashing Magazine

  • Generatoare CSS
  • Simplificarea stilurilor de formulare cu accent-color
  • Soluții CSS inteligente pentru provocări comune ale UI
  • O scufundare profundă în object-fit și background-size în CSS