Precisão inclui quem opera.
Acessibilidade é o contrato entre estrutura, foco e estado. A textura pode desaparecer; o nome, o limite funcional e o caminho de recuperação precisam continuar presentes.
O caminho do foco é parte do componente.
O esquema acompanha uma tarefa: localizar o campo pelo nome, reconhecer seu limite e seu foco, editar o texto, ler a resposta e seguir adiante. Os seis índices apontam às camadas verificáveis.
-
Nome persistente
O label identifica o campo mesmo preenchido, ampliado ou sem placeholder. Nome acessível acompanha a função visível, em português.
-
Limite funcional
Borda de controle usa linha forte; hairlines decorativas não podem ser o único limite percebido. Em cores forçadas, CanvasText e Canvas mantêm a forma.
-
Foco de duplo anel
O intervalo interno separa o controle da borda externa. O foco acompanha Tab e Shift+Tab; contêiner chanfrado não pode cortá-lo.
-
Texto editável
O campo preserva fonte mínima de 16px e rolagem natural. A altura base de 56px acompanha --xq-controle-lg; zoom não pode retirar ajuda nem cortar o valor em uma caixa editorial fixa.
-
Resultado compreensível
Erro nomeia o problema e a recuperação. Cor e ícone são complementos; mensagens de estado precisam continuar compreensíveis como texto.
-
Ordem e saída
Ordem do DOM segue a tarefa. Modal e gaveta contêm o foco, aceitam Escape e devolvem ao gatilho; componentes não modais não prendem Tab.
Contratos de tokens CSS
Valor ou alias no tema claro, propriedade consumidora e limite de uso. Cores são apresentadas em RGB equivalente; a fonte continua no CSS de tokens. O inspetor mostra a resolução no tema escolhido.
| Token / expressão | Aplicação CSS | Regra |
|---|---|---|
--xq-focus-width
2px
|
.xq-btn:focus-visible
outline-width
|
2px de contorno visível; não remover outline sem substituição verificável. |
--xq-focus-gap
2px
|
.xq-btn:focus-visible
outline-offset, box-shadow
|
2px separam o controle e o anel. Espaço externo precisa sobreviver ao recorte do contêiner. |
--xq-focus-inner
var(--xq-fundo)
|
.xq-btn:focus-visible
box-shadow
|
Cor interna resolve no tema local, oferecendo separação antes do anel exterior. |
--xq-focus-outer
var(--xq-anel)
|
.xq-btn:focus-visible
outline-color
|
Anel exterior acompanha o tema; a variante acento usa --xq-anel-acento. |
--xq-controle-lg
56px
|
.xq-btn
min-block-size
|
Altura mínima de 56px no controle padrão. Densidade editorial não reduz o alvo funcional. |
--xq-realce
rgb(36 71 53)
|
[data-tema]
accent-color
|
Sinal dos controles nativos acompanha o tema, com nome e estado textual preservados. |
--xq-linha-forte
rgb(97 115 104)
|
.xq-btn--secundario
border-color
|
Borda funcional sólida; não substituí-la por uma sombra difusa de baixo contraste. |
--xq-texto
rgb(25 39 32)
|
body
color
|
Texto principal sem opacidade aplicada ao conjunto. Contraste depende do plano efetivo. |
--xq-corpo
16px
|
body
font-size
|
Base de leitura 16px. Ampliar texto não pode esconder ações ou mensagens. |
--xq-entrelinha
1.6
|
body
line-height
|
Entrelinha 1,6 para texto corrido; não usar a compressão do display nos parágrafos. |
--xq-font
'Schibsted Grotesk', Arial, sans-serif
|
body
font-family
|
Schibsted Grotesk com fallback. O conteúdo continua utilizável se a fonte não carregar. |
--xq-raio-controle
3px
|
button
border-radius
|
Raio de 3px caracteriza o controle sem ampliar ou reduzir o seu alvo. |
Uso correto × uso incorreto
Compare a mesma intenção em duas composições. Os exemplos são amostras de leitura; os controles operáveis ficam no playground.
OPERAÇÃO / TECLADO DISPONÍVEL
Consultar o contrato do teclado
Abas: Setas, Home e End. Diálogos: Escape fecha e devolve o foco ao gatilho.
Nome explícito, foco visível e link com destino real.
- Summary funciona com Enter e Espaço sem JavaScript.
- O link declara o destino e recebe foco nativo.
- Nome e instruções continuam visíveis após interação.
Experiência incrível
Campo obrigatórioPronto!
- O nome genérico do campo não identifica qual dado preencher.
- Div com aparência de ação não oferece teclado.
- Mensagem vaga não identifica o que aconteceu.
Testar foco, edição e mensagens.
Use Tab até o campo, altere o texto e abra o disclosure por teclado. Os controles de estado do laboratório simulam mensagens sem capturar o foco ou sobrescrever o texto editado.
LEITURA ASSISTIDA / G1–G8ALVO / 56 px
Campo disponível. Use Tab para seguir e Shift+Tab para retornar.
Consultar teclas de navegação
Tab avança. Shift+Tab retorna. Enter ou Espaço abre este disclosure.
Pronto. Altere um controle para inspecionar o contrato.
Ensaio local e determinístico. A ação percorre carregamento → sucesso; movimento reduzido entrega o estado final imediatamente. Repetir preserva os controles.
Inspecionar tokens resolvidos
--xq-focus-width- 2px
--xq-focus-gap- 2px
--xq-focus-inner- var(--xq-fundo)
--xq-focus-outer- var(--xq-anel)
--xq-controle-lg- 56px
--xq-realce- rgb(36 71 53)
--xq-linha-forte- rgb(97 115 104)
--xq-texto- rgb(25 39 32)
--xq-corpo- 16px
--xq-entrelinha- 1.6
--xq-font- 'Schibsted Grotesk', Arial, sans-serif
--xq-raio-controle- 3px
Aplicar o contrato
Preservar nome e destino
Usar controles nativos com rótulos concretos. Neste exemplo, o link abre uma página existente do próprio guia; não precisa de handler ou role adicional.
<a class="xq-btn xq-btn--secundario"
href="acessibilidade.html">
Abrir referência de acessibilidade
</a>
Anunciar sem deslocar o foco
Criar a região de estado antes da atualização e substituir seu texto quando a operação terminar. A confirmação não deve focar um parágrafo nem reabrir um diálogo.
<p role="status" aria-live="polite" aria-atomic="true"></p>
// Após a operação local:
regiao.textContent = "Alterações disponíveis para revisão.";
Oferecer edição sem esconder o nome
O label envolvendo o input associa nome e controle sem IDs adicionais. A classe xq-input já aplica limite funcional, altura mínima e fonte de pelo menos 16px; não duplicar esses contratos inline.
<label class="xq-stack">
Mensagem de ensaio
<input class="xq-input" type="text"
value="Leitura preservada" autocomplete="off">
</label>
Critérios de aceite
- Percorrer o laboratório em ambas as direções por Tab; nenhum controle fica preso ou recebe foco oculto.
- Testar texto ampliado e 390px: labels, ajuda e mensagens quebram linhas sem esconder conteúdo.
- Ativar prefers-reduced-motion e forced-colors: manter estado final, limites de controle e foco visível.
- Sem JavaScript, abrir disclosures, seguir links e consultar tabelas; identificar a dependência dos controles dinâmicos.
- Digitar um texto no campo e alternar todos os estados: a mensagem deve mudar sem apagar a edição ou mover o foco para a região de status.