Por que documentação e acordos de linting viram “infraestrutura” do CSS
Em times, CSS não falha apenas por “código ruim”, mas por falta de acordos explícitos. Quando cada pessoa escreve estilos com suposições diferentes (sobre onde colocar um arquivo, como nomear, quando criar uma variação, como lidar com exceções), o resultado é imprevisibilidade: revisões demoradas, retrabalho, divergências visuais e dificuldade de refatorar com segurança. Documentação e linting funcionam como infraestrutura: reduzem decisões repetidas, tornam o código revisável e criam um padrão verificável automaticamente.
Neste capítulo, o foco é como documentar e manter a arquitetura em equipe por meio de: guidelines (regras e exemplos), referências vivas (exemplos canônicos) e acordos de linting/formatting (checagens automáticas que impedem regressões). A ideia não é produzir um “manual gigante”, e sim um conjunto pequeno de regras com exemplos claros, mais automação para garantir consistência.
O que deve existir: três artefatos essenciais
1) Guidelines (guia de estilo do código)
Guidelines são regras de escrita e organização do CSS que respondem perguntas do dia a dia: “onde coloco isso?”, “como nomeio?”, “quando crio um novo componente?”, “como faço uma variação?”, “o que é permitido e o que é proibido?”. O guia deve ser curto, objetivo e orientado a decisões frequentes. Ele não substitui o código; ele reduz ambiguidade.
2) Exemplos de referência (canônicos)
Exemplos de referência são implementações reais (ou quase reais) que servem como “padrão ouro”. Em vez de explicar tudo em texto, você aponta para um componente exemplar e diz: “faça como aqui”. Isso é especialmente útil para padrões repetidos: botões, campos, cards, modais, tabelas, estados, temas, densidade, etc. Exemplos canônicos também ajudam novos membros a aprenderem mais rápido e ajudam revisores a terem um baseline.
3) Acordos de linting e formatting (checagem automática)
Linting e formatting são a parte “executável” das guidelines: regras que o time concorda e que o CI (ou o editor) valida. O objetivo não é punir, e sim evitar que inconsistências entrem no repositório. Linting bem configurado diminui discussões em PR sobre detalhes e protege o time contra regressões silenciosas (por exemplo, uso de cores hardcoded quando tokens são obrigatórios, ordem inconsistente de propriedades, seletores proibidos, etc.).
Continue em nosso aplicativo
Você poderá ouvir o audiobook com a tela desligada, ganhar gratuitamente o certificado deste curso e ainda ter acesso a outros 5.000 cursos online gratuitos.
ou continue lendo abaixo...Baixar o aplicativo
Como escrever guidelines que realmente funcionam
Princípios para um guia útil
- Decisões, não teoria: foque em “faça X” / “não faça Y” com exemplos.
- Curto e navegável: prefira seções pequenas e repetíveis (ex.: “Objetivo”, “Regra”, “Exemplo”, “Exceções”).
- Comportamento esperado em PR: descreva o que o revisor deve checar e o que o autor deve garantir.
- Exceções explícitas: se algo é permitido “às vezes”, documente quando e como.
- Versionável: mantenha no repositório (ex.: /docs) para evoluir junto do código.
Estrutura sugerida para o documento
Uma estrutura simples que costuma funcionar:
- Visão geral: objetivo do CSS no projeto e o que o time valoriza (consistência, previsibilidade, acessibilidade, performance).
- Regras de escrita: convenções de nomenclatura, limites de seletor, padrões de variação/estado, uso de tokens.
- Regras de organização: onde cada tipo de estilo vive, como criar novos arquivos, como importar/registrar.
- Padrões de componentes: checklist mínimo para criar/alterar componente (estrutura, estados, responsividade, acessibilidade visual).
- Exceções e “escape hatches”: quando usar !important, quando criar utilitário, como lidar com legado.
- Linting e tooling: como rodar localmente, como corrigir, como interpretar erros.
Exemplos de guidelines (com “faça/não faça”)
Regra: tokens são a fonte de verdade para valores de design
Faça: use custom properties/tokens para cor, espaçamento, tipografia, raio e sombra.
.c-alert { padding: var(--space-3); border-radius: var(--radius-2); background: var(--color-surface-warning); color: var(--color-text-on-warning);}Não faça: introduza valores “soltos” sem justificativa.
.c-alert { padding: 12px; border-radius: 6px; background: #ffefc2;}Exceção documentada: valores “one-off” podem existir apenas se forem parte de uma correção temporária com ticket e prazo, ou se forem valores técnicos (ex.: 1px para hairline) e ainda assim preferencialmente tokenizados.
Regra: cada componente deve ter um exemplo canônico
Faça: ao criar/alterar um componente, mantenha um exemplo de referência em um local acordado (ex.: pasta de exemplos, story, página interna de UI). O exemplo deve cobrir estados essenciais (default, hover/focus/disabled, variações principais).
Não faça: depender apenas de prints no PR ou de “testar na tela X” como validação.
Regra: estados e variações precisam ser previsíveis
Faça: documente quais estados existem e como são aplicados (classe, atributo, data-*, etc.).
/* Estado via data-attribute (exemplo) */.c-button[data-loading="true"] { cursor: progress; opacity: 0.7;}Não faça: criar estados “secretos” que só funcionam em uma tela específica sem documentação.
Regra: comentários são para intenção, não para repetir o óbvio
Faça: comente quando houver uma decisão não trivial (workaround, dependência, motivo de um valor).
.c-modal { /* Evita scroll chaining em iOS dentro do container */ overscroll-behavior: contain;}Não faça: comentar o que o código já diz claramente.
/* Define a cor do texto */.c-modal { color: var(--color-text);}Exemplos de referência: como criar uma “biblioteca viva” sem burocracia
O que um exemplo canônico precisa conter
- Markup mínimo: HTML representativo (sem dependências desnecessárias).
- Variações suportadas: tamanhos, temas, densidade, alinhamentos.
- Estados: hover, focus-visible, disabled, loading, erro/sucesso (quando aplicável).
- Casos de borda: texto longo, quebra de linha, ícone opcional, ausência de conteúdo.
- Notas de uso: 3–6 bullets sobre quando usar e quando não usar.
Formato prático de referência (modelo)
Você pode padronizar um arquivo de referência por componente, por exemplo: button.reference.html e button.reference.css (ou equivalente no stack do projeto). O importante é que seja fácil de rodar e revisar.
<!-- button.reference.html --><button class="c-button c-button--primary" type="button">Salvar</button><button class="c-button c-button--secondary" type="button">Cancelar</button><button class="c-button c-button--primary" type="button" disabled>Salvando...</button>Inclua também um “caso de borda”:
<button class="c-button c-button--primary" type="button">Texto muito longo que deve quebrar corretamente sem estourar o layout</button>Como manter exemplos sincronizados com o código
- Regra de PR: “mudou componente, atualize referência”.
- Checklist do revisor: verificar se o exemplo cobre a mudança.
- Automação opcional: teste visual/snapshot (quando existir no projeto) apontando para os exemplos canônicos.
Acordos de linting: o que vale a pena automatizar
Nem tudo precisa virar regra de lint. O que mais traz retorno é aquilo que: (1) é fácil de verificar automaticamente, (2) gera inconsistência quando não é seguido, (3) causa bugs visuais ou dificulta manutenção.
Categorias de regras recomendadas
- Erros reais: propriedades inválidas, valores inválidos, duplicidade de propriedades, seletores impossíveis.
- Consistência: ordem de propriedades, espaçamento, casing, aspas, zeros, notação de cores.
- Arquitetura: proibir padrões que quebram acordos (ex.: IDs, seletores muito específicos, uso de !important fora de exceções).
- Tokens: restringir cores hardcoded, fontes hardcoded, z-index arbitrário, etc.
- Compatibilidade: regras para evitar propriedades sem fallback quando necessário (dependendo do suporte do projeto).
Stylelint como base (exemplo de configuração)
Um caminho comum é usar Stylelint para CSS/SCSS e adicionar plugins conforme a necessidade. Abaixo, um exemplo ilustrativo de .stylelintrc.json com regras típicas de equipe. Ajuste ao seu stack e ao que o time realmente consegue manter.
{ "extends": ["stylelint-config-standard"], "plugins": ["stylelint-order"], "rules": { "color-no-hex": true, "declaration-no-important": true, "selector-max-id": 0, "selector-max-specificity": "0,3,0", "max-nesting-depth": 2, "order/properties-alphabetical-order": true, "declaration-block-no-duplicate-properties": true }}Como ler esse acordo: hex proibido força uso de tokens (ou ao menos evita “#123456” espalhado). selector-max-id impede IDs. selector-max-specificity limita escalada de especificidade. max-nesting-depth controla aninhamento (especialmente útil em SCSS). Regras de ordem reduzem diffs e discussões.
Regras para tokens: como aplicar sem travar o time
Se o projeto usa tokens via custom properties, você pode adotar uma regra de “lista permitida” para cores e fontes, ou uma regra de “banir valores” (ex.: hex, rgb). O ponto crítico é prever exceções: imagens inline, gradientes específicos, valores técnicos. Documente o processo de exceção.
Exemplo de guideline + linting:
- Guideline: “cores devem ser
var(--color-*); exceções exigem comentário com ticket”. - Lint: proibir
#em valores de cor e proibirrgb()/hsl()se isso for compatível com o projeto.
Formatting: Prettier (ou equivalente) para reduzir ruído
Separar “formatting” de “linting” evita conflitos. Formatting deve ser automático e sem debate: indentação, quebras, espaços, ordem simples. Linting fica para regras semânticas e arquiteturais. Se o time adota Prettier, combine com Stylelint de forma que um não brigue com o outro (por exemplo, desabilitando regras de estilo que o formatter já resolve).
Passo a passo prático: implementar documentação + linting em um repositório existente
Passo 1 — Levantar decisões recorrentes e pontos de atrito
Faça um inventário rápido com o time (30–60 minutos):
- Quais discussões se repetem em PRs? (nomeação, onde colocar estilos, ordem, tokens, exceções)
- Quais bugs visuais acontecem por inconsistência? (valores soltos, variações não documentadas, estados faltando)
- Quais partes do CSS são mais sensíveis? (componentes base, temas, responsividade)
O resultado deve ser uma lista de 10–20 decisões que merecem guideline e/ou lint.
Passo 2 — Criar um guia mínimo (MVP) com regras acionáveis
Crie um arquivo único (ex.: /docs/css-guidelines.md ou equivalente) com 8–12 regras no máximo para a primeira versão. Para cada regra, use o formato:
- Regra
- Motivo (1–2 frases)
- Faça / Não faça com snippet
- Exceções (se existirem)
Evite tentar documentar tudo de uma vez. O guia cresce conforme o time encontra novos casos.
Passo 3 — Eleger 3 componentes como referência canônica
Escolha componentes que aparecem em muitas telas e que costumam gerar variações: por exemplo, botão, campo de texto e card. Crie exemplos de referência cobrindo:
- Variações principais
- Estados essenciais
- Casos de borda
Adicione no guia links diretos para esses exemplos e declare: “novos componentes devem ter referência equivalente”.
Passo 4 — Adotar linting com foco em alto impacto e baixa fricção
Comece com um conjunto pequeno de regras:
- Erros: propriedades inválidas, duplicadas
- Arquitetura: proibir IDs, limitar especificidade, limitar nesting
- Consistência: ordem de propriedades (se o time aceitar)
Evite iniciar com regras que gerem centenas de violações no legado sem plano. Se houver muito legado, configure o lint para rodar apenas em arquivos alterados (ou use um baseline) e vá apertando as regras progressivamente.
Passo 5 — Integrar ao fluxo: scripts locais e CI
Defina comandos padrão no projeto (exemplos genéricos):
{ "scripts": { "lint:css": "stylelint \"src/**/*.{css,scss}\"", "lint:css:fix": "stylelint \"src/**/*.{css,scss}\" --fix" }}Em CI, rode lint:css para bloquear violações novas. Localmente, incentive lint:css:fix antes de abrir PR.
Passo 6 — Criar um checklist de PR específico para CSS
Mesmo com lint, algumas coisas exigem revisão humana. Um checklist curto no template de PR ajuda:
- Atualizei/adicionei exemplo de referência do componente (quando aplicável)
- Não introduzi valores visuais fora de tokens (ou documentei exceção)
- Estados essenciais foram considerados (focus-visible, disabled, loading/erro quando aplicável)
- Não criei dependência implícita de contexto (o componente funciona no exemplo canônico)
Passo 7 — Processo de exceção: como quebrar regras sem virar bagunça
Regras rígidas sem escape geram “gambiarras silenciosas”. Defina um processo simples:
- Exceção temporária: permitido com comentário + ticket + prazo.
- Exceção permanente: exige atualização da guideline e, se necessário, ajuste do lint.
- Exceção local: permitida apenas em arquivo/trecho com anotação clara do motivo.
Exemplo de comentário de exceção:
.c-legacy-banner { /* Exceção: cor hardcoded por dependência de imagem do parceiro. Ticket: UI-1842 */ background: #0b1f3a;}Manutenção contínua: como evitar que a documentação “apodreça”
Documentação como parte do Definition of Done
Para mudanças que alteram comportamento de um componente (nova variação, novo estado, mudança de token), inclua no DoD: “atualizar referência e guideline se a regra mudou”. Isso evita que o guia vire um arquivo esquecido.
Revisões periódicas curtas (e objetivas)
Em vez de “refazer o guia”, faça revisões pequenas:
- Mensal: remover regras que ninguém segue e entender por quê
- A cada grande entrega: adicionar 1–2 regras novas que surgiram em PRs
- Quando o lint gera ruído: ajustar regra ou criar exceção documentada
Como lidar com divergências no time
Quando houver desacordo, evite debates abstratos. Use um critério operacional:
- Qual opção reduz mais retrabalho em 3 meses?
- Qual opção é mais fácil de automatizar?
- Qual opção é mais fácil de ensinar para alguém novo?
Se ainda assim houver empate, escolha uma, documente e siga. Consistência costuma valer mais do que a “melhor” preferência individual.
Modelo de “CSS Working Agreement” (acordo de equipe) para colar no repositório
Um acordo curto, no estilo “contrato social” do CSS, ajuda a alinhar expectativas. Exemplo:
- Usamos tokens para valores visuais; exceções precisam de justificativa e ticket.
- Todo componente alterado deve ter exemplo canônico atualizado.
- Linting é obrigatório no CI; PRs não devem desabilitar regras sem discussão.
- Novas regras de lint entram em modo “warning” por 1 semana (quando aplicável) antes de virar bloqueio.
- Quando uma regra atrapalhar, ajustamos a regra (ou a guideline) em vez de ignorar silenciosamente.
Erros comuns ao documentar e lintar CSS em equipe (e como evitar)
Guia grande demais e sem exemplos
Se o guia vira um texto longo sem snippets, ninguém consulta. Prefira regras curtas com exemplos “faça/não faça” e links para referências.
Lint agressivo em base legada sem estratégia
Se o lint falha em centenas de arquivos, o time vai desativar. Comece pequeno, rode em arquivos alterados, ou crie um baseline e reduza a dívida aos poucos.
Exemplos de referência que não representam o uso real
Se o exemplo é “bonito” mas não cobre estados e casos de borda, ele não protege o time. Garanta que todo exemplo tenha pelo menos um caso de texto longo, um estado de foco e uma variação principal.
Regras sem processo de exceção
Sem escape hatch, as pessoas criam exceções escondidas. Documente como exceções funcionam e como elas viram regra (ou são removidas).