sexta-feira, 16 de agosto de 2013

Sass - Indo Além do CSS

Sass é uma meta-linguagem do CSS (construída sobre o CSS) que é utilizada para descrever o estilo de um documento de maneira estruturada e legível, provendo mais poder que um CSS tradicional. 

O Sass provê uma sintaxe mais simples e elegante para o CSS e implementa diversas funcionalidades que são úteis para se criar estilos mais fáceis de serem mantidos e adaptados.

Bom, mas a melhor forma de entender o que é o Sass é vendo seu funcionamento na prática, então vamos ao que interessa!


Instalando o Sass

Antes de mais nada, a primeira coisa a se fazer é instalar o Sass na máquina de desenvolvimento e, para isso, é necessário ter o Ruby já instalado (o Sass é uma "gema", ou seja, uma aplicação feita em Ruby).

Obs.: No Mac OS, o Ruby já vem instalado por padrão. Já no Windows e no Linux, é necessário fazer a sua instalação - no caso do Linux, usar o package manager; no caso do Windows, o instalador pode ser baixado aqui (marcar a opção para incluir o diretório "bin" no PATH do sistema).

Para verificar se o Ruby está corretamente instalado, execute o comando "ruby -v", que retornará no console a versão que está rodando.

Para instalar o Sass, basta executar o comando abaixo no console.
gem install sass

Criando o primeiro arquivo SCSS

O Sass trabalha com arquivos com a extensão "scss". Esses arquivos, se estiverem sendo "monitorados" pelo Sass, serão - sempre que alterados e salvos - convertidos automaticamente em arquivos ".css" correspondentes. Os arquivos ".css" é que serão interpretados pelo navegador, como de costume.

Dessa forma, o desenvolvedor vai criar e alterar apenas os arquivos ".scss", deixar com que o Sass converta esses arquivos e vai então fazer o deploy da aplicação usando apenas os arquivos ".css" que forem gerados.

Para fazer o primeiro teste, crie um arquivo "estilos.scss" com um bloco de notas e execute o comando abaixo para que o Sass comece a fazer o seu monitoramento.
sass --watch estilos.scss:estilos.css

O arquivo "estilos.css" será então automaticamente criado e, daqui pra frente, sempre que o arquivo "estilos.scss" for alterado, o arquivo "estilos.css" será imediatamente atualizado.

Para fazer o teste, inclua o conteúdo abaixo no "estilos.scss", salve o arquivo e abra o "estilos.css" para observar seu conteúdo.
#navbar {
  width: 80%;
  height: 23px;
}

Como o que foi inserido é CSS padrão, o arquivo "estilos.css" vai ficar com o mesmo conteúdo (com exceção do fechamento do colchete, que ficará logo após o último ";" - mas isso é configurável no Sass).

Obs.: Para se trabalhar com múltiplos arquivos ao mesmo tempo, pode-se fazer o Sass monitorar um diretório inteiro de arquivos ".scss", sendo gerados os arquivos ".css" em outro diretório, conforme o exemplo abaixo:
sass --watch diretorio_base/sass:diretorio_base/compiled


Conhecendo as funcionalidades do Sass

Bom, até agora geramos um arquivo ".css" utilizando um arquivo ".scss", mas com o conteúdo de um CSS tradicional. Agora, vamos ao que interessa: as funcionalidades que são o diferencial do Sass e fazem com que ele se torne uma ferramenta poderosíssima no apoio ao desenvolvimento de páginas ou sistemas Web.

1. Aninhamento ("Nesting")

Ao escrevermos um CSS, com frequência acabamos tendo que repetir muitos seletores pais. Por exemplo, podemos ter "#navbar ul", "#navbar li" e "#navbar li a", conforme o exemplo abaixo.
#navbar {
  width: 80%;
  height: 23px; 
}
  #navbar ul {
    list-style-type: none; 
  }
  #navbar li {
    float: left; 
  }
    #navbar li a {
      font-weight: bold; 
    }

Para declarar esse conteúdo em um arquivo Sass, sem ter que ficar repetindo os seletores, podemos fazer uso do recurso de aninhamento, conforme pode ser visto abaixo.
#navbar {
  width: 80%;
  height: 23px;
  ul { list-style-type: none; }
  li {
    float: left;
    a { font-weight: bold; }
  }
}

Obs.: Também é possível aninhar propriedades. Por exemplo, com o Sass não é preciso ficar repetindo o "border-", "border-left" e "border-right", como no exemplo abaixo.
.fakeshadow {
  border-style: solid;
  border-left-width: 4px;
  border-left-color: #888;
  border-right-width: 2px;
  border-right-color: #ccc;
}
Ao invés disso, pode-se utilizar o aninhamento, facilitando a leitura e manutenção desse conteúdo:
.fakeshadow {
  border: {
    style: solid;
    left: {
      width: 4px;
      color: #888;
    }
    right: {
      width: 2px;
      color: #ccc;
    }
  }
}

1.1. Pseudo-classes e referência ao pai

Outra coisa comum de ser feita no CSS é utilizar seletores contendo pseudo-classes como ":hover" e ":visited", conforme pode ser visto abaixo.
a {
  color: #ce4dd6;
}
  a:hover {
    color: #ffb3ff;
  }
  a:visited {
    color: #c458cb;
  }

No CSS, cada seletor desses deve fazer referência ao elemento "pai" (o "a", no exemplo acima). Já no Sass, a referência ao seletor pai pode ser substituída pelo caractere especial "&", fazendo-se o aninhamento dos seletores filhos (contendo as pseudo-classes) conforme abaixo.
a {
  color: #ce4dd6;
  &:hover { color: #ffb3ff; }
  &:visited { color: #c458cb; }
}

2. Variáveis

Um recurso interessante do Sass é a possibilidade de declaração de variáveis, que poderão ser reutilizadas muitas vezes na folha de estilos. Uma variável inicia com o caractere "$" e é declarada como se fosse uma propriedade normal do CSS, usando valores de atributos convencionais, conforme o exemplo abaixo.

Arquivo SCSS:
$cor-principal: #ce4dd6;
$estilo: solid;

#navbar {
  border-bottom: {
    color: $cor-principal;
    style: $estilo;
  }
}

a {
  color: $cor-principal;
  &:hover { border-bottom: $estilo 1px; }
}

Arquivo CSS gerado:
#navbar {
  border-bottom-color: #ce4dd6;
  border-bottom-style: solid;
}

a {
  color: #ce4dd6;
}
  a:hover {
    border-bottom: solid 1px;
  }

A grande vantagem de se utilizar variáveis é poder fazer uma alteração (por exemplo, de cor, tamanho ou característica) em um só lugar, e essa alteração se refletir em vários pontos da folha de estilos.

2.1. Operações e Funções

Além da utilização direta de variáveis, é possível utilizar operações matemáticas (+, -, *, / e %) e funções pré-definidas (para cores, números, strings, listas, fazer introspecção, etc) para cálculos dinâmicos de valores de propriedades, conforme o exemplo abaixo.

Arquivo SCSS:
#navbar {
  $navbar-width: 800px;
  $items: 5;
  $navbar-color: #ce4dd6;

  width: $navbar-width;
  border-bottom: 2px solid $navbar-color;

  li {
    float: left;
    width: $navbar-width/$items - 10px;
    background-color: lighten($navbar-color, 20%);
    &:hover {
      background-color: lighten($navbar-color, 10%);
    }
  }
}

Arquivo CSS gerado:
#navbar {
  width: 800px;
  border-bottom: 2px solid #ce4dd6; }
  #navbar li {
    float: left;
    width: 150px;
    background-color: #e5a0e9; }
    #navbar li:hover {
      background-color: #d976e0; }

2.2. Interpolação

Além de serem utilizadas para atribuição de valores de propriedades, as variáveis podem compor o nome de propriedades e seletores, através do uso de "#{}", conforme pode ser observado abaixo.

Arquivo SCSS:
$vert: top;
$horz: left;
$radius: 10px;
.rounded-#{$vert}-#{$horz} {
  border-#{$vert}-#{$horz}-radius: $radius;
  -moz-border-radius-#{$vert}#{$horz}: $radius;
  -webkit-border-#{$vert}-#{$horz}-radius: $radius;
}

Arquivo CSS gerado:
.rounded-top-left {
  border-top-radius: 10px;
  -moz-border-radius-top: 10px;
  -webkit-border-top-radius: 10px; }

3. Mixins

O mixin é um dos recursos mais poderosos do Sass - ele permite o reuso de estilos, ao invés de ficar copiando e colando trechos de código.

Para se criar um mixin, basta usar a diretiva "@mixin", dar um nome para ele, e criar um bloco com os estilos que serão reutilizados. E, para utilizar um mixin, basta usar a diretiva "@include".

Arquivo SCSS:
@mixin rounded-top-left {
  $vert: top;
  $horz: left;
  $radius: 10px;

  border-#{$vert}-#{$horz}-radius: $radius;
  -moz-border-radius-#{$vert}#{$horz}: $radius;
  -webkit-border-#{$vert}-#{$horz}-radius: $radius;
}

#navbar li { @include rounded-top-left; }
#footer { @include rounded-top-left; }

Arquivo CSS gerado:
#navbar li {
  border-top-left-radius: 10px;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px; }

#footer {
  border-top-left-radius: 10px;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px; }

3.1. Utilizando argumentos nos Mixins

O grande poder no uso dos mixins é a possibilidade de criar argumentos para eles. Dessa forma, pode-se passar parâmetros diferentes cada vez que um mixin for utilizado. Além disso, as variáveis declaradas como argumentos podem ter valores padrões, para o caso de não serem passados nenhum valor pra elas.

Arquivo SCSS:
@mixin rounded($vert, $horz, $radius: 10px) {
  border-#{$vert}-#{$horz}-radius: $radius;
  -moz-border-radius-#{$vert}#{$horz}: $radius;
  -webkit-border-#{$vert}-#{$horz}-radius: $radius;
}
#navbar li { @include rounded(top, left); }
#footer { @include rounded(top, left, 5px); }
#sidebar { @include rounded(top, left, 8px); }

Arquivo CSS gerado:
#navbar li {
  border-top-left-radius: 10px;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px; }
#footer {
  border-top-left-radius: 5px;
  -moz-border-radius-topleft: 5px;
  -webkit-border-top-left-radius: 5px; }
#sidebar {
  border-top-left-radius: 8px;
  -moz-border-radius-topleft: 8px;
  -webkit-border-top-left-radius: 8px; }

4. A diretiva @import e os arquivos "partials"

O CSS tradicional já possui a diretiva "@import" para que seja possível quebrar um arquivo de folha de estilos grande em arquivos menores e facilitar a organização e manutenção do código. O problema é que para cada arquivo referenciado em um @import dentro de um CSS é feita uma requisição HTTP separada, o que pode deixar o carregamento da página mais lento.

Dessa forma, no Sass, a diretiva "@import" faz com que as folhas de estilos referenciadas no arquivo SCSS sejam automaticamente injetadas no arquivo CSS gerado. Assim, mantêm-se a organização das folhas de estilo, sem se ter esse overhead a mais no carregamento das páginas.

Esses arquivos importados são chamados de "partials" e, por convenção do Sass, sempre têm seus nomes iniciados por "_".

No exemplo abaixo, o arquivo "estilos.scss" importa o arquivo "_rounded.scss" e o arquivo css correspondente (gerado pelo Sass) vai ser o "estilos.css".

_rounded.scss
@mixin rounded($vert, $horz, $radius: 10px) {
  border-#{$vert}-#{$horz}-radius: $radius;
  -moz-border-radius-#{$vert}#{$horz}: $radius;
  -webkit-border-#{$vert}-#{$horz}-radius: $radius;
}

estilos.scss
@import "rounded";
#navbar li { @include rounded(top, left); }
#footer { @include rounded(top, left, 5px); }
#sidebar { @include rounded(top, left, 8px); }

estilos.css
#navbar li {
  border-top-left-radius: 10px;
  -moz-border-radius-topleft: 10px;
  -webkit-border-top-left-radius: 10px; }

#footer {
  border-top-left-radius: 5px;
  -moz-border-radius-topleft: 5px;
  -webkit-border-top-left-radius: 5px; }

#sidebar {
  border-top-left-radius: 8px;
  -moz-border-radius-topleft: 8px;
  -webkit-border-top-left-radius: 8px; }


Considerações finais

Bom, o que foi apresentado até agora foi apenas um apanhado geral do funcionamento e das principais funcionalidades do Sass. É interessante também dar uma olhada na documentação de referência do Sass para conhecer detalhes do que foi apresentado e mais algumas funcionalidades não citadas nesse post.


Referências utilizadas: grande parte dessas informações foram tiradas do site oficial do Sass, sendo feita uma seleção, tradução, interpretação, organização e complementação com outras informações.


Nenhum comentário: