Usando pré-processadores CSS com inteligência

Estamos usando Sass nos projetos em Rails aqui da MustacheLabs, e tivemos algumas experiências bem interessantes - ruins e boas. As boas são o uso dos mixins e variables de forma organizada, as vantagens de se utilizar cálculos pra definir grids e outras propriedades de containers, entre outras. Uma das ruins é que, se você não sabe como estruturar seu código, o pré-processador pode virar uma arma contra você mesmo...

A parte boa

Primeiramente, um dos motivos de escolhermos o Sass foi que sua "compatibilidade" com o Rails é uma mão na roda. Isso se deve também a gem sass-rails que possui alguns helpers que agilizam essa integração, como o de assets, que é essencial pra que algumas propriedades não se percam em enviroments diferentes.

background: transparent image-path("imagem.jpg") top left no-repeat;

O que a gem sass-rails faz é, localizar a "imagem.jpg", independente de estar em development ou production mode. Isso evita aquele trabalho chato de ficar vasculhando CSS em busca do background-url que alguém fixou com /assets/images/imagem.jpg...

Fora que, se o diretório de production for o /public/assets/ por exemplo, a gem se encarrega de identificar e servir corretamente os arquivos dessa pasta, livrando você de gerenciar isso na mão.

Existem vários outros pontos comprovando que o uso do pré-processador é benéfico para seu projeto. Alguns artigos que recomendo fortemente são:

Fique atento

Já sabemos do poder dos pré-processadores, mas é bom ficar atento com os pequenos erros na hora de estruturar as coisas. Isso independe do uso deles, mas a probabilidade de você fazer algo não muito inteligente é maior.

* Vou citar exemplos usando o Sass, o qual tenho mais familiaridade.

@include

Um dos erros é achar que o @include é a solução dos problemas de DRY (Don't Repeat Yourself) e que vai facilitar e deixar seu código mais limpo. Vejamos porque isso pode não ser tão real.

@import "common/variables";

@mixin btn($color: #fff) {
    display: inline-block;
    width: 100px;
    padding: 5px 10px;
    color: $color;
}

.btn-blue {
    @include btn($color-blue);
}

.btn-red {
    @include btn($color-red);
}

.btn-yellow {
    @include btn($color-yellow);
}

Perfeito não? Visualmente seu código parece clean e organizado. Vejamos, porém, o que acontece com o CSS gerado nesse caso:

.btn-blue {
    display: inline-block;
    width: 100px;
    padding: 5px 10px;
    color: #00f;
}
.btn-red {
    display: inline-block;
    width: 100px;
    padding: 5px 10px;
    color: #f00;
}
.btn-yellow {
    display: inline-block;
    width: 100px;
    padding: 5px 10px;
    color: #ff0;
}

Viu o problema? Explicando melhor, o que acontece é que, o @include chama um mixin que retorna propriedades, como se fosse uma function. Você tem a opção de passar uma variável, como no exemplo - uma $color.

O problema é que nesse caso, ele vai repetir propriedades em cada um dos locais que você der o @include. Assim, vamos ter vários trechos de código se repetindo, o que fere o conceito do DRY. Isso porque usei poucas propriedades no mixin btn. Imagine se tivéssemos border-radius, font-size, box-shadow, tudo se repetindo loucamente...

Podemos resolver isso partindo pra uma abordagem de abstração, usando uma classe genérica, .btn, e especificar outras classes apenas com o que realmente é mutável, como o color. Ex:

.btn {
    display: inline-block;
    width: 100px;
    padding: 5px 10px;
}
.btn-red {
    color: $color-red;
}
.btn-blue {
    color: $color-blue;
}
.btn-yellow {
    color: $color-yellow;
}

Agora sim temos um cenário bem melhor! Basta adicionar a classe btn na sua tag e mais outra especificando o tipo do btn, no caso, btn-red, btn-blue e etc.

ALERTA! Tome cuidado com essa prática e veja se não está criando muitas classes com apenas um atributo. Evite também essa granularização!

Mas não estou usando o poder do pré-processador, né? Não gostei!

É por isso que o esse artigo enfatiza o uso dele com inteligência. Nesse caso, não compensa o uso do @include de um mixin apenas pra que seu código fique mais clean. Aliás, será que ficou mais clean mesmo? Não é melhor remover redundâncias e repetições pra que o código compilado não sofra e duplique ou triplique de tamanho? Vale o bom senso sempre!

Repense seus componentes com OOCSS

Se ainda não sabe o conceito, vários artigos explicam o uso do OOCSS (Object Oriented CSS). Resumindo, é praticamente o que fizemos com o exemplo do btn.

Veja alguns textos de referência bem interessantes pra se aprofundar mais nessa técnica:

Resumindo

Ao criarmos um componente btn, onde btn-red, por exemplo, é uma extensão de btn, mas que possui uma característica exclusiva, o color, abstraímos propriedades comuns. Isso é OOCSS e DRY lindamente aplicados! Use isso sempre no seu código.

Outra dica importante: SEMPRE verifique o css compilado! Isso ajuda a identificar erros comuns e repetições desnecessárias.

Além disso tudo, use as funcionalidades do pré-processador apenas quando forem realmente necessárias. Não adianta ser cool e ter um código cheio de bizarrices sem lógica. Novamente, bom senso precisa ser seu norte, sempre.

Enfim

Podemos concluir então que usar pré-processadores é bom, mas com inteligência. Se você ainda peca na organização do código, de repente vale a pena estudar mais sobre OOCSS e outras técnicas de modularização.

comments powered by Disqus