Pular para o conteúdo
A
Personalização

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-effects leem 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 classes aura-tilt e aura-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.

selo.tsx
"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
Troque o que se move por algo parado ou por uma transição curta de opacidade. Esconder o conteúdo junto com a animação deixa a pessoa sem a informação.

Em Tailwind ou CSS puro

Sem JavaScript, o Tailwind CSS tem as variantes motion-safe: e motion-reduce:, que seguem a mesma preferência:

tsx
{/* 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:

globals.css
@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-primary com text-aura-primary-foreground, bg-aura-surface com text-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:
tsx
{/* 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.

tsx
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-ring e 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-label dizendo 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.