Ui ux

Escopo: transversal. Aplica-se a qualquer linguagem ou stack do projeto.

A interface é o contrato entre o sistema e quem o usa. Cada decisão de espaçamento, cor, hierarquia e estado comunica alguma coisa ao usuário. Quando essas decisões são inconsistentes, ele precisa de mais esforço para entender o que o sistema oferece.

Conceitos fundamentais

ConceitoO que é
Padding (preenchimento interno)Espaço entre o conteúdo e a borda de um container
Token (valor nomeado do sistema de design)Variável semântica que representa um valor de design (cor, espaçamento, tipografia)
Viewport (área visível da tela)Porção da tela disponível para renderização no momento
WCAG (Web Content Accessibility Guidelines · Diretrizes de Acessibilidade para Conteúdo Web)Padrão internacional de acessibilidade para conteúdo web, com níveis A, AA e AAA
ARIA (Accessible Rich Internet Applications · Aplicações de Internet Ricas Acessíveis)Atributos HTML que complementam a semântica nativa para padrões complexos de UI
Skeleton (esqueleto de carregamento)Placeholder visual que representa o formato do conteúdo enquanto os dados carregam
Toast (notificação temporária)Mensagem de feedback exibida brevemente na interface, sem interromper o fluxo do usuário
Surface (superfície)Plano visual que sustenta conteúdo: o fundo da página, um painel, um card, um modal
Elevation (elevação)Distância aparente entre uma superfície e a que está embaixo dela, sugerida por cor, borda ou sombra
Z-index (ordem de empilhamento)Valor que decide qual elemento fica na frente quando dois se sobrepõem

Densidade visual e respiro

Quando muitos elementos disputam atenção ao mesmo tempo, o olho cansa e a decisão demora. O respiro (o espaço entre os elementos) organiza a leitura: ele mostra por onde começar e onde cada grupo termina.

A regra é o agrupamento semântico: o que se relaciona fica perto, o que é distinto ganha distância. Antes de ler as palavras, o olho lê a interface como parágrafos.

Anti-patternEfeitoSolução
Texto colado na borda do containerSensação de sufocamentoPadding (preenchimento interno) consistente
Todos os elementos com o mesmo peso visualNenhuma hierarquia claraTamanho, cor e espaçamento para criar níveis
Espaçamento inconsistente entre seçõesInterface parece montada por partesSistema de espaçamento em escala fixo
Informação densa sem quebra visualCansativo de lerGrupos de no máximo 2-3 linhas com respiro entre eles

Sistema de espaçamento

Valores escolhidos caso a caso (margin: 13px, padding: 7px) se acumulam e produzem uma inconsistência difícil de localizar depois. Um sistema de espaçamento define uma escala de valores fixos que se repetem na interface toda.

Escala típica, com os valores subindo a cada 4px:

TokenValorUso comum
space-14pxEspaço interno mínimo (ícone + label)
space-28pxPadding de componentes compactos
space-312pxGap entre elementos dentro de um grupo
space-416pxPadding padrão de cards e seções
space-624pxSeparação entre grupos distintos
space-832pxSeparação entre seções maiores
space-1248pxSeparação entre blocos de página

Usar tokens (valores nomeados do sistema de design) em vez de números soltos tem um ganho concreto: ajustar a escala uma vez propaga o ajuste por toda parte. A interface passa a respirar no mesmo ritmo em qualquer viewport (área visível da tela).

Hierarquia tipográfica

Texto sem hierarquia não diz por onde começar. O leitor precisa de âncoras visuais para separar num relance o que é título, o que é descrição e o que é detalhe.

Três níveis bastam para quase todo contexto:

NívelPapelCaracterísticas
PrimárioTítulo da seção ou ação principalTamanho maior, peso alto, cor de maior contraste
SecundárioSubtítulo, rótulo de campo, nome de itemTamanho médio, peso regular
TerciárioMetadado, data, hint (dica), legendaTamanho menor, cor mais suave

Passar de três níveis na mesma tela derruba a hierarquia em vez de refiná-la: quando tudo parece especial, nada parece importante.

Hierarquia de superfícies

Uma interface é lida em camadas antes de ser lida em palavras. O olho identifica o que está no fundo, o que está apoiado sobre ele e o que flutua por cima, e usa essa leitura para decidir o que é conteúdo, o que é moldura e o que exige resposta agora. A superfície (o plano visual que sustenta o conteúdo) é a peça que carrega essa informação.

A pilha tem cinco níveis, e quase toda tela cabe neles:

NívelO que éPapel na leitura
Background (plano de fundo)O fundo da páginaDefine o tom geral e não compete com nada
Surface (painel)Sidebar, cabeçalho, painel lateralEstrutura fixa: mostra onde o usuário está
Card (container de conteúdo)Bloco de conteúdo agrupadoDelimita uma unidade que pode ser lida sozinha
Overlay (camada flutuante)Dropdown, popover, tooltipConteúdo temporário ligado a um gatilho
Modal (janela bloqueante)Diálogo, confirmaçãoInterrompe o fluxo e exige uma decisão
modal      → interrompe: exige decisão do usuário
overlay    → flutua: dropdown, popover, tooltip
card       → agrupa: unidade de conteúdo
surface    → estrutura: sidebar, header
background → base: o plano da página

A ordem importa mais que os valores. Uma camada só aparece acima de outra quando o conteúdo dela é mais urgente ou mais temporário. Um card que flutua como se fosse modal, ou um modal que se confunde com o fundo, faz o usuário perder o rastro do que está ativo.

Elevar com cor, borda ou sombra

Três recursos separam uma camada da que está embaixo, e cada um comunica uma coisa diferente:

RecursoO que comunicaQuando escolher
Diferença de cor de fundoCamadas distintas, ambas fixasEstrutura permanente: sidebar sobre a página, card sobre o fundo
BordaLimite claro, sem sugerir alturaInterfaces densas (tabelas, painéis de dados), dark mode, quando a sombra suja o layout
SombraAltura real: o elemento está acima do planoConteúdo temporário: dropdown, popover, modal, elemento arrastado

O erro comum é acumular os três no mesmo componente. Um card com fundo diferente, borda visível e sombra pesada grita três vezes a mesma informação e ainda assim não fica mais legível. Um recurso resolve a maioria dos casos; dois já é uma decisão que precisa de motivo.

A força do recurso acompanha a altura da camada. Um card em repouso pede uma sombra que mal se nota. Um modal pede uma sombra funda, porque ele precisa parecer descolado de tudo o que está atrás. Quando a sombra do card e a do modal são iguais, o usuário deixa de distinguir o que é conteúdo do que é interrupção.

Para o lado da cor (quanto de luminosidade separa duas camadas em OKLCH, quanto de croma cabe num fundo, como tonalizar a sombra), o SSOT é color-theory.md.

Quanto menos camadas, melhor

Cada camada nova disputa a atenção do usuário e ocupa um lugar na pilha do código. Três anti-patterns aparecem quando a pilha cresce sem controle:

Anti-patternEfeitoSolução
Tudo elevado (card dentro de card dentro de painel)Nenhuma camada se destaca; a tela vira um relevo confusoAchatar: usar espaçamento e tipografia para agrupar, guardar a elevação para o que flutua
Modal que abre modalO usuário perde o caminho de volta e o Esc fecha o que ele não esperavaUm nível de interrupção por vez; o segundo passo vira uma etapa dentro do mesmo modal
z-index: 9999 espalhado pelo códigoNinguém sabe mais o que fica na frente do quêEscala nomeada de z-index no sistema de design, com uma parada por nível da pilha

O z-index merece a mesma disciplina do espaçamento: uma escala fixa, com um valor por camada, definida num lugar só.

--z-base       → 0     conteúdo da página
--z-sticky     → 10    header e sidebar fixos
--z-dropdown   → 20    menus e popovers
--z-modal      → 30    diálogos
--z-toast      → 40    notificações sobre o modal

Com a escala nomeada, quem escreve um componente novo escolhe a camada pelo papel dele. Sem ela, cada desenvolvedor descobre o número que funciona no dia e soma um.

Superfícies e acessibilidade

O contraste é medido contra a superfície imediata, e não contra o fundo da página. Um texto cinza que passa no WCAG sobre o branco da página pode falhar sobre o cinza claro de um card. Cada camada que muda o fundo obriga a reconferir o texto e os ícones que vivem em cima dela.

Elevação sozinha não comunica estado. Um item selecionado que se distingue apenas por uma sombra some para quem enxerga pouco ou usa alto contraste. A sombra entra como reforço, acompanhada de uma borda, uma mudança de cor de fundo ou um ícone.

Temas claro e escuro

Cada tema pede uma paleta própria, reajustada para o seu contexto. Superfície, sombra, opacidade e contraste se comportam de maneira diferente conforme o fundo, e inverter as cores do tema claro não resolve isso.

Na prática, isso se resolve com variáveis semânticas em vez de valores fixos:

AbordagemProblema
color: #1a1a1a direto no componenteNão muda com o tema
color: var(--text-primary) com valores por temaFunciona nos dois modos
--text-primary        → texto de maior hierarquia
--text-secondary      → texto de apoio
--surface-base        → fundo da página
--surface-elevated    → fundo de cards e modais
--border-subtle       → bordas de separação
--interactive-default → cor de botões e links

Para o detalhamento de OKLCH, harmonias, escala tonal de 11 paradas, cor das superfícies, WCAG 1.4.3 e estratégias específicas de light/dark, consulte color-theory.md.

Acessibilidade

Acessibilidade é a garantia de que a interface funciona para todo mundo, incluindo quem usa leitor de tela, navega só pelo teclado ou enxerga pouco.

Contraste

Texto e elementos interativos precisam se destacar do fundo. Um teste caseiro resolve a maioria dos casos: se você aperta os olhos para ler no mockup (protótipo visual), vai falhar em produção.

Todo elemento interativo (botão, link, campo, modal) tem que ser alcançável com Tab e acionável com Enter ou Space, e a ordem do foco precisa seguir a ordem visual da página.

Foco visível é obrigatório. Remover o outline (contorno) de foco sem colocar nada equivalente no lugar deixa quem navega por teclado sem saber onde está.

Semântica HTML

Os elementos HTML (HyperText Markup Language · Linguagem de Marcação de Hipertexto) semânticos são o que comunica estrutura ao leitor de tela:

EvitarUsar
<div> com click handler<button>
<div> para título<h1>–<h6>
<div> para lista<ul>/<ol>/<li>
<img> sem alt<img alt="descrição">

O leitor de tela anuncia o que o HTML declara. Um <div> com aparência de botão fica invisível para quem usa tecnologia assistiva, porque o HTML nunca disse que aquilo era um botão.

ARIA

ARIA completa a semântica nativa nos padrões que o HTML não cobre sozinho: menus, tooltips (dicas flutuantes), modais, comboboxes (campos de seleção combinados).

ARIA é o último recurso. Tente o elemento HTML semântico primeiro, sempre. ARIA aplicado errado anuncia ao leitor de tela uma estrutura que não corresponde ao comportamento real, e isso confunde mais do que a ausência de ARIA.

Estados e feedback

Toda ação do usuário precisa de uma resposta que ele consiga ver:

EstadoComo comunicar
LoadingSpinner (ícone giratório de carregamento) ou skeleton (esqueleto de carregamento) com aria-busy
Erro de formulárioMensagem inline (integrada ao elemento) associada ao campo via aria-describedby
SucessoToast (notificação temporária) ou inline com contraste e ícone
Campo desabilitadoCombinar visual de desabilitado com atributo disabled

Estados da interface

Toda tela tem mais estados do que o estado feliz. Desenhar apenas a versão com dados deixa os outros estados para a produção resolver.

EstadoQuando ocorre
EmptySem dados: primeiro uso ou filtro sem resultado
LoadingDados sendo carregados
ErrorFalha na operação, com mensagem e ação de recuperação
PartialDados carregados com erro em parte deles
SuccessOperação concluída, com feedback temporário

Um estado vazio bem feito aponta a próxima ação. Um estado de erro bem feito diz o que aconteceu e o que fazer agora. Tela em branco e mensagem técnica crua indicam estados que ninguém desenhou.

DoDocs v3.7.0 · Desenvolvido por @thiagocajadev · Baseado no trabalho de pmndrs/docs · Poimandres.