Acessibilidade: movimento reduzido, contraste e teclado
O que o Aura UI já faz por você e o que continua na sua mão: respeitar quem pediu menos animação, manter o texto legível e deixar os formulários claros para teclado e leitor de tela.
Movimento reduzido já vem ligado
Sistemas operacionais têm uma opção para reduzir animações. Ela existe porque movimento na tela pode causar tontura, enjoo ou simplesmente atrapalhar a leitura. O navegador repassa esse pedido para o site pela media query prefers-reduced-motion: reduce.
- Todos os efeitos do pacote
aura-ui-effectsleem essa preferência. Um teste do repositório falha se algum efeito novo esquecer. - As animações de abrir e fechar de diálogos, menus, gavetas e toasts são desligadas no CSS do
aura-ui-core, assim como a inclinação e o "afundar" ao clicar das classesaura-tilteaura-press. - O conteúdo continua lá: o NumberTicker mostra o número final, o WordRotate e o TypingText mostram a primeira frase pronta.
Use o mesmo hook nas suas animações
Para as animações que você escrever, o useReducedMotion devolve true quando a pessoa pediu menos movimento, e atualiza sozinho se ela mudar a opção com a página aberta. No servidor ele devolve false e corrige depois de montar, então funciona com Next.js sem erro de hidratação.
"use client";
import { useReducedMotion } from "aura-ui-core/client";
export function Selo({ children }: { children: React.ReactNode }) {
const reduced = useReducedMotion();
return (
<span
style={{
display: "inline-block",
// Sem movimento para quem pediu menos animação no sistema.
animation: reduced ? "none" : "selo-pulsa 2s ease-in-out infinite"
}}
>
{children}
</span>
);
}Reduzir não é remover tudo
Em Tailwind ou CSS puro
Sem JavaScript, o Tailwind CSS tem as variantes motion-safe: e motion-reduce:, que seguem a mesma preferência:
{/* Só anima para quem não pediu menos movimento. */}
<span className="motion-safe:animate-bounce">Novo</span>
{/* Ou desligue a transição quando o pedido existir. */}
<a className="transition-transform hover:-translate-y-1 motion-reduce:transform-none motion-reduce:transition-none">
Ver planos
</a>Em CSS, é a media query direto:
@media (prefers-reduced-motion: reduce) {
.selo {
animation: none;
}
}Como testar no seu computador
- Windows 11: Configurações → Acessibilidade → Efeitos visuais → desligue "Efeitos de animação".
- macOS: Ajustes do Sistema → Acessibilidade → Tela → ligue "Reduzir movimento".
- Chrome ou Edge, sem mexer no sistema: abra o DevTools, a aba Rendering (pelo menu de comandos, Ctrl+Shift+P, digite "Rendering") e em "Emulate CSS media feature prefers-reduced-motion" escolha
reduce.
Com a opção ligada, abra a vitrine: os efeitos ficam parados e os componentes continuam funcionando.
Contraste do texto
O nível AA da WCAG pede contraste de pelo menos 4,5:1 entre o texto comum e o fundo, e de 3:1 para texto grande e para partes da interface como bordas de campos e ícones.
- Use os pares de tokens:
bg-aura-primarycomtext-aura-primary-foreground,bg-aura-surfacecomtext-aura-surface-foreground. Eles trocam juntos no claro, no escuro e em cada tema. - Para texto colorido sobre um fundo tingido, use as cores
-strong. Elas misturam a cor com a cor do texto para ganhar contraste:
{/* Texto colorido em cima de um fundo tingido da mesma cor. */}
<span className="rounded-full bg-aura-primary/10 px-3 py-1 text-aura-primary-strong">
Em análise
</span>
<p className="bg-aura-success/10 text-aura-success-strong">Pagamento confirmado.</p>Vai criar o tema da sua marca? O gerador de temas mede o contraste das suas cores no claro e no escuro e tem um botão que ajusta o tom até passar no AA.
Formulários: label, ajuda e erro ligados
Quem usa leitor de tela precisa ouvir o nome do campo, a dica e o erro quando o foco chega nele. O Field cria os ids e liga tudo: o label aponta para o controle, a descrição e o erro entram em aria-describedby, e invalid e required viram aria-invalid e aria-required.
import { Field, FieldControl, FieldDescription, FieldError, FieldLabel } from "aura-ui-components/field";
import { Input } from "aura-ui-components/input";
<Field required invalid={!!erro}>
<FieldLabel>E-mail</FieldLabel>
<FieldControl>
<Input type="email" autoComplete="email" />
</FieldControl>
<FieldDescription>Enviaremos o link de confirmação para ele.</FieldDescription>
<FieldError>{erro}</FieldError>
</Field>Teclado e foco
- Diálogos, menus, popovers, selects e abas são construídos sobre o Radix, que cuida do foco preso no diálogo, do Esc para fechar e das setas para navegar.
- O anel de foco usa o token
ring-aura-ringe só aparece na navegação por teclado (focus-visible). Se você remover o contorno de um elemento seu, ponha outro indicador no lugar. - Botão só com ícone precisa de nome: passe
aria-labeldizendo o que ele faz ("Fechar", "Abrir menu").
Antes de publicar
- Navegue a página inteira só com Tab, Shift+Tab, Enter e Esc.
- Ligue o movimento reduzido e veja se nada some nem fica piscando.
- Confira o contraste nos dois modos, claro e escuro.
- Dê zoom de 200% no navegador: o texto precisa continuar legível, sem rolagem para os lados.
- Toda imagem que informa algo tem texto alternativo; a decorativa fica com alt vazio.
Próximo passo: o guia de modo escuro sem flash ou a lista de componentes.