Refactoring UI
Design visual não é talento. É um pequeno conjunto de decisões sistêmicas tomadas uma vez, mais um punhado de técnicas para criar hierarquia. Este skill é esses sistemas e essas técnicas.
A maior causa única de interfaces com aparência amadora é escolher valores ad hoc — 17px aqui,
#3B82F6 ali, lighten(5%) para um estado de hover. Projete a partir de uma escala, sempre.
Os sistemas — use-os, não os derive novamente
Escolha a partir destas listas. Nunca invente um valor que não esteja em uma delas.
Espaçamento e dimensionamento
Base 16px, construído a partir de fatores e múltiplos:
4 8 12 16 24 32 48 64 96 128 192 256 384 512 640 768
Justo na extremidade pequena, espaçando na extremidade grande. Dois valores adjacentes não podem estar a menos de ~25% de distância — é isso que torna a escolha óbvia. Uma escala linear "múltiplos de 4" falha: não ajuda a decidir entre 120px e 124px.
Use para margem, padding, largura, altura, tamanhos de ícone, largura de borda — tudo que é espacial.
Fixe um pequeno conjunto de valores de opacidade também (por exemplo, .05 .1 .2 .4 .6 .8) para estados desabilitados, sobreposições e tons de hover, em vez de ajustar de olho a cada vez. Mesma lógica das outras escalas: decida uma vez, reutilize em todos os lugares.
Escala tipográfica
12 14 16 18 20 24 30 36 48 60 72
Não é uma escala modular construída a partir de uma proporção (4:5, 2:3, número áureo). Essas produzem valores fracionários de pixel que arredondam de forma inconsistente entre navegadores e são muito esparsos para a densidade de interfaces — valores escolhidos manualmente, por como se sentem, vencem.
Unidades: px ou rem apenas. Nunca em. em é relativo ao tamanho da fonte atual, então um .875em dentro de um pai 1.25em calcula para 17,5px — um valor que não está na sua escala. A escala silenciosamente deixa de existir.
Peso da fonte
Dois pesos são suficientes:
- 400 ou 500 — corpo e a maioria do texto de UI
- 600 ou 700 — qualquer coisa enfatizada
Nada abaixo de 400 em uma interface. Para desenfatizar, use uma cor mais clara ou um tamanho menor — nunca um peso mais leve.
Cor
Você precisa de muito mais cores do que um gerador de paletas de cinco amostras lhe dá.
- Cinzas: 8–10 tons. Quase toda uma interface é cinza — texto, fundos, painéis, bordas, controles de formulário. Três ou quatro tons sempre se esgotam. Comece com um cinza muito escuro, não preto verdadeiro (preto verdadeiro parece antinatural).
- Primária: 5–10 tons, uma ou talvez duas primárias.
- Acentos: 5–10 tons cada — vermelho destrutivo, amarelo de alerta, verde positivo, além do que o produto precisar para distinguir (séries de gráficos, eventos de calendário, tags). Dez cores × 5–10 tons é normal para uma interface complexa.
Nomeie-as 100 (mais clara) → 900 (mais escura), base 500.
Construa a escala nesta ordem: escolha 500 primeiro (para uma primária/acento, deve ser um tom que funcione como fundo de botão). Depois encontre as bordas — 900 geralmente é a cor do seu texto, 100 um tom de fundo; um componente de alerta usa ambos, então projete um e leia os dois valores dele. Em seguida, preencha 700 e 300 como o compromisso perfeito entre seus vizinhos, depois 800, 600, 400, 200 da mesma forma.
Escreva cores como HSL, não hex. hsl(220, 95%, 34%) e hsl(220, 65%, 61%) são visivelmente relacionadas; #03369E e #507DD7 não são.
Nunca gere tons em tempo de execução com lighten() / darken(). É assim que você acaba com 35 azuis ligeiramente diferentes.
Sombras — cinco elevações
0 1px 3px hsla(0,0%,0%,.2) /* levemente elevado — botões */
0 4px 6px hsla(0,0%,0%,.2) /* menus suspensos */
0 5px 15px hsla(0,0%,0%,.2)
0 10px 24px hsla(0,0%,0%,.2)
0 15px 35px hsla(0,0%,0%,.2) /* modais */
Escolha perguntando onde no eixo z isso se encontra?, não qual sombra parece legal?.
Mais perto do usuário = mais atenção. Diminuir a sombra de um botão no :active faz parecer que foi pressionado; aumentar a sombra de um item de lista quando é pego para arrastar e reordenar faz o oposto — lê-se como "agora acima de seus irmãos" e serve como a própria affordance de arrastar.
Estas cinco são o padrão e são boas em todos os lugares. references/techniques.md fornece uma versão refinada em duas partes da mesma escala — paralela, mas não com valores idênticos (seu degrau superior é mais pesado). Use-a quando as sombras forem proeminentes no design; use estas quando não forem. Não misture as duas em um projeto.
Altura de linha e comprimento de linha
A altura de linha é inversamente proporcional ao tamanho da fonte e proporcional à largura da linha:
- texto pequeno / colunas largas →
1.5a2 - títulos grandes →
1é suficiente
Comprimento de linha: 45–75 caracteres, ou seja, max-width: 20em–35em. Isso se aplica ao parágrafo mesmo quando o contêiner ao redor for mais largo — larguras mistas em uma área de conteúdo parecem mais polidas, não menos.
(em está correto aqui — a medida deve escalar com o texto que envolve. A regra "nunca em" está limitada à escala tipográfica, onde em se compõe através de aninhamento. Não "corrija" isso.
Raio de borda
Escolha um e seja consistente. Raio pequeno = neutro. Raio grande = lúdico. Nenhum = sério/formal. Misturar cantos quadrados e arredondados em uma interface sempre parece pior.
O procedimento
1. Comece com uma funcionalidade, não com um layout. Não projete "o aplicativo" — você não pode decidir entre navegação superior e barra lateral antes de saber o que há no produto. Projete uma peça real de funcionalidade (o formulário de busca, o compositor de mensagens) e deixe a estrutura emergir.
2. Detalhes vêm depois. Ignore tipos de fonte, sombras e ícones no início. Trabalhe em escala de cinza primeiro — isso força a hierarquia a vir de espaçamento, contraste e tamanho, em vez de cor. Adicione cor quando o layout funcionar.
3. Não invista demais em baixa fidelidade. Esboços, wireframes e protótipos são descartáveis — ninguém pode usar uma imagem estática de um aplicativo. Eles existem para explorar ideias; abandone-os assim que a decisão for tomada e vá construir a coisa real.
4. Projete a menor versão útil, depois construa-a. Trabalhe em ciclos curtos de design→código. Não implique funcionalidades que você não está pronto para construir — uma caixa de comentários com uma zona de anexos que você não pode enviar ainda bloqueia toda a funcionalidade. Itens "legais de ter" são projetados depois.
5. Escolha por eliminação. Ao escolher um valor de uma escala: adivinhe o que você acha que está certo, depois compare-o com o vizinho de cada lado. Dois estarão obviamente errados. Se uma opção externa vencer, refaça a comparação com ela como o novo meio.
6. Comece com muito espaço branco e remova-o. Adicionar espaço até que algo pare de ficar feio lhe dá o mínimo. Começar generoso e cortar lhe dá a quantidade certa. Interfaces densas (dashboards) são legítimas — mas como uma decisão deliberada, não como padrão.
7. Encolha a tela. Um componente pequeno projetado em uma prancheta de 1400px tende a se espalhar, porque o espaço está lá para ser preenchido. Comece com ~400px e projete o layout móvel primeiro, onde as restrições são reais — depois leve para uma tela grande e relaxe apenas o que genuinamente pareceu apertado. Você mudará menos do que espera.
Hierarquia — a técnica que faz mais trabalho
Tudo na tela está em uma pirâmide: primário, secundário, terciário. Quando tudo compete, a interface se lê como ruído. Isso é o que faz um design parecer "projetado" — não estilização.
Tamanho não é tudo. Depender apenas do tamanho da fonte lhe dá conteúdo primário que é grande demais e conteúdo secundário que é pequeno demais. Use peso e cor para carregar ênfase, e mantenha os tamanhos razoáveis.
Três cores de texto, no máximo:
- escuro — conteúdo primário
- cinza — conteúdo secundário
- cinza mais claro — conteúdo terciário (notas de rodapé, direitos autorais)
Todas as três carregam texto de tamanho de corpo real, então todas as três precisam de 4,5:1. "Cinza mais claro" significa o tom mais claro que ainda atende a isso — aproximadamente o meio de uma rampa de 9 degraus, não a extremidade pálida. Os tons pálidos são apenas para estados desabilitados e texto grande.
Enfatize desenfatizando. Quando o elemento importante não se destacar e não houver mais nada a adicionar a ele, suavize o que compete com ele. Escureça os itens de navegação inativos; reduza a cor de fundo da barra lateral para que o conteúdo principal fique à frente.
Ações: estilize por hierarquia, não por semântica.
- Primária → sólida, alto contraste. Geralmente exatamente uma por página.
- Secundária → contorno ou fundo de baixo contraste.
- Terciária → estilizada como um link.
Destrutivo ≠ botão vermelho grande. Se "Excluir" não for a ação primária na página, dê a ela tratamento terciário — depois torne-a um botão primário grande vermelho dentro do diálogo de confirmação, onde é genuinamente a ação primária.
Rótulos são um último recurso. rótulo: valor dá a cada dado o mesmo peso. A maioria dos dados se identifica por formato ($19,99, um endereço de email) ou por contexto. Onde um rótulo é genuinamente necessário, incorpore-o ao valor ("12 restantes em estoque", não "Em estoque: 12"), ou adicione-o como conteúdo visivelmente secundário. Exceção: em páginas no estilo de ficha técnica, onde os usuários escaneiam pelo rótulo, enfatize o rótulo.
Equilibre peso contra contraste. Ícones sólidos são visualmente pesados e vão superar o texto ao lado — suavize sua cor para compensar. Funciona ao contrário também: quando uma borda de 1px é muito sutil em uma cor suave, mas muito agressiva quando escurecida, mantenha a cor suave e vá para 2px. Adicione peso para corrigir baixo contraste; reduza contraste para corrigir excesso de peso.
Hierarquia visual ≠ hierarquia do documento. Marcação semântica e peso visual são decisões separadas. Títulos de seção são geralmente rótulos, não manchetes — um h1 em 16px é suficiente, e às vezes o título deve estar oculto visualmente porque o conteúdo fala por si.
Regras rígidas
Desviar-se destas produz uma falha específica e reconhecível.
- Nunca texto cinza em um fundo colorido. Cinza sobre branco funciona porque reduz contraste; cinza sobre cor parece sujo. Branco com opacidade reduzida parece desbotado e desabilitado, e deixa padrões aparecerem através dos glifos. Escolha manualmente uma cor com o matiz do fundo, ajustando saturação e luminosidade.
- Nunca
empara a escala tipográfica.pxourem. - Nunca gere tons em tempo de execução. Defina-os de antemão.
- Nunca use largura percentual para algo que não deve escalar. Barras laterais recebem larguras fixas; a área principal flexiona. Elementos recebem um
max-widthe só encolhem quando a tela é realmente menor — um cartão de login não deve ser mais largo em telas médias do que em grandes. - Nunca escale coisas proporcionalmente entre pontos de interrupção. Elementos grandes devem encolher mais rápido que os pequenos. Um cabeçalho de 2.5em sobre corpo móvel de 14px resulta em 35px — grande demais; ele deve ter 20–24px ali. Da mesma forma, o padding de um botão deve ficar proporcionalmente mais justo à medida que o botão encolhe, não escalar com seu tamanho de fonte.
- Sempre mais espaço ao redor de um grupo do que dentro dele. Esta é a correção para "qual rótulo pertence a qual campo", listas com marcadores apertadas e cabeçalhos que parecem ligados ao parágrafo errado. Espaçamento ambíguo é um bug funcional, não apenas um feio.
- Nunca use cor como o único sinal. Adicione um ícone, uma forma ou uma dica de texto. Para gráficos, distinga séries por contraste (tons claros→escuros de uma cor) em vez de por matiz — usuários daltônicos leem luminosidade de forma confiável, matiz nem tanto.
- Mínimos de contraste: 4,5:1 para texto normal. A margem de 3:1 se aplica apenas a texto grande, que o WCAG define como 24px regular ou 18,66px negrito — não 18px. Presuma 4,5:1 a menos que o texto seja genuinamente grande. Quando branco sobre cor falhar, inverta: texto colorido escuro sobre um tom claro (veja
references/systems.md). Separadamente, 3:1 se aplica a não-texto também (WCAG 1.4.11): se uma borda é a única coisa identificando um controle — um contorno de input, uma borda de checkbox — ela precisa de 3:1 contra seu fundo. Uma linha fina que apenas divide conteúdo não precisa. Esses são dois tokens diferentes, não um. - Nunca escale um ícone longe de seu tamanho pretendido. Um ícone de 16–24px em 48px parece grosso e com falta de detalhes. Coloque-o dentro de um círculo colorido.
Referências
assets/tokens.css — um conjunto inicial completo e verificado de contraste de todos os itens acima como propriedades personalizadas CSS: espaçamento, tipo, pesos, largura de borda, uma escala fixa de opacidade, uma rampa de 9 tons de cinza frio, uma primária de 9 tons, três trios de acento, cinco elevações, uma camada de papéis semânticos (--surface, --text-primary, --action…) e um bloco de modo escuro que substitui apenas esses papéis. Copie e ajuste os matizes em vez de derivar as escalas desta prosa. Faça referência aos papéis nos componentes, não às rampas brutas — é isso que faz o modo escuro funcionar. Cada par texto/superfície é verificado ≥4,5:1 em ambos os modos e cada borda funcional ≥3:1; os tons deliberadamente abaixo do limiar (desabilitados, divisores decorativos, a etapa apenas para texto grande) são isentos por critério e comentados inline.
Carregue estes quando o trabalho os exigir:
references/systems.md— construindo uma paleta do zero: escolhendo a cor base, mantendo a saturação viva nas extremidades clara e escura, rotação de matiz, cinzas quentes/frios e as duas saídas de emergência para atingir taxas de contraste sem cor feia.references/diagnose.md— tabela de sintoma → correção. Carregue primeiro sempre que a tarefa for melhorar uma interface existente em vez de construir uma nova.references/techniques.md— simulação de profundidade e luz, sombras em duas partes, alinhamento de baseline, espaçamento entre letras, quebra das formas padrão de componentes e manipulação de imagens enviadas pelo usuário.