Aangepaste geselecteerde stijlen met pure CSS

Dit is aflevering 20 in een serie waarin moderne CSS-oplossingen worden onderzocht voor problemen die ik heb opgelost in de afgelopen 13+ jaar als frontend-ontwikkelaar.

Moderne CSS geeft ons een reeks eigenschappen om aangepaste geselecteerde stijlen te realiseren die een bijna identieke eerste weergave voor enkele, meervoudige en uitgeschakelde select -elementen in de topbrowsers.

Een paar eigenschappen en technieken die onze oplossing zal gebruiken:

  • clip-path om de aangepaste vervolgkeuzepijl te maken
  • CSS-rasterlay-out om de native selectie en pijl uit te lijnen
  • aangepaste CSS-variabelen voor flexibele vormgeving
  • em eenheden voor relatieve afmetingen

Veelvoorkomende problemen met Native Selects #

Zoals met alle formulierveldtypen, varieert <select> van browser tot aanvankelijk.

Van links naar rechts, hier is de eerste weergave voor <select> in Firefox, Chrome en Safari:

De verschillen zijn onder meer de grootte van het kader, de lettergrootte, de regelhoogte en het meest opvallende is het verschil in de stijl van de vervolgkeuzelijst.

Onze Het doel is om in deze browsers dezelfde oorspronkelijke weergave te creëren, inclusief meerdere selecties en uitgeschakelde statussen.

Opmerking: de vervolgkeuzelijst is nog steeds niet opmaakbaar, dus zodra de <select> is geopend, zal het nog steeds de individuele browserstijlen ophalen voor de option lijst. Dit is oké – we kunnen hiermee omgaan om de gratis toegankelijkheid van een native select te behouden!

Base HTML #

Wij ” Ik zal me concentreren op een enkele <select> om te beginnen.

Het label maakt geen deel uit van onze stylingoefening, maar is opgenomen als een algemene vereiste, met name bij de for attribuut met de waarde van id op de <select>.

Om onze aangepaste stijlen te bereiken, hebben we de native selectie in een extra div verpakt met de klasse select voor het gemak in deze tutorial.

Overgenomen stijlen resetten en verwijderen #

Zoals in al mijn tutorials is opgenomen als een moderne best practice, voegen we eerst de volgende reset toe:

Daarna, we kunnen beginnen met de regel voor de native select en het volgende toepassen om het uiterlijk ervan te laten rusten:

Hoewel de meeste waarschijnlijk bekend zijn, is de vreemde eend in de bijt . Dit is een eigenschap die niet vaak wordt gebruikt en u zult opmerken dat het niet helemaal is waar we het voor ondersteuning zouden willen, maar wat het ons in dit geval voornamelijk verschaft, is het verwijderen van de dropdown-pijl van de native browser.

Opmerking: de CodePen is ingesteld om autoprefixer te gebruiken die vereiste vooraf vaste versies van de appearance eigenschap zal toevoegen. Mogelijk moet u dit specifiek voor uw project instellen of ze handmatig toevoegen. Mijn HTML / Sass Jumpstart bevat autoprefixer als onderdeel van de productie-build.

Het goede nieuws is dat we nog een regel kunnen toevoegen om de pijl te verwijderen voor lagere IE-versies als dat nodig is:

Deze tip vind je in de uitstekend artikel van Filament Group dat een alternatieve methode toont om geselecteerde stijlen te maken.

Het laatste deel is het verwijderen van de standaard outline. Maak je geen zorgen – wij ” Ik zal later een vervanging toevoegen voor de :focus state!

En hier is een gif van onze voortgang. U kunt zien dat er nu geen visuele indicatie is dat dit een select is voordat u erop klikt:

Aangepaste selectievakstijlen #

Laten we eerst wat CSS-variabelen instellen. Hierdoor kan onze selectie flexibel opnieuw worden gekleurd om een foutstatus weer te geven.

Opmerking voor toegankelijkheid: als gebruikersinterface-element moet de geselecteerde rand een contrast van 3: 1 hebben of groter ten opzichte van de omringende oppervlaktekleur.

Nu is het tijd om de aangepaste geselecteerde stijlen te maken die we zullen toepassen op onze omloop div.select:

Eerst hebben we enkele breedte-beperkingen ingesteld. De min-width en max-width waarden zijn voornamelijk voor deze demo, en u kunt ervoor kiezen om deze te verwijderen of te wijzigen voor uw specifieke situatie.

Vervolgens passen we enkele boxmodeleigenschappen toe, waaronder border, border-radius en padding. Let op het gebruik van de em eenheid die deze eigenschappen proportioneel houdt met de set font-size.

In de reset-stijlen hebben we verschillende eigenschappen ingesteld op inherit, dus hier definiëren we die, inclusief font-size, cursor, en line-height.

Ten slotte leveren we achtergrondeigenschappen, inclusief een verloop voor het kleinste beetje dimensie. Als u de achtergrondeigenschappen verwijdert, wordt de selectie transparant en wordt de pagina-achtergrond opgehaald. Dit kan wenselijk zijn, maar wees u bewust en test de effecten op het contrast.

En hier is onze vooruitgang:

Aangepast Selecteer dropdown-pijl #

Voor onze dropdown-pijl gebruiken we een van de meest opwindende moderne CSS-eigenschappen: clip-path.

Met clippaden kunnen we allerlei vormen maken door de anders vierkante en rechthoekige vormen die we standaard van de meeste elementen ontvangen, te “knippen”. Ik had plezier met het gebruik van clip-path bij mijn recente herontwerp van de portfoliosite.

Voordat clip-path betere ondersteuning kreeg, waren er alternatieve methoden inbegrepen:

  • background-image – typisch een png, iets moderner zou een SVG zijn
  • een inline SVG als een extra element
  • de randtruc om een driehoek te maken

SVG kan aanvoelen als de optimale oplossing, maar wanneer het wordt gebruikt als een background-image, verliest het de mogelijkheid om zich als een pictogram te gedragen in de zin dat het niet o de eigenschappen ervan, zoals de vulkleur, wijzigen zonder deze volledig opnieuw te definiëren. Dit betekent dat we onze aangepaste CSS-variabele niet kunnen gebruiken.

Het inline plaatsen van een SVG lost het fill kleurprobleem op, maar het betekent dat er telkens een extra element moet worden toegevoegd als een <select> is gedefinieerd.

Met clip-path krijgen we een scherpe, schaalbare pijl “graphic” die aanvoelt als een SVG, maar met de voordelen dat we onze aangepaste variabele kunnen gebruiken en opgenomen zijn in de stijl versus de HTML-opmaak.

Om de pijl te maken, zullen we deze definiëren als een ::after pseudo-element.

De clip-path syntaxis is een beetje vreemd, en aangezien het niet echt de focus van dit artikel, ik raad de volgende bronnen aan:

  • Colby Fayock geeft een toelichting op de syntaxis met een voorbeeld in deze egghead-video
  • Clippy is een online tool waarmee u om een vorm te selecteren en de punten aan te passen terwijl u dynamisch de clip-path CSS

genereert als u “volgt Als je mee vliegt, heb je misschien gemerkt dat de pijl niet verschijnt ondanks het definiëren van width en height. Bij inspectie bleek dat de ::after de breedte niet is toegestaan.

We lossen dit op door onze .select om de CSS-rasterlay-out te gebruiken.

Dit laat de pijl verschijnen door deze in wezen uit te breiden tot een weergavewaarde die lijkt op “block”.

In dit stadium kunnen we verifiëren dat we inderdaad een driehoek hebben gemaakt.

Om de uitlijning te corrigeren, we “zullen mijn favoriete CSS-grid-hack gebruiken (oude hoed voor jou als je” hier een paar artikelen hebt gelezen!).

Oude CSS-oplossing: position: absolute Nieuwe CSS-oplossing: een enkele grid-template-areas om ze allemaal te bevatten

Eerst “zullen we ons gebied definiëren en dan definiëren dat de select en de ::after gebruiken het beide. De naam wordt bepaald door het element waarvoor het is gemaakt, en we “houden het gemakkelijk door het” select “te noemen:

Wat ons een overlap geeft van de pijl boven de native selecteer vanwege stapelcontext via bronvolgorde:

We kunnen nu rastereigenschappen gebruiken om de uitlijning af te ronden van elk element:

Ta-da!

: focus State #

Oh ja – onthoud hoe we de outline hebben verwijderd? We moeten de ontbrekende :focus staat om dat te laten vallen.

Er is een aankomende eigenschap die we zouden kunnen gebruiken genaamd :focus-within, maar het is nog steeds het beste om hier een polyfill voor op te nemen tijd.

Voor deze tutorial zullen we een alternatieve methode gebruiken die hetzelfde resultaat oplevert, maar een beetje zwaarder.

Helaas betekent dit dat we nog een element moeten toevoegen aan de DOM.

Na het native select-element, als het laatste kind binnen .select, voeg toe:

Waarom daarna? Omdat dit een pure CSS-oplossing is, betekent het plaatsen na de native select dat we deze kunnen wijzigen wanneer de select wordt gefocust door de aangrenzende selector op hetzelfde niveau te gebruiken – +.

Dit stelt ons in staat om de volgende regel te creëren:

Je vraagt je misschien af waarom we” terug zijn bij position: absolute na het leren van de vorige grid-area hack.

De reden is om aanpassingen op basis van opvulling niet opnieuw te berekenen. Als je het zelf probeert, zul je zien dat zelfs als je width en height instelt op 100%, het nog steeds binnen de opvulling blijft .

De taak position: absolute doet het het beste door de grootte van een element aan te passen. We trekken er een extra pixel aan in elke richting om ervoor te zorgen dat het de rand overlapt eigenschap.

Maar we moeten nog een toevoeging maken aan .select om er zeker van te zijn dat het relatief is aan onze selectie door – nou, position: relative.

En hier is onze aangepaste selectie allemaal zoals te zien in Chrome:

Multiple Select #

Selects komen in een tweede variant, die een gebruiker in staat stelt om meer dan één optie te selecteren. Vanuit HTML-perspectief betekent dit eenvoudigweg het multiple -attribuut toevoegen, maar we “zullen ook een klasse toevoegen om te helpen bij het maken van stijlaanpassingen, genaamd select--multiple :

En als we ernaar kijken, zien we dat de meeste van onze stijlen gunstig zijn geërfd, behalve dat we de pijl in deze weergave niet nodig hebben.

Dit is een snelle oplossing om onze selector aan te passen die de pijl definieert. We gebruiken :not() om onze nieuw gedefinieerde klasse uit te sluiten:

We moeten een paar kleine aanpassingen maken voor de meervoudige selectie, de eerste is het verwijderen van opvulling die eerder was toegevoegd om ruimte te maken voor de pijl:

Standaard zullen opties met een lange waarde het zichtbare gebied overlopen en worden afgekapt, maar ik ontdekte dat de hoofdbrowsers toestaan dat de wrapping wordt overschreven als je dat wilt:

Optioneel kunnen we een height op de select zetten om een iets betrouwbaarder cross-browser gedrag. Door dit te testen, heb ik geleerd dat Chrome en Firefox een gedeeltelijke optie zullen tonen, maar Safari zal een optie volledig verbergen die niet volledig zichtbaar is.

De hoogte moet rechtstreeks op de native select worden ingesteld. . Gezien onze andere stijlen, kan de waarde 6rem 3 opties weergeven:

Op dit punt, dankzij de huidige browserondersteuning hebben we zo veel mogelijk aanpassingen gemaakt.

De :selected status van de options is redelijk aanpasbaar in Chrome, enigszins in Firefox, en helemaal niet in Safari. Zie de CodePen-demo voor een sectie die niet kan worden becommentarieerd om een voorbeeld hiervan te bekijken.

: disabled Styles #

Hoewel ik zou pleiten voor eenvoudigweg geen uitgeschakelde besturingselementen laten zien, we zouden de stijlen voor die toestand moeten voorbereiden om onze bases te dekken.

Om de uitgeschakelde toestand te benadrukken, willen we een grijze achtergrond toepassen. Maar aangezien we “achtergrondstijlen hebben ingesteld op .select en er geen” ta :parent selector is, moeten we nog een laatste klasse maken voor deze toestand:

Hier hebben we “de cursor bijgewerkt als een extra hint dat er geen interactie met het veld kan plaatsvinden, en de achtergrondwaarden bijgewerkt die we eerder hadden ingesteld op wees wit om nu meer grijs te zijn voor de uitgeschakelde staat.

Dit resulteert in de volgende verschijningen:

Demo #

Je kunt het zelf testen, maar hier is een voorbeeld van de volledige oplossing tegenover (van links) Firefox, Chrome en Safari:

Door Stephanie Eckles (@ 5t3ph)

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *