Med hjälp av Feature Detection, Villkorssatser, och Grupper med Omkopplare

0
24

CSS är utformad på ett sätt som gör det möjligt för relativt smidig tillägg av nya funktioner. Sedan början av språket, specifikationer krävs webbläsare till graciöst ignorera alla egenskaper, värderingar, selektorer, eller at-regler som de inte stöder. Följaktligen, i de flesta fall är det möjligt att framgångsrikt använda en nyare teknik utan att orsaka några problem i äldre webbläsare.

Överväga relativt ny hatt-färg egendom (det ändrar färg på markören i-ingångar). Dess stöd är fortfarande låg, men det betyder inte att vi inte ska använda det i dag.

.myInput {
färg: blå;
hatt-color: red;
}

Lägg märke till hur vi lägger det bredvid färg, en fastighet med praktiskt taget universellt webbläsare stöd, en som kommer att tillämpas överallt. I detta fall har vi inte uttryckligen diskriminerade mellan den moderna och den äldre webbläsare. Istället, vi bara förlita sig på de äldre ignorera funktioner som de inte stöder.

Det visar sig att detta mönster är kraftfull nog i de allra flesta situationer.

När du har upptäckt är nödvändigt

I vissa fall, men vi skulle verkligen vilja att använda en modern fastighet eller i fastighets värde som skiljer sig avsevärt från dess återgång. I dessa fall, @stöder kommer till undsättning.

@stöd är en särskild i-regel som tillåter oss att villkorligt gälla alla stilar i webbläsare som stöder en viss egendom och dess värde.

@stöd (display: grid) {
/* Stilar för webbläsare som har stöd grid layout… */
}

Det fungerar analogt till @media-frågor, vilket även gäller endast stilar villkorligt när ett visst predikat är uppfyllda.

För att illustrera användningen av @stöd för, tänk dig följande exempel: vi skulle vilja visa en upplagda avatar i en fin cirkel men vi kan inte garantera att den faktiska filen kommer att vara av kvadratiska dimensioner. För att objektet-fit egendom skulle vara oerhört bra, men det stöds inte av Internet Explorer (IE). Vad gör vi då?

Låt oss börja med koden:

<div class=”avatar”>
<img class=”avatar-image” src=”…” alt=”…” />
</div>

Som en inte-så-vackra fallback, vi kommer att pressa bildens bredd inom avatar till den kostnad som större filer kommer inte att helt täcka avatar området. Istället, vårt enda färg som bakgrund visas nedanför.

.avatar {
position: relative;
bredd: 5em;
höjd: 5em;
border-radius: 50%;
overflow: hidden;
bakgrund: #cccccc; /* Återgång färg */
}

.avatar-bild {
position: absolute;
topp: 50%;
rätt: 0;
bottom: 0;
vänster: 50%;
förändra: översätta(-50%, -50%);
max-width: 100%;
}

Du kan se detta beteende i aktion här:

Se Pennan Demo fallback för objekt-fit by Jirka Vebr (@JirkaVebr) på CodePen.

Lägg märke till att det är en fyrkantig bild, en bred och en och en lång en.

Nu, om vi använder objekt-fit, vi kan låta webbläsaren bestämma det bästa sättet att placera bilden, nämligen om att sträcka bredd, höjd, eller varken eller.

@stöd (objekt-fit: omslag) {
.avatar-bild {
/* För att vi inte längre behöver absolut positionering eller någon förvandlar */
position: statisk;
transform: none;
objekt-fit: omslag,
width: 100%;
höjd: 100%;
}
}

Resultatet för samma uppsättning av bildens mått, fungerar bra i moderna webbläsare:

Se Pennan @stöder objekt-fit demo av Jirka Vebr (@JirkaVebr) på CodePen.

Villkorlig väljare stöd

Även om Omkopplare Nivå 4 specifikation är fortfarande ett Utkast, några av de väljare som den definierar som platshållare-visas — är redan stöds av många webbläsare. Bör denna trend fortsätta (och bör förslaget behålla de flesta av sina nuvarande förslag), denna nivå av specifikationen kommer att presentera fler nya väljare än någon av sina föregångare. Under tiden, och även när IE är fortfarande vid liv, CSS-utvecklare kommer att rikta sig till en ännu mer mångsidig och flyktiga spektrum av webbläsare med begynnande stöd för dessa väljare.

Det kommer att vara mycket användbara för att utföra funktionen upptäckt på axlen. Tyvärr, @stöder endast är avsedd för att testa stöd av fastigheter och deras värderingar, och även de senaste utkastet av dess specifikation innebär inte att visas för att ändra på det. Ända sedan starten har det dock definierat en särskild produktion regeln i dess grammatik vars enda syfte är att ge utrymme för potentiella bakåt-kompatibla tillägg, och det är alltså fullt möjligt för en framtida version för att lägga till möjligheten att villkoret om stöd för enskilda väljare. Trots att fallen förblir helt hypotetisk.

Väljaren motsvarighet till @stöd

Först av allt, det är viktigt att understryka att, analogt med ovan nämnda hatt-färg exempel där @stöder är förmodligen inte nödvändigt, många väljare inte behöver vara explicit testas för heller. Till exempel, vi kan helt enkelt försöka att matcha ::urval och inte oroa dig för webbläsare som inte har stöd för det eftersom det inte kommer att vara slut i världen om urval utseende förblir webbläsaren som standard.

Det finns dock fall där uttrycklig har upptäckt för väljare skulle vara mycket önskvärt. I resten av den här artikeln, vi kommer att införa ett mönster för att ta itu med sådana behov och därefter använda den med :platshållare som visas för att bygga en CSS-enda alternativet till det Material Design textfält med en flytande etikett.

Grundläggande egenskap grupper av väljare

För att undvika dubbelarbete, det är möjligt att kondensera flera identiska deklarationer in en kommaseparerad lista av väljare, som kallas en grupp av selektorer.

Således kan vi slå:

.foo { color: red }
.bar { color: red }

…till:

.foo .bar { color: red }

Men som Väljare Nivå 3 specifikation varnar för att detta bara är likvärdiga eftersom alla väljare som berörs är giltigt. Enligt specifikationen, om någon av de väljare i gruppen är ogiltig, hela gruppen ignoreras. Följaktligen selektorer:

..foo { color: red } /* Observera att extra prick */
.bar { color: red }

…kunde inte vara grupperade på ett säkert sätt, som tidigare väljare är ogiltig. Om vi grupperat dem, vi skulle orsaka webbläsaren för att strunta i deklarationen för den senare.

Det är värt att påpeka att, så långt som en webbläsare är berörda, det är ingen skillnad mellan en ogiltig väljare och väljare som är endast giltig enligt en nyare version av specifikationen, eller en som läsaren inte vet. Till webbläsaren, båda är helt enkelt felaktigt.

Vi kan dra nytta av den här egenskapen för att testa för stöd av en särskild väljare. Allt vi behöver är en väljare att vi kan garantera matcher ingenting. I våra exempel kommer vi att använda :inte(*).

.foo { color: red }

:ej(*):en platshållare som visas,
.foo {
färg: grön
}

Låt oss bryta ner vad det är som händer här. En äldre webbläsare kommer att lyckas gäller den första regeln, men när den behandlar resten, det kommer att hitta den första väljaren i gruppen ogiltig eftersom den inte vet :platshållare som visas, och det kommer därmed att ignorera hela selector-gruppen. Det innebär att alla delar matchar .foo kommer att förbli röd. I motsats, medan en nyare webbläsare kommer sannolikt att rulla sin robot ögon på att stöta på :inte(*) (som aldrig matchar något) kommer det inte att kasta hela selector-gruppen. Det kommer i stället att åsidosätta den tidigare regeln, och därmed alla delar matchar .foo kommer att vara grön.

Märker likhet med @stöder (eller någon @media-query, för den delen) i termer av hur det används. Vi först ange fallback och sedan åsidosätta den webbläsare för att tillfredsställa ett predikat, som i detta fall är stödet för en viss väljare — om än skriven på ett ganska invecklat sätt.

Se Pennan @stöd för väljare genom att Jirka Vebr (@JirkaVebr) på CodePen.

Verkliga exempel

Vi kan använda den här tekniken för vår insats med en flytande etikett separat webbläsare att göra från dem som inte har stöd för :platshållare som visas, en pseudo-klass som är helt avgörande för detta exempel. För den skull relativa enkelhet, trots bästa UI praxis, att vi ska välja våra återgång till att vara bara den faktiska platshållare.

Låt oss börja med koden:

<div class=”ingång”>
<input class=”ingång-kontroll” typ=”e-post” name=”email” platshållare=”E-post” id=”e-post” – krävs />
<etiketten class=”ingångs-etikett” för=”e-post”>E-post</label>
</div>

Som tidigare, det viktiga är att först lägga till stilar för äldre webbläsare. Vi dölja etikett och sätt färg på den platshållare.

.input {
höjd: 3.2 em;
position: relative;
display: flex;
align-objekt: center;
font-size: 1em;
}

.ingång-kontroll {
flex: 1;
z-index: 2; /* Så att det alltid är “över” den etikett */
border: none;
padding: 0 0 0 1em;
background: transparent;
position: relative;
}

.input-label {
position: absolute;
topp: 50%;
rätt: 0;
bottom: 0;
left: 1em; /* Justera detta med kontroll utfyllnad */
z-index: 1;
display: none; /* Dölja detta för gammal webbläsare */
förvandla-ursprung: top left;
text-align: left;
}

För moderna webbläsare, som vi effektivt kan inaktivera den platshållare genom att sätta sin färg till transparent. Vi kan också justera input och etikett i förhållande till ett annat för när platshållare visas. För detta ändamål, kan vi också använda syskon selector för att styla etiketten med hänsyn till den aktuella ingången.

.ingång-kontroll:en platshållare som visas::platshållare {
färg: transparent;
}

.ingång-kontroll:en platshållare som visas ~ .input-label {
förändra: translateY(-50%)
}

.ingång-kontroll:en platshållare som visas {
förändra: translateY(0);
}

Slutligen susen! Precis som ovan, vi åsidosätta stilar för etiketten och ingång för en modern webbläsare, och den stat där den platshållare visas inte. Det innebär att man går etiketten ur vägen och krymper den lite.

:ej(*):en platshållare som visas,
.input-label {
display: block;
förändra: translateY(-70%) skala(.7);

}
:ej(*):en platshållare som visas,
.ingång-kontroll {
förändra: translateY(35 procent).
}

Med alla bitar tillsammans, samt fler stilar och alternativ för konfiguration som är ortogonal till detta exempel kan du se den i full demo:

Se Pennan CSS-only @stöd för selector demo av Jirka Vebr (@JirkaVebr) på CodePen.

Tillförlitlighet och begränsningar av denna teknik

I grunden är denna teknik kräver en väljare som matchar ingenting. För detta ändamål har vi använt :inte(*); men dess stöd är också begränsad. Universal-väljaren * stöds även av IE 7, medan den :inte pseudo-klass har endast genomförts eftersom IE 9, vilket är därmed det äldsta webbläsare där denna metod fungerar. Äldre webbläsare skulle förkasta våra väljare grupper av fel anledning — de har inte stöd för :inte! Vi skulle även kunna använda en klass som väljare till exempel .foo eller en typ av väljare som foo, och därigenom stödja även de mest gammal webbläsare. Dock kommer dessa att koden blir mindre läsbar som de inte förmedla att de aldrig bör matcha vad som helst, och därmed för de flesta moderna webbplatser :inte(*) verkar som det bästa alternativet.

För oavsett om den egendom grupper av väljare att vi har tagit tillvara håller även i äldre webbläsare, beteende illustreras i ett exempel som en del av CSS 1 avsnitt på fram-kompatibla tolkning. Dessutom, CSS 2.1 specifikation sedan explicit mandat för detta beteende. Att sätta en ålder av denna specifikation i perspektiv, detta är något som infördes :hover. Kort sagt, även om denna teknik har inte testats i den äldsta eller mest obskyra webbläsare, dess stöd bör vara mycket stort.

Slutligen finns det en liten varning för Sass användare (Sass, inte SCSS): när du stöter på den :inte(*):en platshållare som visas i väljaren för kompilatorn blir lurad av de ledande kolon, försök att tolka det som en egendom, och när de stöter på den fel, ger råd till byggherren att fly väljare som så: :inte(*):en platshållare som visas, som inte ser mycket trevlig. En bättre lösning är kanske att ersätta det omvända snedstrecket med ännu en universell selector för att få *:inte(*):en platshållare som visas eftersom, enligt den specifikation, är det underförstådda i alla fall i detta fall.