Fácil de aprender, difícil de dominar. Não é porque tá funcionando que tá bom” –Raphael Fabeni sobre CSS
Dando continuidade a série sobre minha organização e fluxo de trabalho atual, vou contar um pouco sobre como tenho trabalhado o CSS.
“CSS é muito fácil!”. Será?
Durante anos escrevemos CSS como se não houvesse amanhã e tínhamos como maiores problemas as diferenças de renderização no IE(ca). E já não era simples.
Mas nos últimos tempos, tivemos que começar a fazer projetos que funcionassem em diferentes resoluções, diferentes navegadores, diferentes dispositivos e que tivessem performance, acessibilidade, fossem bonitos e escaláveis.
Além disso, o CSS começou a ser usado para animações (inclusive em SVG), controlar estados e até mesmo criar comportamentos que só eram feitos através de JavaScript.
Um CSS sem planejamento e mal construído pode arruinar um projeto, que a longo prazo vai virar um monstro, cheio de “janelas quebradas”.
O tal do Atomic Design
Junto com a necessidade de organizar o CSS, surgiram vários termos e metodologias que visam melhorar nosso controle sobre o código.
No último Meetup CSS, o Rafael Rinaldi deu uma verdadeira aula sobre diferentes tipos de Arquitetura CSS. Vocês podem assistir o vídeo e dar uma estudada nos slides.
Dentro dessas metodologias, a que mais me agradou foi o conceito de Atomic Design, proposta pelo Brad Frost, que deu origem ao Pattern Lab. Ela me agradou de cara, e ia de encontro com tudo que pensava sobre o desenvolvimento de CSS. Em 2013 eu já estava usando um conceito parecido e incorporei várias ideias no meu workflow.
Mas foi apenas no segundo semestre de 2014 que me aproximei de vez do Atomic Design e cheguei a uma estrutura muito parecida com a que foi proposta inicialmente.
Metodologias não precisam ser seguidas à risca e servem mais para nortear o trabalho. Portanto, considerem o que vou explicar abaixo uma livre interpretação do conceito original.
Organização dos arquivos CSS
Segue um esquema de organização com alguns exemplos de arquivos, mas lembre-se: são apenas exemplos e podem variar conforme o projeto.
Como sempre explico, estou dando um exemplo de estrutura em LESS, mas ela serve para QUALQUER pré-processador. Dentro das (), adicionei uma pequena descrição de cada pasta principal.
less/ ├── _core/ (Configurações básicas do projeto) │ ├── mixins/ │ |── colors │ ├── fonts │ ├── grid │ ├── margins │ ├── media-queries │ ├── mixins │ ├── normalize │ ├── type | ├── atoms/ (Classes individuais e elementos pequenos e reutilizáveis) │ ├── global/ │ | ├── scaffolding (html, body) │ | ├── utilies (.hidden, .show, .sr-only) | | │ ├── buttons/ │ | ├── btn │ | ├── btn-link | | │ ├── text/ │ | ├── headings (h1, h1, h3, h4, h5, h6) │ | ├── paragraph (p) │ | ├── blockquote │ | ├── code │ | ├── link (a) │ | ├── hr │ | ├── date (.date) │ | ├── inline (b, i, strong, em, u, stroke, cite ...) | | │ ├── list/ │ | ├── unordered │ | ├── ordered │ | ├── definition | | │ ├── images/ │ | ├── icons │ | ├── img │ | ├── logo | | │ ├── forms/ │ | ├── label │ | ├── input │ | ├── input-file │ | ├── select │ | ├── radio │ | ├── checkbox | | │ ├── tables/ │ ├── tables | ├── molecules/ (Cria um elemento 'pai' para modificar os atomos) │ ├── blocks/ │ | ├── toolbar │ | ├── filterbar | | │ ├── media/ │ | ├── banner │ | ├── media | | │ ├── forms/ │ | ├── search │ | ├── form-group | | │ ├── navigation/ │ | ├── navbar │ | ├── breadcrumbs │ | ├── pagination │ | ├── tabs | | │ ├── text/ │ | ├── address │ | ├── page-header │ | ├── author │ | ├── article-text │ | ├── captions | | │ ├── components/ (Componentes que usam JavaScript) │ ├── carousel │ ├── collapse │ ├── tooltip │ ├── popover │ ├── modal | ├── organisms/ (Estruturas maiores do projeto, que podem modificar átomos e móleculas) │ ├── header │ ├── footer │ ├── main │ ├── wrap │ ├── content │ ├── comments | ├── templates/ (Sistemas de grids e alinhamentos de templates) │ ├── grids │ ├── container │ ├── thumbnails | ├── pages/ (Estiliza páginas individualmente) │ ├── home | ├── vendor/ (Estiliza dependencias externas)
Exemplos práticos
Core
_core/margins:
//
// Margins
// --------------------------------------------------
@space: 20px; // Regular space margin
@space-xs: (@space / 4); // Extra small space margin
@space-sm: (@space / 2); // Small space margin
@space-md: (@space * 2); // Medium space margin
@space-lg: (@space * 3); // Large space margin
_core/type:
//
// Typography
// --------------------------------------------------
#type {
// Headings
// --------------------------------------------------
.h1() {
.font(36, 700);
margin-bottom: @space;
}
// Paragraphs
// --------------------------------------------------
.p1() {
.font(16);
}
}
Observem que defino alguns mixins e configurações reaproveitáveis em todo o projeto.
Atoms
Atoms/headings:
//
// Headings
// --------------------------------------------------
h1 {
margin: 0;
}
h1 {
#type > .h1();
}
atoms/paragraph:
//
// Paragraph
// --------------------------------------------------
p {
#type > .p1();
margin: 0 0 @space;
&:last-child {
margin: 0;
}
}
São definidas classes ou elementos bases, que serão utilizadas e modificadas conforme a necessidade das ‘molecules’, ‘organisms’ ou ‘pages’.
Os elementos devem ser únicos, nunca aninhados.
Molecules
Molecules/page-header:
//
// Page Header
// --------------------------------------------------
.page-header {
text-align: center;
h1 {
border-bottom: @gray-lighter solid 1px;
color: @gray-light;
padding-bottom: @space-sm;
}
p {
color: @gray;
}
}
Modifica os átomos para a criação de um componente específico.
Organisms
Organisms/header:
//
// Header
// --------------------------------------------------
.header {
// Page Header
// --------------------------------------------------
.page-header {
text-align: center;
}
}
Modifica os átomos e moléculas para a criação de uma sessão do projeto.
Pages
Pages/home:
//
// Home
// --------------------------------------------------
.home {
// Header
// --------------------------------------------------
.header {
position: fixed;
top: 0;
right: 0;
left: 0;
}
// Page Header
// --------------------------------------------------
.page-header {
padding: @space @space-lg;
}
}
Modifica os átomos, moléculas e organismos para a criação de uma página específica do projeto.
Dicas rápidas
- Não se prenda à metodologia. Abra espaço para implementar mudanças que vão melhorar a utilização, seja para uso próprio ou para um escopo especifico;
- A organização das pastas é muito importante. Você precisa se sentir confortável com a estrutura para não ficar pensando aonde está determinado arquivo;
- Não faça aninhamentos maiores do que três níveis – geralmente você não vai precisar passar do segundo nível. Quando chegar ao terceiro, ligue o sinal de alerta e confirme se realmente faz sentido;
- Lembre-se que seu workflow não é definitivo. Sempre surgirão ideias e ferramentas para agregar ao seu trabalho. Esteja de cabeça aberta para mudanças. Porém não faça alterações drásticas antes de amadurecer a ideia.
Um plus sobre ‘Media Queries’
No começo do ano eu escrevi um artigo sobre CSS Modular com Mobile First e agora essa ideia fica ainda mais aplicável.
Não precisa mais ter um arquivo específico para ajustar media-queries. Nessa organização de CSS, cada elemento pode ter sua própria customização aplicada seguindo a ideia do Mobile First.
Como?
Vamos imaginar que o .header precise ser absoluto em resoluções médias, fixo em resoluções grandes e tenha o background branco em telas menores:
organisms/header:
//
// Header
// --------------------------------------------------
.header {
padding: @space; // Padrão para todas as resoluções
@media (max-width: @screen-xs-max) {
background: #fff;
}
@media (min-width: @screen-sm-min) {
position: absolute;
top: 0;
right: 0;
left: 0;
}
@media (min-width: @screen-lg-min) {
position: fixed;
// O top, right e left está escalando na resolução 'sm', não precisa repetir :)
}
}
Se tiverem alguma dúvida ou quiserem debater sobre o assunto, saiba que o Disqus escala e podem usar os comentários sem medo.
Abraços!



