Conhecendo o LESS. The Dynamic Stylesheet.

Como todos devem ter percebido, nos últimos meses o CSS3 e o HTML5 tem ganho um grande destaque no desenvolvimento web. Grandes empresas como o Google, Microsoft, Adobe e Apple estão apoiando fortemente o desenvolvimento web utilizando WebStandards. Caso você já conheça algo sobre CSS, provavelmente deve saber como é complicado a organização desses documentos em um projeto de médio ou grande porte. Dado esses problemas conhecidos, foram surgindo os chamados pré-processadores de CSS, que viabilizam a criação de documentos de estilo, adicionando novas funcionalidades.

Hoje vamos conhecer o LESS, The Dynamic Stylesheet Language. O objetivo dessa biblioteca em javascript é prover uma série de funcionalidades para as, usualmente criadas a mão, folhas de estilos. Recursos tais como, variáveis, mixins (Multiple Inheritance, Traits), mixins parametrizáveis, funções, namespaces, importação, etc. Vamos aprender como utilizar os principais recursos dessa biblioteca em um projeto e como aproveitar o melhor dessa biblioteca para organizar corretamente nossas folhas de estilo.

Variables

As variáveis ajudam-nos a definir valores que podem ser utilizados em diversas regras do nosso CSS. Elas possuem escopo assim como em uma linguagem de programação orientada a objetos, trocando em miúdos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Arquivo stylesheet.less
// Essa variável foi definida no escopo do arquivo, logo, todas as regras do arquivo podem acessar seu valor.
@siteBackgroundColor: #FF3300; // Laranja

h1 {
    // A variável headingColor foi criada no escopo da regra h1, logo, apenas ela e outras regras criadas dentro
    // do mesmo escopo tem acesso ao seu valor.
    @headingColor: #333333; // Cinza
   
    // Isto significa que, se criarmos uma outra regra chamada &.mainTitle
    // Observe o uso do &.classe, isso copia a regra pai e associa uma classe, o output disso seria exatamente h1.mainTitle
    &.mainTitle {
        // Como essa regra esta contida na regra h1, podemos acessar o valor da variável headingColor.
        color: @headingColor;
    }
}

h2 {
    // Se tentarmos acessar o valor nessa regra, que não encontra-se contida na regra h1, receberemos um erro da biblioteca
    // informando que a variável headingColor não encontra-se definida.
    color: @headingColor; // Brrrrrr! Error.
}

O que é interessante no uso de variáveis é a reutilização e organização. Imagine uma design guideline onde existem RGBs especí­ficos a serem seguidos, essas cores poderiam ser definidas em um documento chamado color_variables.less e adicionados ao nosso arquivo principal utilizando a clausula @import.

@Import – Importando outros arquivos

Quando um arquivo LESS é importado, todas as suas variáveis e mixins são adicionados ao arquivo principal. Os escopos serão mantidos e a extensão .less é opcional.

@import “lib.less”
@import “lib”

ɉ possí­vel utilizar pastas nas clausulas de @import:

@import “where/is/my/stylesheet.less”
@import “where/is/my/stylesheet”

Mixins

No LESS, mixis são como uma espécie de classe CSS que pode ser reutilizada em diversas outras regras. Quando utilizadas, todas as propriedades definidas no mixin são adicionadas a regra onde a mesma foi adicionada, caso um mixin mude, todas as regras que o referenciam serão também modificadas.

Imagine o conceito de mixin como classes CSS orientadas a objeto, o que é interessante do mixin é que temos aqui algo como uma herança múltipla, caso uma mesma instrução seja declarada em mixins diferentes, e esses mixins adicionados a uma regra, o mixin declarado por último terá vantagem na construção final do CSS da regra onde foi adicionado.

1
2
3
4
5
6
7
8
9
10
11
12
.bordered {
    border-top: dotted 1px black;
    border-bottom: solid 2px black;
}

// Declaramos agora uma regra qualquer que fará uso do nosso mixin.
div.someDiv {
    .bordered; // Simples assim, adicionamos todas as propriedades contidas no mixin em nossa regra.
}
div.anotherDiv {
    .bordered; // A mesmas propriedades serão adicionadas nessa regra.
}

Quando modificarmos o mixin .bordered, todos os elementos que o estão utilizando serão modificados. Reutilização!
Vamos para um exemplo mais usável para exemplificar como é um mixin parametrizável.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Bordas arredondadas cross-browser.
// Observe que utilizamos algo parecido com uma função de javascript para declararmos nosso mixin.
// A notação de variável deve ser adicionada (@radius), com isso, criamos uma variável chamada "radius" no escopo
// do mixin que poderá ser utilizada apenas internamente pelo método.
// Observe também que declaramos um valor padrão para o parâmetro, de 5px.
.border-radius( @radius: 5px )
{
      // Repare que utilizamos a mesma variável para todas as regras.
      border-radius: @radius;
      -moz-border-radius: @radius;
      -webkit-border-radius: @radius;
}

// Para utilizarmos a regra, seguimos o mesmo padrão
div.someDiv {
.border-radius; // Nesse caso estaremos utilizando o valor padrão de 5px.
}
div.anotherDiv {
.border-radius(10px); // Nessa aplicação, modificamos o valor da propriedade para 10px.
}

ɉ importante destacar que um mixin pode conter diversos parâmetros. Isso pode ser feito da seguinte forma:

1
2
3
4
5
6
// Declaramos um novo mixin
.border-radius-and-color( @radius: 5px, @borderColor: #000000 )
{
.border-radius( @radius ); // Observe que aqui reutilizei o mixin previamente definido. Composição de mixins.
border: 2px solid @borderColor; // Adicionamos agora a cor para a borda.
}

Nested Rules

Com o LESS você pode criar suas regras de CSS utilizando uma espécie de hierarquia. Vamos ver como isso funciona na prática.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Dado o CSS abaixo
div#header #menu {
...
rules
}

div#header #menu li a {
...
more rules
}

div#header #topNav {
...
another rules
}

Com o LESS, o mesmo CSS acima poderia ser escrito da seguinte forma:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Como utilizar hierarquia com Less
div#header {
    #menu {
        ul {
            li {
           
            }
        }
    }
   
    #topNav {
   
    }
}

Depois de processado, o CSS será exatamente igual. Você não precisa utilizar esse esquema de hierarquia caso não queira, é importante lembrar que o LESS é apenas uma extensão do CSS, se for de desejo do desenvolvedor, podemos escrever um código LESS sem usar nenhum recurso especial, como se fosse um CSS tradicional.

Operations

Com o LESS o seu CSS sabe fazer contas. Qualquer número, cor ou variável pode ser utilizada em uma operação aritmética.
Ele sabe identificar quando estamos utilizando uma cor ou um número, por exemplo:

1
2
3
4
5
6
7
@base: 5%;
@filler: @base * 2;
@other: @base + @filler;

color: #888 / 4;
background-color: @base-color + #111;
height: 100% / 2 + @filler;

Assim como no javascript, é possí­vel também utilizar parênteses nas suas operações:

1
width: (@var + 5) * 2;

Color Functions

Na minha opinião um dos recursos mais úteis durante o desenvolvimento de uma aplicação. Podemos efetuar operações em cima de RGBs, por exemplo, imagine que o layout do seu website foi criado baseado-se em apenas uma cor, utilizando diversos tons dessa cor. Com o LESS é possí­vel utilizar métodos pré-definidos como lighten, saturate, darken, fadein, fadeout e spin. Esses métodos retornam sempre um RGB que pode ser utilizado em seu LESS. Vejamos alguns exemplos:

1
2
3
4
5
6
7
8
9
@base: #f04615;

.class {
// Saturo em 5% a cor base.
color: saturate(@base, 5%);

// Utilizo a cor base 25% mais clara
background-color: lighten(@base, 25%);
}

ɉ possí­vel também extrair informações de uma determinada cor para ser utilizada em outra.
Isso é feito a partir dos métodos hue, saturation e lightness.

1
2
3
hue(@color);        // retorna o valor do canal 'hue' da cor @color
saturation(@color); // retorna o valor do canal 'saturation' da cor @color
lightness(@color);  // retorna o valor do canal 'lightness' da cor @color

Namespaces

Em dado momento necessitamos organizar uma série de mixins e variáveis. Para isto podemos utilizar um conceito presente no LESS chamado Namespaces. Assim como em linguagens de programação orientadas a objetos, que possuem o conceito de pacotes, os namespaces fornecem encapsulação para nossas folhas de estilo. Isso pode ser implementado facilmente utilizando a mesma notação de ID do CSS tradicional. Vejamos.

1
2
3
4
5
6
7
8
9
10
11
12
#bundle
{
.button ()
{
display: block;
border: 1px solid black;
background-color: grey;
&:hover { background-color: white }
}
.tab { ... }
.citation { ... }
}

Verifique que acima, criamos um mixin chamado button dentro do namespace bundle. Para o utilizarmos devemos fazer da seguinte forma:

1
2
3
4
#header a {
color: orange;
#bundle > .button; // Estamos acessando o namespace 'bundle' e fazendo uma chamada para o mixin 'button'.
}

Uma utilização muito comum dos namespaces é na criação de pequenas bibliotecas de utilidades. Imagine que sua empresa pode possuir uma série de arquivos LESS, e em um determinado projeto você necessita de acesso a esses mixins, variáveis, etc. Organizar seus documentos com namespaces fácilita a visualização e localização de uma determinada instrução no seu documento LESS, como por exemplo, um mixin customizado que pode ser facilmente encontrado a partir da sua indicação de namespace.

1
2
3
someRule {
#dclick > .border-radius(10px);
}

Conclusão

Como podemos ver, o LESS facilita uma série de tarefas que são praticamente impossí­veis de serem efetuadas pelo CSS tradicional.
Aconselho a todos que tenham interesse em se aprofundar mais na biblioteca a conhecer o website (http://lesscss.org/). Lá você poderá encontrar a documentação com maior riqueza de informações também poderá ver alguns exemplos de código que não foram abordados nesse post.

Qualquer dúvida, sinta-se a vontade e envie-nos um comentário!
Abraço!