Tudo Que Você Sempre Quis Saber Sobre Interpolação no Sass
() translation by (you can also view the original English article)
Então você curte utilizar o pré processador Sass. Ela de fato otimiza sua produtividade. Mas ainda existe uma coisa que você não consegue entender: interpolação (ou interpolation, em inglês) - que basicamente significa encaixar valores dentro de outros valores. Hoje você está com sorte, pois neste artigo vamos abordar como funciona a interpolação no Sass.
Interpo... o que?
Interpolação ou interpolation, as vezes mencionada como variable interpolation ou interpolação de variáveis não é uma funcionalidade exclusiva do Sass. Atualmente você encontra essa funcionalidade em diversas linguagens (PHP, Perl, Ruby, Tcl, Groovy, Unix shells...). As vezes também comentamos sobre interpolar uma variável/interpolating a variable ou interpolar uma expressão/interpolating an expression. Sem mais delongas, interpolação é o processo de analisar uma expressão ou uma string com uma ou mais variáveis, gerando um resultado onde as variáveis são substituidas pelos valores presentes na memória.
Hm, meio confuso.
Vamos analisar um exemplo. Se você tem conhecimento básico em PHP você vai conseguir entender este exemplo. Digamos que você quer apresentar uma string que contém uma variável. A maneira mais comum para fazer isso é esta:
1 |
|
2 |
$description = "awesome"; |
3 |
echo "Tuts+ is " . $description . "!"; |
Isso não é interpolar. Isso na verdade é o método de concatenar strings/string-concatenation. Estamos concatenando (juntando) três strings: "Tuts+ is "
,"awesome"
(como $description
) e "!"
. Podemos interpolar, ao invés de concatenar uma string, veja o exemplo:
1 |
|
2 |
$description = "awesome"; |
3 |
echo "Tuts+ is ${description}!"; |
As chaves em volta da variável orientam o PHP a printar o valor da variável junto a string. Note que precisamos utilizar aspas duplas para este recurso com a linguagem PHP (e para maioria das linguagens).
De qualquer forma, isso é uma interpolação de expressão/variável. Utilizar tanto interpolação quando concatenação é uma decisão sua, mas digamos que a interpolação é uma maneira mais fácil de ler e entender a concatenação de strings.



E como isso funciona com o Sass?
Vamos analisar como a substituição de variável ocorre utilizando o pré processador Sass.
As variáveis da linguagem Sass, assim como no PHP, utilizam o símbolo do dólar ($
) para indicar uma variável. Pois é que a diferenteça termina, o Sass tem uma abordagem totalmente diferente para interpolação. E existe uma razão para isso: Sass opera sobre a linguagem Ruby, que utiliza #{}
para substituir expressões.
Exemplo, utilizando Sass:
1 |
|
2 |
$description: "awesome"; |
3 |
@warn "Tuts+ is #{$description}!"; |



Note que o símbolo $
é utilizado para indicar a variável na segunda linha, ao contrário do PHP. A variável é apenas declarada entre #{}
. Vale salientar que você pode interpolar qualquer tipo de variável, além de strings. Por exemplo:
1 |
|
2 |
$answer: 42; |
3 |
@warn "The Answer to the Ultimate Question of Life, the Universe, and Everything is #{$answer}."; |
Quando devemos utilizar a interpolação?
Agora que você sabe o que é interpolar uma variável e como utilizar com Sass, é hora de analisar alguns casos de uso. Para a primeira análise, vamos utilizar um exemplo com a diretiva @warn
, que printa o conteúdo no console.
Strings
Digamos que você tem um map/mapa de cores chamado $colors
(map é uma variável que contém um série de valores) e que você está cansado de digitar map-get($colors, ...)
a todo momento, então você cria uma função color()
que aponta a cor mapeada para qualquer valor apresentado. Vamos escrever o código básico juntos:
1 |
|
2 |
// _config.scss |
3 |
$colors: ( |
4 |
"primary": tomato, |
5 |
"secondary": hotpink |
6 |
);
|
7 |
|
8 |
// _function.scss |
9 |
@function color($key) { |
10 |
@return map-get($colors, $key); |
11 |
}
|
12 |
|
13 |
// _component.scss |
14 |
.el { |
15 |
background-color: color(primary); |
16 |
}
|
Digamos que agora você quer ser informado quando um valor não existe ou quando é apresentado um valor desconhecido para o mapa (by the way, este artigo pode interessar introduction to error handling in Sass.) Isso pode ser feito com a diretiva @warn
na função color()
.
1 |
|
2 |
@function color($key) { |
3 |
@if not map-has-key($colors, $key) { |
4 |
@warn "Key not found."; |
5 |
}
|
6 |
@return map-get($colors, $key); |
7 |
}
|
E se você quiser indentificar qual valor não foi encontrado?
1 |
|
2 |
@function color($key) { |
3 |
@if not map-has-key($colors, $key) { |
4 |
@warn "Key `#{$key}` not found."; |
5 |
}
|
6 |
@return map-get($colors, $key); |
7 |
}
|
Pronto, você interpolou as variáveis. Requisitar [cci lang="html"]color(awesomeness)[/cci] vai apresentar a seguinte mensagem no console:
Key
awesomeness
not found.
Bacana, mas o contexto ficou um pouco obscuro. Para ajudar, podemos incluir o nome do map junto a mensagem de erro.
1 |
|
2 |
@function color($key) { |
3 |
@if not map-has-key($colors, $key) { |
4 |
@warn "Key `#{$key}` not found in $colors map."; |
5 |
}
|
6 |
@return map-get($colors, $key); |
7 |
}
|
Assim, mesmo a variável $colors
não sendo interpolada ela vai se apresentar como uma string.
Key
awesomeness
not found in $colors map.
Funções CSS
Até agora, vimos o caso mais comum de substituição de variáveis: printar o conteúdo de uma variávem em uma string. Esse exemplo é muito bom, mas existem exemplos mais interessantes: variáveis em funções CSS, por exemplo calc()
.
Digamos que você quer ajustar o tamnho do seu container se baseando na largura da sidebar. Com o valor da largura da sidebar guardado em uma variável, podemos seguir este exemplo:
1 |
|
2 |
$sidebar-width: 250px; |
3 |
|
4 |
.main { |
5 |
width: calc(100% - $sidebar-width); |
6 |
}
|
Surpresa! Não funcionou. O Sass não apresentou erro, e o container não foi ajustado esperado. Se você analisar os estilos com o DevTools, você vai ver o estilo riscado - que significa que é uma propriedade inválidade não aplicada:
1 |
.main { |
2 |
width: calc(100% - $sidebar-width); |
3 |
}
|
Vamos pensar sobre isso: calc()
é uma função CSS, não uma função Sass. Isso significa que o Sass interpreta toda a expressão em uma string. Teste este exemplo:
1 |
|
2 |
$type-of-expression: type-of(calc(100% - $sidebar-width)); // string |
Por ser uma string, não há razão para o Sass agir diferente como o caso da variável $colors
na string @warn
. Mas não é isso que você espera, certo? Vamos interpolar isso!
1 |
|
2 |
.main { |
3 |
width: calc(100% - #{$sidebar-width}); |
4 |
}
|
Agora, quando o Sass compilar os estilos, ele vai substituir o código #{$sidebar-width}
pelo valor associado a $sidebar-width
, neste caso 250px
, resultando na expressão CSS:
1 |
|
2 |
.main { |
3 |
width: calc(100% - 250px); |
4 |
}
|
Missão cumprida! Neste exemplo utilizamos a função calc()
mas é a mesma coisa para outras funções como url()
, linear-gradient()
,radial-gradient()
, cubic-bezier()
e qualquer outra função nativa do CSS, incluindo pseudo-classes.
Outro exemplo utilizando funções CSS:
1 |
|
2 |
@for $i from 1 through $max { |
3 |
.el:nth-of-type(#{$i}) { |
4 |
// ... |
5 |
}
|
6 |
}
|
Esse é um caso que você ja deve ter se deparado: utilizar o looping for
com os seletores :nth-*()
. Mais uma vez, você vai precisar interpolar a variável para que ela seja apresentada no CSS gerado.
Para fixar: a linguagem Sass trata as funções CSS como string, fazendo com que você evite o uso de qualquer variável utilizada pois o valor da mesma será apresentado no CSS gerado.
Diretivas CSS
Seguindo em frente, temos outro exemplo interessante de interpolação: diretivas CSS, como por exemplo @support
, @page
e @media
.
Este tem mais a ver com a forma que o Sass analisa o CSS perante as diretivas, espcialmente a diretiva de mídia. Analisando o código Sass, já que minha experiência em Ruby não é lá essas coisas, eu encontrei algo interessante:
1 |
|
2 |
def query_expr |
3 |
interp = interpolation |
4 |
return interp if interp |
5 |
return unless tok(/\(/) |
6 |
res = ['('] |
7 |
ss
|
8 |
res << sass_script(:parse) |
9 |
|
10 |
if tok(/:/) |
11 |
res << ': ' |
12 |
ss
|
13 |
res << sass_script(:parse) |
14 |
end
|
15 |
res << tok!(/\)/) |
16 |
ss
|
17 |
res
|
18 |
end
|
Basicamente, as primeiras linhas orientam o Sass a retornar o media query caso haja expressão interpolada, ou erro, a não ser que seja detectada a presença do parênteses ((
), caso contrário ele deve continuar a verificação até o fim. Vamos analisar um exemplo:
1 |
|
2 |
$value: screen; |
3 |
|
4 |
@media $value { |
5 |
// ... |
6 |
}
|
Como esperado, o exemplo apresenta falha:
Invalid CSS after "@media ": expected media query (e.g. print, screen, print and screen), was "$value {"
Segundo a mensagem de erro, o Sass espera uma media query. Neste momento, você precisa interpolar sua variável se ela é apresentada depois da string @media
. Por exemplo:
1 |
|
2 |
$value: screen; |
3 |
|
4 |
@media #{$value} { |
5 |
// ... |
6 |
}
|
Como verificado acima na breve análise da linguagem Ruby, se a @media
é seguida de parênteses (()
), você não precisa interpolar a variável, porque o Sass vai considerar qualquer coisa dentro do parenteses. Por exemplo:
1 |
|
2 |
$value: 1336px; |
3 |
|
4 |
@media (max-width: $value) { |
5 |
// ... |
6 |
}
|
Neste caso, o Sass avalia a expressão (max-width: $value)
, que se transforma em (max-width: 1337px)
, gerando um CSS válido sem a necessidade de alterar a variável.
Perguntei ao Nathan Weizenbaum, porque o Sass é mantido desta forma e obtive a seguinte resposta:
Em geral, não orientamos que variáveis X sejam utilizadas onde espressões SassScript não podem ser utilizadas. Media queries são uma solução, tendo em mente a ambiguidade do SassScript (em maps especialmente).
In general, we don't like allowing raw variables in places where full SassScript expressions can't be used. Media queries are such a place, since SassScript can be ambiguous there (maps especially).
— Nathan Weizenbaum (@nex3) June 10, 2014
Seletores
Este é o ultimo caso de uso, onde vamos interpolar variáveis Sass: quando utilizar uma variável como seletor ou parte dele. Apesar de não ser um caso presente no dia dia, é comum se deparar com algo como:
1 |
|
2 |
$value: custom; |
3 |
|
4 |
selector-$value { |
5 |
property: value; |
6 |
}
|
Infelizmente, este recurso não funciona, apresentando a falha:
Invalid CSS after "selector-": expected "{", was "$value {"
A falha é apresentada basicamento pelo menos motivo do exemplo com media query. O Sass tem sua própria maneira de interpretar seletores CSS. Se ele encontra algo inesperado, neste caso o sinal do dólar (que indica a variável), ele apresenta erro.
Felizmente, solucionar essa falha é fácil (agora que você já conhece a solução): basta interpolar a variável.
1 |
|
2 |
$value: custom; |
3 |
|
4 |
selector-#{$value} { |
5 |
property: value; |
6 |
}
|
Conclusão
No final, interpolar na linguagem Sass não é tão simples quanto parecia. Vão existir casos onde você vai precisar utilizar ou não as variáveis.
Espero que vocês tenham entendido como a interpolação funciona na linguagem Sass, qualquer informação adicional é bem vinda nos comentários.
Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!