Met behulp van de Functie Detectie, Conditionals, en Groepen met Selectors

0
28

CSS is ontworpen op een manier die het mogelijk maakt voor relatief naadloze toevoeging van nieuwe functies. Sinds de dageraad van de taal, specificaties nodig browsers om sierlijk negeren eigenschappen, waarden, selectors, of regels die ze niet ondersteunen. Bijgevolg, in de meeste gevallen is het mogelijk om met succes gebruik een nieuwere technologie, zonder dat eventuele problemen in oudere browsers.

Overweeg de relatief nieuwe caret-color eigenschap (het verandert de kleur van de cursor in-ingangen). De ondersteuning is nog steeds laag, maar dat betekent niet dat we niet moeten gebruiken vandaag.

.myInput {
kleur: blue;
caret-color: red;
}

Merk op hoe we deze direct naast de kleur, een woning met een bijna universele steun van de browser; een die zal worden overal toegepast. In dit geval hebben we niet expliciet wordt gediscrimineerd tussen moderne en oudere browsers. In plaats daarvan hebben we gewoon vertrouwen op de oudere negeren van eigenschappen die ze niet ondersteunen.

Het blijkt dat dit patroon is krachtig genoeg in de overgrote meerderheid van de situaties.

Wanneer de functie is detectie nodig

In sommige gevallen, echter, wij zouden heel graag gebruiken in een modern pand of woning waarde, waarvan het gebruik verschilt aanzienlijk van de fallback. In die gevallen, @ondersteunt komt tot de redding.

@ondersteunt is een speciale op-regel die stelt ons in staat om voorwaardelijk toepassen van stijlen in browsers die ondersteuning bieden voor een specifieke eigenschap en haar waarde.

@ondersteunt (display: grid) {
/* Stijlen voor browsers die het ondersteunen grid lay-out… */
}

Het werkt analoog aan de @media queries, die ook alleen van toepassing stijlen voorwaardelijk wanneer een bepaalde predicaat is voldaan.

Ter illustratie van het gebruik van @ondersteunt, beschouw het volgende voorbeeld: we willen graag voor het weergeven van een gebruiker geüploade avatar in een mooie cirkel, maar we kunnen niet garanderen dat de werkelijke bestand van vierkante afmetingen. Voor de object-fit eigenschap zou enorm handig zijn, echter, het wordt niet ondersteund door Internet Explorer (IE). Wat doen we dan?

Laat ons beginnen met opmaak:

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

Als een niet-zo-mooie terugval, we knijpen de breedte van de afbeelding binnen de avatar in de kosten die breder zullen de bestanden niet volledig te dekken van de avatar gebied. In plaats daarvan, onze single-kleur achtergrond tevoorschijn.

.avatar {
position: relative;
width: 5em;
hoogte: 5em;
border-radius: 50%;
overflow: hidden;
background: #cccccc; /* Fallback kleur */
}

.avatar-afbeelding {
position: absolute;
top: 50%;
rechts: 0;
bottom: 0;
left: 50%;
transformeren: translate(-50%, -50%);
max-width: 100%;
}

U kunt dit gedrag zien in de actie hier:

Zie de Pen Demo fallback voor object-fit door Jirka Vebr (@JirkaVebr) op CodePen.

Merk op dat er een vierkante afbeelding, een brede en een lange.

Nu, als we gebruik maken van de object-fit, kunnen we de browser beslissen over de beste manier om de positie van het beeld, namelijk of de stretch in de breedte, in de hoogte, of geen van beide.

@ondersteunt (object-fit: cover) {
.avatar-afbeelding {
/* We hoeven niet langer absolute positionering of een transformeert */
position: static;
transform: none;
object-fit: cover;
breedte: 100%;
height: 100%;
}
}

Het resultaat, voor dezelfde set van de afmetingen van het beeld, werkt goed in moderne browsers:

Zie de Pen @ondersteunt object-fit demo door Jirka Vebr (@JirkaVebr) op CodePen.

Voorwaardelijke selector ondersteuning

Hoewel de Selectors Level 4 specificatie is nog steeds een Werkende Ontwerp, sommige van deze schakelaars het definieert, zoals :tijdelijke aanduiding weergegeven — worden al ondersteund door veel browsers. Mocht deze trend blijven (en moet het ontwerp behouden de meeste van de huidige voorstellen), dit niveau van de specificatie zal het introduceren van meer nieuwe kiezers dan elk van zijn voorgangers. In de tussentijd, en ook terwijl IE nog leeft, CSS ontwikkelaars hebben tot doel een nog meer gevarieerde en vluchtige spectrum van browsers met beginnende ondersteuning voor deze kiezers.

Het zal zeer nuttig zijn voor het uitvoeren van de functie detectie op kiezers. Helaas, @ondersteunt is alleen ontworpen voor het testen van de ondersteuning van eigenschappen en hun waarden, en zelfs de nieuwste ontwerp van de specificatie niet wordt weergegeven om dat te veranderen. Sinds haar oprichting, heeft echter vastgesteld dat er een speciale productie regel in de grammatica van wiens enige doel het is om de ruimte geven voor potentiële backwards-compatible extensions, en het is dus perfect mogelijk voor een toekomstige versie toe te voegen, de mogelijkheid om de conditie op steun voor bepaalde keuzemogelijkheden. Desondanks is het mogelijk dat geval blijft volledig hypothetisch.

Kiezen tegenhanger van @ondersteunt

Eerste van alles, het is belangrijk om te benadrukken dat, analoog aan de eerder genoemde caret-kleur voorbeeld waar @ondersteunt is waarschijnlijk niet nodig, veel kiezers hoeft niet expliciet te worden getest. Bijvoorbeeld, we kunnen het gewoon proberen aan te passen ::selectie en niet zorgen te maken over browsers die het niet ondersteunen, omdat het niet het einde van de wereld als de selectie van de verschijning blijft de browser standaard.

Toch zijn er gevallen waarin een expliciete functie van detectie voor kiezers zou zeer wenselijk. In de rest van dit artikel introduceren we een patroon voor de aanpak van dergelijke behoeften en vervolgens te gebruiken met :aanduiding-voor het bouwen van een CSS-enige alternatief is voor het Ontwerp van het Materiaal tekstveld met een variabele label.

Fundamentele eigenschap groepen van kiezers

Om dubbel werk te voorkomen, is het mogelijk om te condenseren meerdere identieke verklaringen in een door komma ‘ s gescheiden lijst van kiezers, die wordt aangeduid als de groep van kiezers.

Dus we kunnen zetten:

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

…in:

.foo, .bar { color: red }

Echter, als de Kiezers Niveau 3 specificatie waarschuwt, deze zijn gelijk vanwege alle kiezers die betrokken zijn geldig. Volgens de specificatie, als een van de keuzemogelijkheden in de groep is ongeldig is, wordt de hele groep wordt genegeerd. Bijgevolg, de selectors:

..foo { color: red } /* Let op de extra dot */
.bar { color: red }

…niet veilig kunnen worden gegroepeerd, zoals de voormalige selector is ongeldig. Als we gegroepeerd, kunnen we ertoe zou leiden dat de browser negeert de verklaring voor het laatste.

Het is de moeite waard erop te wijzen dat, voor zover een browser is betrokken, is er geen verschil tussen een ongeldige selector en een selector is alleen geldig als per een nieuwere versie van de specificatie, of dat de browser niet weten. Naar de browser, beide zijn gewoon ongeldig.

We kunnen profiteren van deze eigenschap om te testen voor de ondersteuning van een bepaalde keuzemogelijkheid. Alles wat we nodig hebben is een keuzemogelijkheid, dat wij kunnen garanderen wedstrijden niets. In onze voorbeelden gebruiken we :geen(*).

.foo { color: red }

:geen(*):aanduiding vertoond,
.foo {
kleur: groen
}

Laat ons breken wat hier gebeurt. Een oudere browser succesvol toepassen van de eerste regel, maar bij het verwerken van de rest, zal het vinden van de eerste kiezen in de groep ongeldig, omdat het niet weet :een tijdelijke aanduiding weergegeven, en dus negeert de hele selector groep. Bijgevolg worden alle elementen met elkaar overeenkomen .foo blijft rood. In tegenstelling, terwijl een nieuwere browser zal waarschijnlijk roll zijn robot-ogen op de ontmoeting :geen(*) (die nooit overeenkomt met iets) zal het niet gooi het hele selector groep. In plaats daarvan, zal het overschrijven van de vorige regel, en dus ook alle elementen met elkaar overeenkomen .foo groen.

Let op de gelijkenis met @ondersteunt (of een @media-query, voor die kwestie) in termen van hoe het wordt gebruikt. We hebben eerst geef de fallback en dan voorrang voor browsers die voldoen aan een predicaat, die in dit geval is de steun voor een bepaalde selector — zij het geschreven in een wat ingewikkelde manier.

Zie de Pen @ondersteunt voor selectors door Jirka Vebr (@JirkaVebr) op CodePen.

Real-world voorbeeld

We kunnen gebruik maken van deze techniek voor onze ingang met een variabele label te scheiden browsers die van degenen die geen ondersteuning bieden :een tijdelijke aanduiding weergegeven, een pseudo-class dat is van essentieel belang voor dit voorbeeld. Omwille van de relatieve eenvoud, in weerwil van het beste UI praktijken, kiezen wij voor onze fallback worden alleen de werkelijke tijdelijke aanduiding.

Laat ons beginnen met opmaak:

<div class=”input”>
<input class=”input-control” type=”email” name=”email” placeholder=”Email” id=”email” “noodzakelijk” / >
<label class=”input-label for=”email”>e-Mail</label>
</div>

Net als voorheen, de sleutel is om eerst het toevoegen van stijlen voor oudere browsers. We verbergen de label en stel de kleur in van de tijdelijke aanduiding.

.input {
hoogte: 3.2 em;
position: relative;
display: flex;
lijn-items: center;
font-size: 1em;
}

.input-regelaar {
flex: 1;
z-index: 2; /* het is altijd “boven” de label */
border: none;
padding: 0 0 0 1em;
achtergrond: transparant;
position: relative;
}

.input-label {
position: absolute;
top: 50%;
rechts: 0;
bottom: 0;
left: 1em; /* Lijn met de control padding */
z-index: 1;
display: none; /* Verbergen voor oude browsers */
transform-herkomst: top left;
text-align: left;
}

Voor moderne browsers, kunnen we effectief uitschakelen van de aanduiding door het instellen van de kleur transparant. Kan ook afgestemd worden op de input en het label in vergelijking met een andere voor wanneer de tijdelijke aanduiding wordt weergegeven. Tot dat einde is, kunnen we ook gebruik maken van de sibling selector om de stijl van het label met betrekking tot de staat van de ingang.

.input-control:een tijdelijke aanduiding weergegeven::tijdelijke aanduiding {
kleur: transparant;
}

.input-control:aanduiding -~ .input-label {
transformeren: translateY(-50%)
}

.input-control:een tijdelijke aanduiding weergegeven {
transformeren: translateY(0);
}

Ten slotte is de truc! Precies zoals hierboven, we negeren de stijlen voor het label en de ingang voor de moderne browsers en de staat waarin de tijdelijke aanduiding wordt niet weergegeven. Dat gaat om het verplaatsen van het label uit de weg en krimpt het een beetje.

:geen(*):aanduiding vertoond,
.input-label {
display: block;
transformeren: translateY(-70%) schaal(.7);

}
:geen(*):aanduiding vertoond,
.input-regelaar {
transformeren: translateY(35%);
}

Met alle stukjes samen, evenals meer stijlen en configuratie opties die loodrecht op dit voorbeeld kunt u raadpleegt het volledige demo:

Zie de Pen CSS-alleen @ondersteunt voor selectors demo door Jirka Vebr (@JirkaVebr) op CodePen.

Betrouwbaarheid en beperkingen van deze techniek

Fundamenteel, zijn deze techniek vereist een selector die overeenkomt met niets. Daartoe hebben we gebruik gemaakt van : (*); echter, de ondersteuning is ook beperkt. De universele selector * wordt zelfs ondersteund door IE 7, overwegende dat :niet van pseudo-class is alleen uitgevoerd omdat IE 9, dat is dus de oudste browser waarin u deze aanpak werkt. Oudere browsers zou weigeren onze selector groepen voor de verkeerde redenen — ze hebben geen ondersteuning voor :niet! Ook kunnen we gebruik maken van een class selector zoals .foo of een type kiezen zoals foo, waardoor het ondersteunen van zelfs de meest oude browsers. Niettemin, deze zorgen ervoor dat de code minder leesbaar is, omdat zij niet over te brengen dat zij nooit overeenkomen met wat dan ook, en dus voor de meeste moderne websites, :geen(*) lijkt de beste optie.

Als voor de vraag of de eigendom van groepen kiezers die hebben we al een voordeel heeft ook in oudere browsers, het probleem wordt geïllustreerd door een voorbeeld van een deel van de CSS 1 sectie op de forward-compatibele parsing. Bovendien, de CSS 2.1 specificatie uitdrukkelijk mandaten van dit probleem. Om de leeftijd van deze specificatie in perspectief, dit is degene die geïntroduceerd :hover. In het kort, terwijl deze techniek is niet uitgebreid getest in de oudste of meest obscure browsers, de ondersteuning moet zeer breed.

Tenslotte is er een klein addertje onder het gras voor de Sass gebruikers (Sass, niet SCSS): na de ontmoeting met de :geen(*):aanduiding-selector, de compiler wordt voor de gek gehouden door de toonaangevende colon, pogingen om het te ontleden als een eigenschap, en wanneer je het fout, geeft het comité advies aan de ontwikkelaar om te ontsnappen aan de kiezer zo: :geen(*):aanduiding vertoond, die niet erg aangenaam. Een betere oplossing is misschien te vervangen door de backslash met nog een andere universele selector te verkrijgen *:geen(*):aanduiding-weergegeven, omdat, volgens de specificatie, het is impliciet toch in dit geval.