Alt du trenger å vite om Sass Interpolation

Så du spiller med Sass fra tid til annen. Du begynner å nyte det, siden det passer til de fleste av dine behov. Men det er denne ting du ikke forstår helt: interpole - slotting verdier i andre verdier. Vel, du har lykke, for i dag skal jeg kaste litt lys på saken.

Interpo ... Hva?

interpole, ofte referert til som variabel interpolering eller variabel substitusjon er ikke noe unikt for Sass. Faktisk kan du finne det på mange språk (PHP, Perl, Ruby, Tcl, Groovy, Unix skjell ...). Vi snakker ofte om interpolere en variabel eller interpolere et uttrykk. For å si det konsistent er interpolering prosessen med å evaluere et uttrykk eller en streng som inneholder en eller flere variabler, og gir et resultat der variablene erstattes med deres tilsvarende verdier i minnet.

Hm.

La oss se på et eksempel i stedet. Hvis du har noen grunnleggende kunnskaper om PHP, kan dette være lettere å forstå. La oss si at du vil ekko en streng som inneholder en variabel. Den vanlige måten er å gjøre dette:

$ description = "awesome"; ekko "Tuts + er". $ beskrivelse. "!"; 

Dette er ikke interpolering. Dette er string-sammenkjedingen. I utgangspunktet trekker vi sammen (sammenhengende) tre strenger: "Tuts + er","Rått" (referert til som $ beskrivelse) og "!". Nå kan vi bruke interpolering i stedet for strengkonsentrasjon:

$ description = "awesome"; ekko "Tuts + er $ description!"; 

Braces rundt variabelen forteller PHP for å skrive ut variabelen i strengen. Vær oppmerksom på at det trenger dobbelt anførselstegn for å fungere i PHP (som er sant for de fleste språk).

Uansett er dette variabel / uttrykksinterpolering. Enten du bruker concatenation eller interpolering, er det virkelig opp til deg på dette punktet, men la oss bare si at interpolering er syntaktisk sukker for strengkonsentasjon.

Søt.

Hva med Sass?

La oss se på hvordan variabel substitusjon fungerer i Sass.

Sass-variabelnavn, akkurat som i PHP, er prefiks med dollartegnet ($). Dette er hvor sammenligningen slutter skjønt, fordi når det gjelder interpolering, oppfører Sass og PHP seg annerledes. Det er en god grunn til dette: Sass er bygd i Ruby, som bruker # for ekspresjonssubstitusjon.

I Sass vil du gjøre følgende:

$ description: "awesome"; @warn "Tuts + er # $ description!";

Legg merke til at $ Tegnet trekkes ikke fra det variable navnet som i PHP. Variabelen er enkelt innkapslet i # . Det er også verdt å merke seg at du kan interpolere noen variabel type, ikke bare strenger. For eksempel:

$ svar: 42; @warn "Svaret på det ultimative spørsmålet om liv, universet og alt er # $ answer."; 

Når skal jeg bruke interpolering?

Nå som du er klar over hvilken variabel interpolering som er og hvordan du gjør det i Sass, er det på tide å gå videre til faktiske brukstilfeller. For den første vil vi gjenbruke det vi nettopp gjorde med @varsle direktivet, som skriver ut innhold til konsollen.

Strings

La oss si at du har et kart over farger som heter $ farger (et kart er en variabel som lagrer en blanding av nøkkel / verdi par), men du er lei av å skrive kart-få ($ farger, ...) om og om igjen, så du bygger litt farge() Funksjonen henter fargen kartlagt til hvilken tast som helst. La oss skrive det grunnleggende sammen:

// _config.scss $ farger: ("primær": tomat, "sekundær": hotpink); // _function.scss @function color ($ key) @return map-get ($ farger, $ key);  // _component.scss .el bakgrunnsfarge: farge (primær);  

Så det er ganske fint, ikke sant? Nå vil du advare deg selv om nøkkelen ikke eksisterer hvis du skriver en skrivefeil eller prøver å hente en ukjent nøkkel fra kartet (for øvrig vil du kanskje lese denne introduksjonen til feilhåndtering i Sass.) Dette gjøres gjennom @varsle direktiv, i farge() funksjon.

@funksjon farge ($ key) @if ikke kart-har-nøkkel ($ farger, $ nøkkel) @warn "Nøkkel ikke funnet.";  @return map-get ($ farger, $ nøkkel);  

Ikke verst. Nå, hva hvis du vil identifisere hvilken nøkkel som ikke er funnet?

@function farge ($ key) @if ikke map-has-key ($ farger, $ key) @warn "Key" # $ key 'ikke funnet. ";  @return map-get ($ farger, $ nøkkel);  

Boom, variabel interpolering. ringe farge (awesomeness) vil kaste ut følgende melding i konsollen:

Nøkkel awesomeness ikke funnet.

Det er kult, men vi vet egentlig ikke hva sammenhengen er. For å hjelpe vår fremtidige selv, kunne vi legge til kartnavnet i feilmeldingen.

@function farge ($ key) @if ikke map-has-key ($ farger, $ key) @warn "Key" # $ key 'ikke funnet i $ farger kart. ";  @return map-get ($ farger, $ nøkkel);  

I dette tilfellet, siden $ farger variabel har ikke blitt interpolert, den vil bli skrevet ut som en streng.

Nøkkel awesomeness ikke funnet i $ farger kart.

CSS-funksjoner

Så langt har vi sett det vanligste tilfellet for variabel substitusjon: utskrift av innholdet av en variabel i en streng. Det er et godt eksempel, men det har skjedd meg, det er et enda bedre tilfelle for dette: variabler i CSS-funksjoner, for eksempel calc ().

La oss si at du vil formatere hovedbeholderen din basert på bredden på sidefeltet. Som du er en samvittighetsfull frontend-utvikler, har du lagret denne bredden i en variabel, slik at du kan gjøre dette:

$ sidebar-bredde: 250px; .main width: calc (100% - $ sidebar-bredde);  

Og så overraske! Det virker ikke. Det er ingen Sass-feil, men beholderen din er ikke riktig format. Hvis du går og inspiserer stilene sine med DevTools, ser du dette - krysset ut fordi det er ugyldig:

.main width: calc (100% - $ sidebar-bredde);  

La oss nå tenke på det: calc () er en CSS-funksjon, ikke en Sass-funksjon. Dette betyr at Sass tolker hele uttrykket en streng. Du kan prøve det:

$ type-of-expression: type-of (calc (100% - $ sidebar-bredde)); // streng 

Fordi det er en streng, er det ingen grunn til at Sass oppfører seg annerledes enn tidligere $ farger i vår@varsle string. $ Sidebar-bredde regnes som en vanlig streng, så blir det skrevet som det er. Men det er ikke det du vil ha, ikke sant? Så la oss interpolere det!

.main width: calc (100% - # $ sidebar-bredde);  

Nå, når Sass kompilerer stilarket, erstatter det # $ Sidefelt-bredde med verdien knyttet til$ Sidebar-bredde, i dette tilfellet 250px, som resulterer i følgende gyldige CSS-uttrykk:

.main width: calc (100% - 250px);  

Oppdrag utført! Vi snakket om calc () her, men det er det samme med url (), lineær-gradient (),radial-gradient (), kubikk-Bezier-() og andre CSS-innfødte funksjoner, inkludert alle pseudoklassene.

Her er et annet eksempel ved hjelp av CSS-funksjoner:

@for $ i fra 1 til $ maks. .el: nth-of-type (# $ i) // ... 

Dette er et tilfelle du muligens har oppstått: bruker en til sløyfe i forbindelse med : N-te - * () velgere. Igjen må du interpolere variabelen slik at den blir skrevet ut i CSS-utgangen.

For å oppsummere: Sass behandler CSS-funksjoner som strenge, og krever at du unnslipper en variabel som brukes innenfor dem for å skrive ut verdien i den resulterende CSS.

CSS-direktiver

La oss fortsette med et annet interessant tilfelle for variabel interpolering: CSS-direktiver, som @Brukerstøtte, @side men viktigst @media.

Nå har dette å gjøre med hvordan Sass analyserer CSS-direktiver, spesielt mediedirektivet. Jeg har sniffet gjennom Sass-koden, og mens Ruby min egentlig ikke er så god, klarte jeg å finne noe interessant:

 def query_expr interp = interpolering returinterp hvis interp returnere med mindre tok (/ \ (/) res = ['('] ss res << sass_script(:parse) if tok(/:/) res << ': ' ss res << sass_script(:parse) end res << tok!(/\)/) ss res end 

I utgangspunktet forteller de første linjene her at Sass skal returnere medieforespørselen hvis det er et interpolert uttrykk, eller en feil, med mindre den finner en åpningsbøyle ((), i så fall bør det fortsette å gå og analysere hele greia. La oss prøve et eksempel her:

$ verdi: skjerm; @media $ verdi // ... 

Ikke overraskende, mislykkes dette:

Ugyldig CSS etter "@media": forventet medieforespørsel (for eksempel utskrift, skjerm, utskrift og skjerm), var "$ verdi "

Som feilmeldingen peker ut, forventer det et medieforespørsel. På dette punktet må du interpolere variabelen din hvis den kommer rett etter @media streng. For eksempel:

$ verdi: skjerm; @media # $ value // ... 

Som vi har utledet fra vår Ruby escapade tidligere, hvis @media er direkte etterfulgt av braces (()), trenger du ikke å interpolere variabelen lenger fordi Sass vil evaluere alt i disse bøylene. For eksempel:

$ verdi: 1336px; @media (maksimal bredde: $ verdi) // ... 

I dette tilfellet vurderer Sass uttrykket (maksimal bredde: $ verdi), snu den inn (maks bredde: 1337px) gir et gyldig CSS-resultat, så det er ikke nødvendig å unnslippe variabelen.

Som for Hvorfor Sass-opprettholdere designer det slik, spurte jeg Nathan Weizenbaum. Her er hans svar:

Generelt liker vi ikke å tillate råvariabler på steder der fulle SassScript-uttrykk ikke kan brukes. Medieforespørsler er et slikt sted, siden SassScript kan være tvetydig der (spesielt kart).

- Nathan Weizenbaum (@ nex3) 10. juni 2014

velgere

Ok, dette er det siste eksemplet på et brukstilfelle hvor du må interpolere Sass-variabler: når du bruker en variabel som en velger eller som en del av en velger. Selv om det kanskje ikke er en daglig brukstilfelle, er det ikke uvanlig å gjøre noe slikt:

$ verdi: tilpasset; selector- $ value property: value;  

Dessverre virker dette ikke:

Ugyldig CSS etter "selector-": forventet "", var "$ verdi "

Dette er ganske mye av samme grunner som for spørreskjemaet for media. Sass har sin egen måte å analysere en CSS velger på. Hvis det møter noe uventet, for eksempel et unescaped dollar tegn, så krasjer det.

Heldigvis er løsningen av dette problemet enkel (og du kjenner løsningen nå): interpolere variabelen!

$ verdi: tilpasset; selector - # $ value property: value;  

Siste tanker

Til slutt er Sass-interpolering ikke så enkelt som det kan virke. Det er noen tilfeller der du må unnslippe variablene dine, og noen hvor du ikke gjør det. Derfra har du to måter å gjøre ting på:

  • enten du venter på en feilmelding, så unnslipper du
  • eller du unnslippe overalt, men i vanlige CSS-verdier (hvor du vet det fungerer bra).

Uansett, jeg håper jeg har hjulpet deg med å forstå hvordan variabel interpolering fungerer. Hvis du har noe å legge til, må du dele med i kommentarene.