Stiluri selectate personalizate cu CSS pur

Acesta este episodul nr. 20 dintr-o serie care examinează soluții CSS moderne la problemele pe care le-am rezolvat în ultimii 13+ ani de când am fost dezvoltator de frontend.

CSS modern ne oferă o gamă de proprietăți pentru a obține stiluri selectate personalizate care au aproape o identitate aspectul inițial pentru elementele select simple, multiple și dezactivate din browserele de top.

Câteva proprietăți și tehnici pe care soluția noastră le va utiliza:

  • clip-path pentru a crea săgeata drop-down personalizată
  • aspectul grilei CSS pentru a alinia selecția și săgeata nativă
  • variabilele CSS personalizate pentru stil flexibil
  • em unități pentru dimensionarea relativă

Probleme obișnuite cu selecțiile native #

La fel ca în cazul tuturor tipurilor de câmpuri de formular, <select> variază în funcție de browser în aspectul său inițial.

De la stânga la dreapta, iată aspectul inițial pentru <select> în Firefox, Chrome și Safari:

Diferențele includ dimensiunea casetei, dimensiunea fontului, înălțimea liniei și cea mai importantă diferență este modul în care este indicat stilul derulant.

obiectivul este de a crea același aspect inițial în aceste browsere, inclusiv selecții multiple și stări dezactivate.

Notă: lista derulantă nu este încă stilabilă, deci, odată ce <select> este deschisă, va prelua în continuare stilurile individuale ale browserului pentru lista option. Acest lucru este ok – ne putem ocupa de asta pentru a păstra accesibilitatea gratuită a unei selecții native!

HTML HTML de bază

Noi ” Ne vom concentra pe un singur <select> pentru a începe.

Eticheta nu face parte din exercițiul nostru de styling, ci este inclusă ca o cerință generală, în special cu for atribut având valoarea id pe <select>.

Pentru a ne îndeplini stilurile personalizate, am „împachetat selecția nativă într-un div suplimentar cu clasa select pentru simplitate în acest tutorial.

Resetați și eliminați stilurile moștenite #

După cum este inclus în toate tutorialele mele ca o bună practică modernă, adăugăm mai întâi următoarea resetare:

După aceea, putem începe regula pentru nativul select și putem aplica următoarele pentru a-și odihni aspectul:

În timp ce majoritatea dintre aceștia sunt familiarizați, ciudat este . Aceasta este o proprietate rar utilizată și veți observa că nu ne place exact locul în care ne-ar plăcea pentru asistență, ci ceea ce ne oferă în primul rând în acest caz este eliminarea săgeții derulante a browserului nativ.

Notă: CodePen este configurat pentru a utiliza autoprefixer care va adăuga versiunile prestabilite necesare ale proprietății appearance. Este posibil să trebuiască să configurați acest lucru în mod specific pentru proiectul dvs. sau să îl adăugați manual. HTML / Sass Jumpstart include autoprefixer ca parte a versiunii de producție.

Vestea bună este că putem adăuga încă o regulă pentru a obține eliminarea săgeții pentru versiunile IE mai mici, dacă aveți nevoie de ea:

Acest sfat găsit în articol excelent din Filament Group care prezintă o metodă alternativă pentru a crea stiluri selectate.

Ultima parte este eliminarea valorii implicite outline. Nu vă faceți griji – noi ” Voi adăuga un înlocuitor mai târziu pentru :focus state!

Și aici este un gif al progresului nostru. Puteți vedea că acum există zero indicații vizuale că acesta este un select înainte de a face clic pe acesta:

Stiluri de casetă de selectare personalizate #

Mai întâi, să setăm câteva variabile CSS. Acest lucru va permite selecției noastre să fie recolorată flexibil, astfel încât să reprezinte o stare de eroare.

Notă de accesibilitate: ca element de interfață cu utilizatorul, chenarul selectat trebuie să aibă un contrast 3: 1 sau mai mare în raport cu culoarea suprafeței înconjurătoare.

Acum este timpul să creăm stilurile de selectare personalizate pe care le vom aplica la ambalajul nostru div.select:

Mai întâi, configurăm câteva constrângeri de lățime. Valorile min-width și max-width sunt în mare parte pentru această demonstrație și puteți alege să o renunțați sau să o modificați pentru cazul dvs. de utilizare.

Apoi aplicăm câteva proprietăți ale modelului de casetă, inclusiv border, border-radius și padding. Rețineți utilizarea unității em care va păstra aceste proprietăți proporționale cu setul font-size.

În stilurile de resetare, setăm mai multe proprietăți la inherit, deci aici le definim pe acestea, inclusiv font-size, cursor și line-height.

În cele din urmă, îi furnizăm proprietăți de fundal, inclusiv un gradient pentru cel mai mic bit de dimensiune. Dacă eliminați proprietățile fundalului, selectarea va fi transparentă și va prelua fundalul paginii. Acest lucru poate fi de dorit, totuși, fiți conștienți și testați efectele asupra contrastului.

Și aici sunt progresele noastre:

Personalizat Selectați săgeata dropdown #

Pentru săgeata dropdown, vom folosi una dintre cele mai interesante proprietăți CSS moderne: clip-path.

Căile de decupare ne permit să realizăm tot felul de forme „decupând” formele pătrate și dreptunghiulare pe care le primim ca implicite din cele mai multe elemente. M-am distrat folosind clip-path pe recențierea site-ului meu recent al portofoliului.

Înainte ca clip-path să aibă un suport mai bun, metodele alternative includ:

  • background-image – de obicei un png, ceva mai modern ar fi un SVG
  • un SVG în linie ca element suplimentar
  • trucul de frontieră pentru a crea un triunghi

SVG se poate simți ca soluția optimă, cu toate acestea, atunci când este utilizat ca background-image, pierde capacitatea de a acționa ca o pictogramă în sensul că nu poți t o modificați proprietățile sale, cum ar fi culoarea umplerii, fără a o redefini complet. Aceasta înseamnă că nu putem folosi variabila personalizată CSS.

Plasarea unei linii SVG rezolvă problema de culoare fill, totuși înseamnă să mai includeți un element de fiecare dată când <select> este definit.

Cu clip-path, obținem o săgeată clară, scalabilă, „grafică”, care pare a fi un SVG cu avantajele de a putea folosi variabila noastră personalizată și de a fi conținut în stilul față de marcajul HTML.

Pentru a crea săgeata, o vom defini ca ::after pseudo-element.

Sintaxa clip-path este puțin ciudată și, din moment ce „s nu este chiar punctul central al acestui articol, vă recomand următoarele resurse:

  • Colby Fayock explică sintaxa cu un exemplu în acest videoclip egghead
  • Clippy este un instrument online care permite să selectați o formă și să ajustați punctele în timp ce generați dinamic CSS clip-path

Dacă urmați aripa de-a lungul, este posibil să fi observat că săgeata nu apare în ciuda definirii width și height. Când a fost inspectat, sa constatat că ::after nu este de fapt permisă lățimii sale.

Vom rezolva acest lucru actualizându-ne .select pentru a utiliza aspectul grilei CSS.

Aceasta permite săgeții să apară prin extinderea ei, în esență, a unei valori de afișare asemănătoare cu „bloc”.

În această etapă putem verifica dacă am creat într-adevăr un triunghi.

Pentru a remedia alinierea, vom folosi hack-ul meu de grilă CSS preferat (pălărie veche pentru tine dacă ai citit câteva articole aici!).

Soluție CSS veche: position: absolute Nouă soluție CSS: o singură grid-template-areas care să le conțină pe toate

Mai întâi ne vom defini zona, apoi vom defini că select și ::after îl folosesc ambele. Numele este definit pentru elementul pentru care a fost creat și îl vom ușura numindu-l „select”:

Ceea ce ne oferă o suprapunere a săgeata de deasupra selecției native datorită contextului de stivuire prin ordinea sursă:

Acum putem folosi proprietățile grilei pentru a finaliza alinierea din fiecare element:

Ta-da!

: focus State #

Oh, da – vă amintiți cum am eliminat outline? Trebuie să rezolvăm :focus state din renunțarea la acest lucru.

Există o proprietate viitoare pe care am putea să o folosim, numită :focus-within, dar este totuși cel mai bine să includem un polyfill pentru aceasta la acest moment timp.

Pentru acest tutorial, vom folosi o metodă alternativă care obține același rezultat, puțin mai greu.

Din păcate, asta înseamnă că trebuie să adăugăm încă un element în DOM.

După elementul nativ de selectare, ca ultim copil din .select, adăugați:

De ce după? Deoarece, deoarece aceasta este o soluție CSS pură, plasarea acesteia după selecția nativă înseamnă că o putem modifica atunci când select este focalizat prin utilizarea selectorului de frate adiacent – +.

Acest lucru ne permite să creăm următoarea regulă:

Este posibil să vă întrebați de ce revenim la position: absolute după ce tocmai ați învățat grid-area hack anterior.

Motivul este de a evita recalcularea ajustărilor bazate pe umplutură. Dacă îl încercați singur, veți vedea că chiar și setarea width și height la 100% îl face să rămână în interiorul căptușelii .

Lucrarea position: absolute este cel mai bine potrivită cu dimensiunea unui element. Îl atragem un pixel suplimentar în fiecare direcție pentru a ne asigura că se suprapune peste margine property.

Dar, trebuie să mai facem o adăugire la .select pentru a ne asigura că este „relativ la selectarea noastră de – bine, position: relative.

Și aici personalizarea noastră selectează toate împreună așa cum se vede în Chrome:

Selectare multiplă #

Selecțiile vin într-o a doua aromă, care permite unui utilizator să selecteze mai multe opțiuni. Din perspectiva HTML, aceasta înseamnă pur și simplu adăugați atributul multiple, dar vom adăuga și o clasă pentru a ajuta la crearea ajustărilor de stil numite select--multiple :

Și uitându-ne la el, putem vedea că a moștenit favorabil majoritatea stilurilor noastre, cu excepția faptului că nu avem nevoie de săgeată în această vizualizare.

Aceasta este o soluție rapidă pentru a regla selectorul nostru care definește săgeata. Folosim :not() pentru a exclude noua noastră clasă definită:

Avem câteva ajustări minore de făcut pentru selectarea multiplă, primul eliminând căptușeala care a fost adăugată anterior pentru a face loc săgeții:

În mod implicit, opțiunile cu o valoare lungă vor depăși zona vizibilă și vor fi decupate, dar am constatat că principalele browsere permit înlocuirea înfășurării dacă doriți:

Opțional, putem seta un height pe selecție pentru a aduce un un comportament mult mai fiabil pe mai multe browsere. Testând acest lucru, am aflat că Chrome și Firefox vor afișa o opțiune parțială, dar Safari va ascunde complet o opțiune care nu poate fi vizualizată complet.

Înălțimea trebuie setată direct pe selecția nativă . Având în vedere celelalte stiluri ale noastre, valoarea 6rem va putea afișa 3 opțiuni:

În acest moment, datorită suportului actual al browserului, am făcut cât mai multe ajustări posibil.

Starea :selected din options este destul de personalizabil în Chrome, oarecum în Firefox și deloc în Safari. Consultați demonstrația CodePen pentru o secțiune care poate fi necomentată pentru a previzualiza acest lucru.

: Stiluri dezactivate #

În timp ce aș pleda pentru pur și simplu nu afișăm controale dezactivate, ar trebui să pregătim stilurile pentru acea stare doar pentru a acoperi bazele noastre.

Pentru a sublinia starea dezactivată, dorim să aplicăm un fundal gri. Dar, din moment ce „am setat stiluri de fundal pe .select și nu există un selector” ta :parent, trebuie să creăm o ultimă clasă pentru care să se ocupe această stare:

Aici am actualizat cursorul ca un indiciu suplimentar cu care câmpul nu poate fi interacționat și am actualizat valorile de fundal pe care le setam anterior la să fie alb pentru a fi acum mai gri pentru starea dezactivată.

Acest lucru are ca rezultat următoarele apariții:

Demo #

Puteți să-l testați singuri, dar aici este o previzualizare a soluției complete din (din stânga) Firefox, Chrome și Safari:

De Stephanie Eckles (@ 5t3ph)

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *