Organizando CSS em Projetos Complexos #3 – Dicas Avançadas
Dicas avançadas
O motivo da estrutura apresentada nas primeiras duas partes da série ser tão complexa é porque a mesma propõe boas práticas de desenvolvimento e manutenção de estilos, além de visar aproveitar da melhor forma possível os recursos disponíveis. Para otimizar os resultados e o uso dos recursos ao máximo, algumas dicas avançadas de SASS se fazem pertinentes para manter um bom workflow trabalhando com o SassySkeleton e bibliotecas externas.
A pasta library
Traduzindo a introdução do arquivo README da pasta assets/sass/library
:
Este diretório deve ser composto de porções de código que não gerem CSS sozinhas. Isso deve permitir, entre outras coisas, que este diretório possa ser inteiramente reutilizado em outros projetos.
Dentro da estrutura desta pasta se utilizam recursos específicos de escrita de SASS, como variáveis, mixins, placeholders e funções, que não geram CSS quando o SASS é compilado, mas servem para serem aplicados em seletores que vão gerar. Ela é subdividida em quatro subpastas que ajudam a deixar a organização dos recursos mais modular. São elas:
- components: onde devem ser definidos estilos reutilizáveis para componentes da interface e onde deve ficar, num cenário ideal, a maior parte da escrita dos estilos.
- extensions: esta pasta é destinada, principalmente, a extensões de Compass, para serem mais facilmente importadas nos arquivos de SASS. Extensões de Bower, gerenciador de pacotes recomendado no artigo anterior, também podem ser alocadas aqui, mas é preciso tomar cuidado para não gerar CSS a partir desta pasta, como mencionado. O próprio autor do SassySkeleton prevê o Bower como solução para isso, no README desta pasta, mas ainda não há certeza de como ficaria uma estrutura destes componentes, porque muitas bibliotecas geram CSS sozinhas, então por isso neste exemplo estão sendo mantidas fora da arquitetura de SASS. Outro motivo é que extensões nem sempre são exclusivamente de CSS, então todas as bibliotecas de front-end, sejam elas de Javascript ou CSS, ficam no mesmo lugar.
- settings: deve conter configurações relativas aos elementos de interface, como cores, fontes, dimensões básicas, etc. Os arquivos nesta pasta normalmente contém variáveis para definir os valores de estilos, mas isso não é uma restrição.
- sprites: prevê onde ficam alocados os sprites gerados com Compass, que possui uma ótima ferramenta para isso (http://compass-style.org/help/tutorials/spriting/).
Tá, e daí?
Tendo entendido melhor como funciona a estrutura de estilos aqui proposta, e também como usar bibliotecas externas de forma limpa e sem muitas complicações, é hora de avançar um pouco mais na organização do projeto. Para isso, é importante manter uma boa relação entre a arquitetura interna de estilos e o uso de estilos externos.
É altamente recomendado, sempre que possível, usar bibliotecas que forneçam seu código também em SASS, pois assim elas podem prover formas mais avançadas de seu uso dentro de uma arquitetura complexa. Algumas dessas formas serão detalhadas a seguir.
Para melhor exemplificar os recursos, será usada de exemplo uma biblioteca mais complexa, o Foundation (http://foundation.zurb.com/) que, por fornecer variados recursos, facilitará a amostragem de casos de uso. Basta rodar o comando bower install --save foundation
na pasta /assets
, adicionar o caminho ao arquivoassets/sass/config.rb
e importar o arquivo base do Foundation no arquivo assets/sass/source/main.sass
.
config.rb
# =================================
# Vendor Settings
# =================================
# Add importing paths to use vendor's partials that reside outside
# this directory.
# add_import_path '../../path/to/other/project'
add_import_path '../bower_components/unsemantic/assets/sass'
add_import_path '../bower_components/foundation/scss'
main.sass
// ------------------------------------
// Import outputing extensions.
// ------------------------------------
// @import normalize
@import unsemantic-grid-base
@import foundation
Existem formas mais avançadas de usar e importar o Foundation, vale a pena consultar sua documentação para SASS (http://foundation.zurb.com/docs/sass.html) para não importar o projeto inteiro.
Sobrescrevendo variáveis
Ao se usar uma biblioteca que traga várias coisas prontas, como faz o Foundation, é normal desejar usar ao máximo os padrões que são oferecidos. Alguns ajustes e customizações, entretanto, são comumente necessários. E há formas de fazer isso sem fugir da estrutura já oferecida, aproveitando definições já implementadas.
O caso das variáveis é um dos mais corriqueiros: pode ser necessário que a cor principal do site não seja a mesma do Foundation, mas para isso não é necessário criar uma nova variável. Sobrescrever a variável do Foundation já é o suficiente e também mais útil, porque mixins da biblioteca que usam essa variável já serão implementados com a cor nova, por exemplo.
A documentação recomenda que seja alterado o arquivo_settings.scss
presente, neste caso, em assets/bower_components/foundation/scss/foundation
, descomentando e alterando as variáveis para alterar o resultado final. Neste caso, porém, as variáveis serão sobrescritas dentro da arquitetura do SassySkeleton, para melhor centralizar as definições de estilos e poder usar a mesma abordagem para diferentes bibliotecas, caso necessário, e o arquivo _settings.scss
será usado apenas como referência.
Neste arquivo, encontra-se a variável $primary-color: #008CBA;
. Ela recebe um tom de azul padrão do Foundation. Caso o projeto em questão tenha como cor primária um tom de verde, por exemplo, basta sobrescrever a variável no arquivoassets/sass/library/settings/colors.sass
com o valor desejado:
// Foundation overwritten color variables.
$primary-color: #00AA00
Vale ressaltar duas coisas: o novo valor da variável só será válido para estilos escritos depois de sobrescrevê-la e deve-se ter atenção à sintaxe, já que o exemplo está sendo escrito em SASS e a biblioteca em SCSS.
Agrupando extends e mixins
A partir do SASS, existem basicamente duas formas de usar os estilos dos componentes do Foundation: usar os estilos básicos, estendendo as classes com @extend .classe-foo
, ou customizar os estilos, usando os mixins que ele provê na documentação.
É muito comum, no entanto, precisar estender duas ou mais classes no mesmo elemento mais de uma vez, ou algo semelhante envolvendo mixins. Para modularizar ainda mais a arquitetura, é possível criar novos mixins contemplando isso.
Exemplo: sempre que for usada a lógica de colunas do foundation, é necessário um container com os estilos da classe row
. É necessário, também, que os itens dispostos em coluna sempre tenham a classecolumns
. Pensando assim, a única coisa que realmente varia é o número de colunas. Um mixin poderia resolver isso, usando o número de colunas como argumento, escrito no arquivoassets/sass/library/components/columns.sass
:
// General columns classes aplication.
=columns($large, $small)
@extend .row
> *
@extend .column
@extend .large-#{$large}
@extend .small-#{$small}
Para melhor exemplificar, será criada uma lista no arquivoindex.html
e nela será usado este mixin e a classe sobrescrita anteriormente no arquivo assets/sass/partials/base.sass
:
index.html
…
<body>
<header>
<nav>
<ul>
<li>Your menu</li>
</ul>
</nav>
</header>
<h2>Foundation columns example. Resize the page to test.</h2>
<ul class="foundation-example">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
...
base.sass
.foundation-example
+columns(4, 6)
padding-bottom: 5rem
list-style: none
li
background-color: $primary-color
text-align: center
line-height: 5em
font-weight: bold
color: white
&:nth-child(odd)
opacity: 0.8
Estilos condicionais
É possível aprofundar ainda mais: o mixin criado acima pode estar também sendo aplicado de forma repetitiva dentro do sistema, tendo sempre casos com 4 colunas para desktop e 3 para mobile ou 2 para desktop ou 1 para mobile. Conhecendo isso como um requisito dos sistema, é possível abstrair inclusive qual estilo da biblioteca será aplicado, tratando os componentes de forma semântica.
index.html
...
<ul class="foundation-example">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
<ul class="foundation-example-2">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
...
columns.sass
// General columns classes aplication.
=columns($large, $small)
@extend .row
> *
@extend .column
@extend .large-#{$large}
@extend .small-#{$small}
=columns-translate($how-much)
@if $how-much == many
+columns(3, 4)
@else if $how-much == few
+columns(6, 12)
base.sass
%foundation-example
padding-bottom: 5rem
list-style: none
li
background-color: $primary-color
text-align: center
line-height: 5em
font-weight: bold
color: white
&:nth-child(odd)
opacity: 0.8
.foundation-example
+columns(4, 6)
@extend %foundation-example
.foundation-example-2
+columns-translate(few)
@extend %foundation-example
Já é uma base
Com essas dicas avançadas, já se pode ter um significativo avanço na modularidade dos estilos. Vale frisar que as ferramentas apresentadas possuem mais recursos e inclusive mais avançados do que os apresentados aqui, e que um estudo contínuo desses recursos sempre tem a melhorar a experiência do desenvolvedor e o código desenvolvido.