Custom Select-stilarter med ren CSS

Dette er afsnit nr. 20 i en serie, der undersøger moderne CSS-løsninger på problemer, jeg har løst i løbet af de sidste 13 år med at være frontend-udvikler.

Moderne CSS giver os en række egenskaber for at opnå brugerdefinerede valgstile, der har næsten identiske indledende udseende for enkelt-, flere og deaktiverede select -elementer i de øverste browsere.

Et par egenskaber og teknikker, som vores løsning vil bruge:

  • clip-path for at oprette den brugerdefinerede dropdown-pil
  • CSS-gitterlayout for at justere de oprindelige select- og pil
  • tilpassede CSS-variabler til fleksibel styling
  • em enheder til relativ størrelse

Almindelige problemer med indfødte markeringer #

Som med alle formularfelttyper varierer <select> på tværs af browsere i dets oprindelige udseende.

Fra venstre mod højre er her det første udseende for <select> i Firefox, Chrome og Safari:

Forskellene inkluderer boksstørrelse, skriftstørrelse, linjehøjde, og mest standout er forskellen i, hvordan rullemenuen er stylet.

Vores Målet er at skabe det samme indledende udseende på tværs af disse browsere, inklusive flere valg og deaktiverede tilstande.

Bemærk: Dropdown-listen er stadig ikke stilbar, så når <select> er åbnet, vil den stadig hente de individuelle browserstile til option -listen. Dette er ok – vi kan håndtere det for at bevare den gratis tilgængelighed af en native select!

Base HTML #

We ” Jeg vil fokusere på en enkelt <select> til at begynde.

Etiketten er ikke en del af vores stylingøvelse, men den er inkluderet som et generelt krav, især med for -attribut med værdien af id<select>.

For at udføre vores brugerdefinerede stilarter har vi “pakket det oprindelige valg i en ekstra div med klassen select for at gøre det nemmere i denne selvstudie.

Nulstil og fjern arvede stilarter #

Som inkluderet i alle mine tutorials som en moderne bedste praksis, tilføjer vi følgende nulstilling først:

Herefter, vi kan begynde reglen for den indfødte select og anvende følgende for at hvile sit udseende:

Selvom de fleste af dem sandsynligvis er velkendte, er oddball out . Dette er en sjældent anvendt egenskab, og du vil bemærke, at det ikke er helt, hvor vi vil have det til support, men hvad det primært giver os i dette tilfælde, er fjernelsen af den oprindelige browsers rullemenu.

Bemærk: CodePen er indstillet til at bruge autoprefixer, som tilføjer nødvendige forudbestemte versioner af egenskaben appearance. Du skal muligvis specifikt konfigurere dette til dit projekt eller tilføje dem manuelt. Min HTML / Sass Jumpstart inkluderer autoprefixer som en del af produktionsbygningen.

Den gode nyhed er, at vi kan tilføje endnu en regel for at fjerne pilen til lavere IE-versioner, hvis du har brug for det:

Dette tip findes i fremragende artikel fra Filament Group, der viser en alternativ metode til at oprette valgte stilarter.

Den sidste del er at fjerne standard outline. Vær ikke bekymret – vi ” Jeg tilføjer en erstatning senere for :focus tilstand!

Og her er en gif af vores fremskridt. Du kan se, at der nu er nul visuel indikation af, at dette er en select før du klikker på den:

Custom Select Box Styles #

Lad os først oprette nogle CSS-variabler. Dette gør det muligt for vores valg at blive fleksibelt omfarvet for at repræsentere en fejltilstand.

Bemærk om tilgængelighed: Som brugergrænsefladeelement skal den valgte kant have en kontrast på 3: 1 eller større mod den omgivende overfladefarve.

Nu er det tid til at oprette de brugerdefinerede valgstile, som vi vil anvende til vores indpakning div.select:

Først oprettede vi nogle bredde begrænsninger. min-width og max-width værdierne er for det meste til denne demo, og du kan vælge at droppe eller ændre den til din brugssag.

Så anvender vi nogle boksmodelegenskaber, herunder border, border-radius og padding. Bemærk brugen af em -enheden, som holder disse egenskaber proportionale med sættet font-size.

I reset-typografierne indstiller vi flere egenskaber til inherit, så her definerer vi dem, inklusive font-size, cursor og line-height.

Endelig leverer vi det baggrundsegenskaber, inklusive en gradient for den mindste bit af dimension. Hvis du fjerner baggrundsegenskaberne, vil markeringen være gennemsigtig og samle sidebaggrunden op. Dette kan være ønskeligt, men vær opmærksom på og test virkningerne på kontrasten.

Og her er vores fremskridt:

Custom Vælg Dropdown Pil #

For vores dropdown-pil skal vi bruge en af de mest spændende moderne CSS-egenskaber: clip-path.

Klipstier giver os mulighed for at lave alle former for former ved at “klippe” de ellers firkantede og rektangulære figurer, som vi modtager som standardindstillinger fra de fleste elementer. Jeg havde det sjovt med at bruge clip-path på mit nylige redesign af porteføljesiden.

Før clip-path har bedre support, inkluderede alternative metoder:

  • background-image – typisk en png, lidt mere moderne ville være en SVG
  • en inline SVG som et yderligere element
  • grænsetricket for at oprette en trekant

SVG kan føles som den optimale løsning, men når det bruges som et background-image mister det evnen til at fungere som et ikon i den forstand, at det ikke er i stand til at o ændre dens egenskaber såsom fyldfarve uden at omdefinere den helt. Dette betyder, at vi ikke kan bruge vores tilpassede CSS-variabel.

Placering af en SVG inline løser fill farveproblemet, men det betyder at inkludere et element mere hver gang en <select> er defineret.

Med clip-path får vi en skarp, skalerbar pil “grafik”, der føles som en SVG, men med fordelene ved at kunne bruge vores brugerdefinerede variabel og være indeholdt i typografien vs. HTML-markeringen.

For at oprette pilen definerer vi den som en ::after pseudo-element.

clip-path syntaksen er lidt underlig, og da den “s ikke rigtig fokus for denne artikel, jeg anbefaler følgende ressourcer:

  • Colby Fayock uddyber syntaksen med et eksempel i denne egghead-video
  • Clippy er et onlineværktøj, der tillader dig til at vælge en figur og justere punkterne mens du dynamisk genererer clip-path CSS

Hvis du følger fløj langs, har du måske bemærket, at pilen ikke vises på trods af, at du definerer width og height. Når det blev inspiceret, fandt det, at ::after faktisk ikke får tilladelse til dets bredde.

Vi løser dette ved at opdatere vores .select for at bruge CSS-gitterlayout.

Dette lader pilen vises ved i det væsentlige at udvide den til en visningsværdi svarende til “blok”.

På dette tidspunkt kan vi kontrollere, at vi virkelig har oprettet en trekant.

For at rette opretningen, vi bruger mit foretrukne CSS-gitterhack (gammel hat til dig, hvis du har læst et par artikler her!).

Gammel CSS-løsning: position: absolute Ny CSS-løsning: En enkelt grid-template-areas til at indeholde dem alle

Først definerer vi vores område og definer derefter, at select og ::after bruger begge det. Navnet er afgrænset til det element, det er oprettet til, og vi “holder det let ved at kalde det” vælg “:

Hvilket giver os en overlapning af pilen over det oprindelige valg på grund af stabling af kontekst via kildeordre:

Vi kan nu bruge gitteregenskaber til at færdiggøre justeringen af hvert element:

Ta-da!

: fokus tilstand #

Åh ja – husk hvordan vi fjernede outline? Vi er nødt til at løse den manglende :focus tilstand fra at droppe det.

Der er en kommende ejendom, vi kan bruge, kaldet :focus-within, men det er stadig bedst at inkludere en polyfyld til det på dette tid.

I denne vejledning bruger vi en alternativ metode, der opnår det samme resultat, bare lidt kraftigere.

Desværre betyder det, at vi er nødt til at tilføje endnu et element i DOM.

Efter det oprindelige valgelement, som det sidste barn inden for .select, tilføj:

Hvorfor efter? Fordi da dette er en ren CSS-løsning, betyder det at placere den efter den oprindelige vælger, at vi kan ændre den, når select fokuseres ved hjælp af den tilstødende søskendevælger – +.

Dette giver os mulighed for at oprette følgende regel:

Du undrer dig måske over, hvorfor vi” vender tilbage til position: absolute efter bare at have lært det forrige grid-area hack.

Årsagen er at undgå genberegning af justeringer baseret på polstring. Hvis du prøver det alene, vil du se, at selv indstilling af width og height til 100% stadig får det til at sidde indenfor polstringen .

Jobbet position: absolute passer bedst til at matche størrelsen på et element. Vi trækker det en ekstra pixel i hver retning for at sikre, at det overlapper grænsen egenskab.

Men vi er nødt til at tilføje endnu en til .select for at sikre, at det er i forhold til vores valg af – ja, position: relative.

Og her vælger vores brugerdefinerede alt sammen som set i Chrome:

Multiple Select #

Selects kommer i en anden smag, som giver brugeren mulighed for at vælge mere end en mulighed. Fra HTML-perspektivet betyder dette simpelthen tilføj multiple -attributten, men vi tilføjer også en klasse for at hjælpe med at skabe stiljusteringer kaldet select--multiple :

Og når vi ser på det, kan vi se, at det arvede de fleste af vores stilarter positivt, bortset fra at vi ikke har brug for pilen i denne visning.

Dette er en hurtig løsning til at justere vores vælger, der definerer pilen. Vi bruger :not() til at udelukke vores nyligt definerede klasse:

Vi har et par mindre justeringer, der skal foretages for multiple select, den første fjerner polstring, der tidligere blev tilføjet for at give plads til pilen:

Som standard vil indstillinger med en lang værdi overløbe det synlige område og blive klippet, men jeg fandt ud af, at de vigtigste browsere tillader indpakning at blive tilsidesat, hvis du ønsker:

Valgfrit kan vi indstille en height på markøren for at bringe en lidt mere pålidelig adfærd på tværs af browsere. Ved at teste dette lærte jeg, at Chrome og Firefox viser en delvis mulighed, men Safari skjuler en mulighed helt, der ikke er i stand til at være fuldt synlig.

Højden skal indstilles direkte på den oprindelige vælger . I betragtning af vores andre stilarter vil værdien 6rem kunne vise 3 muligheder:

På dette tidspunkt, på grund af den aktuelle browsersupport har vi foretaget så mange justeringer, som vi er i stand.

:selected af options er ret tilpasselig i Chrome, noget i Firefox og slet ikke i Safari. Se CodePen-demoen for et afsnit, der ikke kan kommenteres for at få vist dette eksempel.

: deaktiverede stilarter #

Mens jeg vil tale for simpelthen ikke viser deaktiverede kontroller, vi skal forberede typografierne for den tilstand bare for at dække vores baser.

For at fremhæve den deaktiverede tilstand ønsker vi at anvende en grå baggrund. Men da vi “har indstillet baggrundsformater til .select, og der ikke er en” ta :parent -vælger, er vi nødt til at oprette en sidste klasse til at håndtere denne tilstand:

Her har vi opdateret markøren som et ekstra tip til, at feltet ikke kan interageres med, og opdateret de baggrundsværdier, vi tidligere har indstillet til være hvid for nu at være mere grå for den deaktiverede tilstand.

Dette resulterer i følgende optrædener:

Demo #

Du kan teste det selv, men her er et eksempel på den fulde løsning over (fra venstre) Firefox, Chrome og Safari:

Af Stephanie Eckles (@ 5t3ph)

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *