Dus je speelt af en toe met Sass. Je begint ervan te genieten, omdat het geschikt is voor de meeste van je behoeften. Maar er is een ding dat je niet helemaal begrijpt: interpolatie - waarden in andere waarden steken. Nou je hebt geluk, want vandaag ga ik wat licht werpen op de zaak.
interpolatie, vaak aangeduid als variabele interpolatie of variabele vervanging is niet iets unieks voor Sass. Eigenlijk kun je het in vele talen vinden (PHP, Perl, Ruby, Tcl, Groovy, Unix shells ...). We hebben het vaak over interpolatie van een variabele of interpolatie van een uitdrukking. Kort gezegd, interpoleren is het proces van het evalueren van een uitdrukking of een reeks die een of meer variabelen bevat, waardoor een resultaat wordt verkregen waarin de variabelen worden vervangen door hun overeenkomstige waarden in het geheugen.
hm.
Laten we eens naar een voorbeeld kijken. Als je enige basiskennis van PHP hebt, is dit misschien makkelijker te begrijpen. Laten we zeggen dat je een string wilt echoën die een variabele bevat. De gebruikelijke manier is om dit te doen:
$ description = "geweldig"; echo "Tuts + is". $ beschrijving. "!";
Dit is geen interpolatie. Dit is koord-aaneenschakeling. In principe zijn we bezig met het aaneenschakelen (samen ketenen) van drie snaren: "Tuts + is"
,"geweldig"
(waarnaar wordt verwezen als $ beschrijving
) en "!"
. We kunnen nu interpolatie gebruiken in plaats van tekenreeksaaneenschakeling:
$ description = "geweldig"; echo "Tuts + is $ description!";
De accolades rond de variabele vertelt PHP om de variabele waarde binnen de tekenreeks af te drukken. Merk op dat het dubbele aanhalingstekens nodig heeft om in PHP te werken (wat geldt voor de meeste talen).
Hoe dan ook, dit is variabele / expressie-interpolatie. Of u nu aaneenschakeling of interpolatie gebruikt, is nu echt aan u, maar laten we zeggen dat interpolatie syntactische suiker is voor string concatenation.
Zoet.Laten we eens kijken hoe variabele substitutie werkt in Sass.
Sass-variabelenamen, net als in PHP, worden voorafgegaan door het dollarteken ($
). Dit is echter waar de vergelijking eindigt, want als het op interpolatie aankomt, gedragen Sass en PHP zich anders. Daar is een goede reden voor: Sass is gebouwd in Ruby, dat gebruikt #
voor expressievervanging.
In Sass doet u het volgende:
$ beschrijving: "geweldig"; @warn "Tuts + is # $ description!";
Merk op dat de $
teken wordt niet afgetrokken van de variabelenaam zoals in PHP. De variabele is eenvoudig ingekapseld in #
. Het is ook vermeldenswaard dat je elk variabel type kunt interpoleren, niet alleen strings. Bijvoorbeeld:
$ antwoord: 42; @warn "Het antwoord op de ultieme vraag van het leven, het universum en alles is # $ answer.";
Nu u zich bewust bent van wat variabele interpolatie is en hoe u dit in Sass moet doen, is het tijd om verder te gaan naar daadwerkelijke use-cases. Voor de eerste zullen we opnieuw gebruiken wat we net deden met de @waarschuwen
richtlijn, die inhoud op de console afdrukt.
Laten we zeggen dat je een gekleurde kaart hebt $ kleuren
(een kaart is een variabele die een mix van sleutel / waarde-paren opslaat), maar je bent het typen beu map-get ($ kleuren, ...)
steeds weer opnieuw, dus je bouwt een beetje kleur()
functie om de kleur op te halen die is toegewezen aan de sleutel die wordt doorgegeven. Laten we de basis samen schrijven:
// _config.scss $ colors: ("primary": tomaat, "secondary": hotpink); // _function.scss @function color ($ key) @return map-get ($ colors, $ key); // _component.scss .el background-color: color (primary);
Dus dat is best aardig, toch? Nu zou je jezelf willen waarschuwen dat de sleutel niet bestaat als je een typfout maakt of een onbekende sleutel van de kaart probeert op te halen (trouwens, lees deze inleiding over foutafhandeling in Sass.) Dit gebeurt via de @waarschuwen
richtlijn, in de kleur()
functie.
@function color ($ key) @if not map-has-key ($ colors, $ key) @warn "Key not found."; @return map-get ($ colors, $ key);
Niet slecht. Nu, wat als u wilt weten welke sleutel nog niet is gevonden?
@function color ($ key) @if not map-has-key ($ colors, $ key) @warn "Key '# $ key' not found."; @return map-get ($ colors, $ key);
Boom, variabele interpolatie. Roeping Kleur (awesomeness)
zal het volgende bericht in de console weggooien:
Sleutel
geweldigheid
niet gevonden.
Dat is cool, maar we weten niet echt wat de context is. Om ons zelf te helpen, kunnen we de kaartnaam toevoegen aan het foutbericht.
@function color ($ key) @if niet map-has-key ($ colors, $ key) @warn "Key '# $ key' niet gevonden in $ colors map."; @return map-get ($ colors, $ key);
In dit geval, sinds de $ kleuren
variabele is niet geïnterpoleerd, het zal als een string worden afgedrukt.
Sleutel
geweldigheid
niet gevonden in $ kleurenkaart.
Tot nu toe hebben we het meest voorkomende geval van variabele substitutie gezien: de inhoud van een variabele in een tekenreeks afdrukken. Dat is een geweldig voorbeeld, maar het is bij mij opgekomen dat er een nog beter geval is: variabelen in CSS-functies, bijvoorbeeld calc ()
.
Stel dat u uw hoofdcontainer wilt vergroten op basis van de breedte van de zijbalk. Omdat je een gewetensvolle front-end ontwikkelaar bent, heb je deze breedte in een variabele opgeslagen, zodat je dit kunt doen:
$ sidebar-width: 250px; .main width: calc (100% - $ sidebar-width);
En dan verrassing! Het werkt niet. Er is geen Sass-fout opgetreden, maar uw container heeft geen juiste grootte. Als je de stijlen gaat bekijken met DevTools, zie je dit - doorgestreept omdat het ongeldig is:
.main width: calc (100% - $ sidebar-width);
Laten we er nu eens over nadenken: calc ()
is een CSS-functie, geen Sass-functie. Dit betekent dat Sass de hele expressie interpreteert als een tekenreeks. Je kunt het proberen:
$ type-van-expressie: type-of (calc (100% - $ sidebar-width)); // draad
Omdat het een tekenreeks is, is er geen reden voor Sass om zich anders dan vroeger te gedragen $ kleuren
in onze@waarschuwen
draad. $ Sidebar-width
wordt beschouwd als een normale reeks, dus wordt afgedrukt zoals ze is. Maar dat is niet wat u wilt, toch? Dus laten we het interpoleren!
.main width: calc (100% - # $ sidebar-width);
Als Sass het stylesheet nu compileert, wordt het vervangen # $ Sidebar-width
met de waarde gekoppeld aan$ Sidebar-width
, in dit geval 250px
, resulterend in de volgende geldige CSS-expressie:
.hoofd width: calc (100% - 250px);
Missie volbracht! We spraken over calc ()
hier maar het is hetzelfde met url ()
, lineaire gradiënt ()
,radiaal-gradiënt ()
, kubieke Bezier ()
en alle andere CSS-native functies, inclusief alle pseudo-klassen.
Hier is nog een voorbeeld met behulp van CSS-functies:
@voor $ i van 1 tot $ max .el: nth-of-type (# $ i) // ...
Dit is een geval dat u mogelijk bent tegengekomen: met behulp van een voor
loop in combinatie met : N - * ()
selectors. Nogmaals, u moet de variabele interpoleren zodat deze wordt afgedrukt in de uitvoer-CSS.
Samenvattend: Sass behandelt CSS-functies als strings, waardoor je moet ontsnappen aan elke variabele die in die functies wordt gebruikt om hun waarde in de resulterende CSS te printen.
Laten we verder gaan met een ander interessant geval voor variabele interpolatie: CSS-richtlijnen, zoals @ondersteuning
, @pagina
maar het belangrijkste @media
.
Dit heeft nu te maken met hoe Sass CSS-richtlijnen adverteert, met name de mediarichtlijn. Ik heb gesnuffeld door Sass-code, en hoewel mijn Ruby echt niet zo goed is, heb ik iets interessants kunnen vinden:
def query_expr interp = interpolatie retourneer interp als interp return tenzij tok (/ \ (/) res = ['('] ss res << sass_script(:parse) if tok(/:/) res << ': ' ss res << sass_script(:parse) end res << tok!(/\)/) ss res end
Kort gezegd, vertellen de eerste regels hier Sass om de mediaquery terug te sturen als er een geïnterpoleerde expressie is, of een fout tenzij een openingscorrectie wordt gevonden ((
), in welk geval het moet doorgaan en het hele ding ontleden. Laten we hier een voorbeeld proberen:
$ waarde: scherm; @media $ waarde // ...
Niet verwonderlijk, dit mislukt:
Ongeldige CSS na '@media': verwachte mediaquery (bijvoorbeeld afdrukken, scherm, afdrukken en scherm), was '$ value '
Zoals de foutmelding aangeeft, verwacht het een media-query. Op dit punt moet u uw variabele interpoleren als deze direct na de @media
draad. Bijvoorbeeld:
$ waarde: scherm; @media # $ value // ...
Zoals we eerder uit onze Ruby-escapade hebben afgeleid, als @media
wordt direct gevolgd door beugels (()
), hoeft u de variabele niet meer te interpoleren omdat Sass alles binnen die accolades zal evalueren. Bijvoorbeeld:
$ waarde: 1336px; @media (max-width: $ value) // ...
In dit geval evalueert Sass de expressie (max-breedte: $ waarde)
, het veranderen (max. breedte: 1337 px)
levert een geldig CSS-resultaat op, dus het is niet nodig om aan de variabele te ontsnappen.
Wat betreft waarom Sass-beheerders ontwerpen het zo, vroeg ik Nathan Weizenbaum. Dit is zijn antwoord:
Over het algemeen houden we niet van het toestaan van onbewerkte variabelen op plaatsen waar volledige SassScript-expressies niet kunnen worden gebruikt. Mediaquery's zijn zo'n plek, omdat SassScript daar dubbelzinnig kan zijn (met name kaarten).
- Nathan Weizenbaum (@ nex3) 10 juni 2014
Oké, dit is het laatste voorbeeld van een use-case waarbij je Sass-variabelen moet interpoleren: wanneer je een variabele als een selector gebruikt of als onderdeel van een selector. Hoewel het misschien geen dagelijks gebruik is, is het niet ongewoon om zoiets te doen:
$ waarde: aangepast; selector- $ waarde eigenschap: waarde;
Helaas werkt dit niet:
Ongeldige CSS na "selector-": expected "", was "$ value "
Dit gebeurt om dezelfde redenen als voor het voorbeeld van de mediaquery. Sass heeft een eigen manier om een CSS-selector te ontleden. Als het iets onverwachts tegenkomt, bijvoorbeeld een niet-escaped dollarteken, dan crasht het.
Gelukkig is het oplossen van dit probleem eenvoudig (en u kent nu de oplossing): interpoleer de variabele!
$ waarde: aangepast; selector - # $ value property: value;
Uiteindelijk is Sass-interpolatie niet zo eenvoudig als het lijkt. Er zijn enkele gevallen waarin u aan uw variabelen moet ontsnappen en andere waar dat niet het geval is. Vanaf daar heb je twee manieren om dingen te doen:
Hoe dan ook, ik hoop dat ik je heb geholpen begrijpen hoe variabele interpolatie werkt. Als je iets toe te voegen hebt, zorg er dan voor dat je deze in de comments deelt.