Escrevendo CSS com Stylus

Ué, vai falar de CSS? Cadê os artigos de Javascript?
E se eu te disser que Stylus é Javascript, você acredita? Duvida? Vem comigo então ;)

CSS é feio, é verboso, é estático, difícil de organizar, tem muita repetição na escrita. E quando você diminui a repetição, acaba aumentando o acoplamento, e deixando difícil de escalar. Infelizmente a ferramenta que você usa para deixar sua aplicação bonita tem todos esses defeitos.

Mas como escrever CSS de uma forma dinâmica e modular, que fique fácil para organizar e escalar?

Claro: pré-processadores!

A maior parte dos devs que conheço trabalham com SASS ou Less, - que por sinal, são ótimas ferramentas - e talvez pela popularidade delas, acabam deixando de experimentar outras ferramentas que poderiam facilitar ainda mais o seu dia-a-dia. Sim, estou falando do Stylus!

O Stylus é melhor que o SASS e o Less?

Bom, eu já usei os três, logo, tenho argumentos o bastante sobre os prós e contras de cada um. E, como opinião pessoal, eu prefiro o Stylus. E nessa nova série de posts eu vou mostrar porquê!

Preparando o ambiente

Antes de qualquer coisa, precisamos deixar nosso ambiente preparado para usar o Stylus. Só precisamos de uma ferramenta para usá-lo, e você já deve saber qual é, não?

Isso mesmo, o NodeJS!

Provavelmente você já o tem instalado. Se não tiver, faça o download e instale :)

Como o Node instalado, instale o Stylus de modo global:

1
npm i -g stylus

E já temos nosso ambiente pronto :D

Estrutura de diretórios para nosso teste

Crie um diretório onde iremos colocar os arquivos do Stylus e os CSS compilados.

Dentro desse diretório, crie dois diretórios: stylus e css, e um arquivo main.styl dentro de stylus:

1
2
3
4
.
├── /css
└── /stylus
└── main.styl

Todo arquivo do stylus deve ter a extensão .styl.

Fazendo isso, podemos executar o comando abaixo para assistir os arquivos do stylus e compilar:

1
stylus --watch stylus/main.styl --out css/

No Stylus, você só precisa assistir ao arquivo principal. Todos os arquivos importados à partir dele serão também automaticamente assistidos. Qualquer alteração nesses arquivos irá compilar o CSS final :)

Stylus na prática

Agora estamos prontos para presenciar todo o poder do Stylus! Coloque os códigos mostrados ao longo do post no arquivo stylus/main.styl (a menos que seja dito o contrário), e acompanhe o resultado gerado em css/main.css :)

Seletores

Uma das diferenças do Stylus para outros pré-processadores, é que as chaves e dois-pontos e ponto-e-vírgula não são obrigatórios. Mas ainda assim, você pode usá-los, se quiser.

Com Less, você precisa deles sempre. Com SASS, você tem duas sintaxes: .scss, onde você escreve no formato do CSS, e .sass, onde você escreve baseado na indentação, sem ponto-e-vírgula e sem chaves.

Em Stylus, todos os formatos abaixo são válidos:

1
2
3
4
5
6
7
8
9
body {
color: #fff;
}

main
color #fff

div
color: #fff

E detalhe: você pode utilizar isso no mesmo arquivo. Experimente! Escrevendo isso no Stylus, o resultado em main.css será:

1
2
3
4
5
6
7
8
9
body {
color: #fff;
}

main {
color: #fff;
}

div {
color: #fff;
}

Você pode também unir estilos iguais, de duas formas: separando por vírgula, como no CSS, ou colocando um abaixo do outro:

1
2
3
4
5
6
7
body, main, div
color #fff

body
main
div
color #fff

Os dois compilam o mesmo resultado:

1
2
3
4
5
body,
main,
div {
color: #fff;
}

Para fazer referência ao seletor pai (parent reference), você pode usar o &:

1
2
3
4
5
a
color #000

&:hover
color: #f00

Compila para:

1
2
3
4
5
6
a {
color: #000;
}

a:hover {
color: #f00;
}

Se você precisar usar o símbolo & explicitamente em um seletor, você pode escapá-lo com a barra invertida:

1
2
.foo[title*='\&']
font-size: 3em

Vai compilar o & literalmente:

1
2
3
.foo[title*='&'] {
font-size: 3em;
}

Mas isso eu consigo fazer no SASS e no Less também!

Sim! Mas ainda tem mais! :D

Uma das features mais legais, - em minha opinião - é o Root reference. Em alguns momentos você precisa, por exemplo, que o mesmo estilo do a:hover seja o estilo também do input:focus. Como fazer isso sem duplicar o código? Usando o root reference:

1
2
3
4
5
6
a
color #000

&:hover
input:focus
color: #f00

Se você compilar o código acima, ele ficará errado, pois o Stylus vai supor que o input:focus está dentro de a, por causa da indentação:

1
2
3
4
5
6
7
a {
color: #000;
}

a:hover,
a input:focus {
color: #f00;
}

Usando root reference, com a barra (/), você diz ao Stylus para ignorar a indentação e compilar aquele seletor como se ele estivesse na raiz:

1
2
3
4
5
6
a
color #000

&:hover
/input:focus
color: #f00

Fazendo isso, nós temos o resultado esperado:

1
2
3
4
5
6
7
a {
color: #000;
}

a:hover,
input:focus {
color: #f00;
}

Legal não? Isso é exclusivo do Stylus xD

Variáveis

SASS e Less também têm variáveis, mas cada pré-processador tem uma forma de tratá-las. Em Less, elas devem começar com um @, e é usado o sinal : para atribuir valores. No SASS, as variáveis começam com $. A atribuição é igual ao Less.

Em Stylus, você tem liberdade para escrever suas variáveis como quiser, e usa-se o sinal = para atribuição:

1
2
3
4
5
color = #000
font-size = 14px
body
color color
font-size font-size

Vai compilar para:

1
2
3
4
body {
color: #000;
font-size: 14px;
}

Mas isso pode ser ficar um pouco confuso, já que os nomes podem ser os mesmos das propriedades. Temos então a opção de usar o $ como prefixo da variável, como no SASS:

1
2
3
4
5
$color = #000
$font-size = 14px
body
color $color
font-size $font-size

E assim fica melhor :)

No Stylus, temos uma outra feature legal chamada Property Lookup, onde você pode definir variáveis locais no momento da atribuição do valor à uma propriedade:

1
2
3
4
5
div
width: w = 150px
height: h = 120px
margin-left: -( w / 2 )
margin-top: -( h / 2 )

Só coloquei os dois-pontos para facilitar a leitura. Eles continuam opcionais, ainda nesse caso.
E o resultado disso é:

1
2
3
4
5
6
div {
width: 150px;
height: 120px;
margin-left: -75px;
margin-top: -60px;
}

Mas no lugar de definir novas variáveis, você ainda pode usar a própria propriedade como variável, usando o símbolo @:

1
2
3
4
5
div
width 150px
height 120px
margin-left: -( @width / 2 )
margin-top: -( @height / 2 )

Doido, não? :D

Por hoje é só! Esse post foi só pra dar um gostinho :P

Acompanhe os próximos posts da série para descobrir todos os super-poderes do Stylus!

Ficou com alguma dúvida? Comente!

Até o próximo! :D

Sobre o #1postperday: https://blog.da2k.com.br/2014/12/31/um-post-por-dia/

Tem alguma sugestão para os próximos posts do #1postperday? Deixe ela aqui: https://github.com/fdaciuk/fdaciuk.github.io/issues/1