Construindo menus de navegação acessíveis com HTML, CSS e JavaScript modernos


para o controle do menu. Os botões fornecem interação integrada ao teclado e expõem sua função a tecnologias assistivas sem exigir que os desenvolvedores recriem esse comportamento manualmente.

2. Crie um layout responsivo com CSS

Um componente de navegação responsivo deve se adaptar ao espaço disponível, mantendo seus links legíveis e utilizáveis.

CSS Grid e Flexbox fornecem controle suficiente para um layout simples sem a necessidade de uma estrutura.

.site-header {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 1rem;
  padding: 1rem clamp(1rem, 4vw, 3rem);
  border-bottom: 1px solid #dfe3e8;
}

.site-logo {
  color: #172554;
  font-size: 1.25rem;
  font-weight: 700;
  text-decoration: none;
}

.menu-toggle {
  display: none;
}

.navigation-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.navigation-list a {
  display: block;
  padding: 0.75rem;
  border-radius: 0.375rem;
  color: #243047;
  text-decoration: none;
}

.navigation-list a:hover {
  background: #eef2ff;
}

.navigation-list a:focus-visible,
.menu-toggle:focus-visible,
.site-logo:focus-visible {
  outline: 3px solid #315bd6;
  outline-offset: 3px;
}

@media (max-width: 48rem) {
  .menu-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.625rem 0.875rem;
    border: 1px solid #b8c2d1;
    border-radius: 0.375rem;
    background: white;
    color: #172554;
    font: inherit;
    cursor: pointer;
  }

  .primary-navigation {
    grid-column: 1 / -1;
  }

  .primary-navigation(hidden) {
    display: none;
  }

  .navigation-list {
    flex-direction: column;
    align-items: stretch;
  }
}

Em telas maiores, os links de navegação aparecem ao lado do logotipo. Em larguras mais estreitas, o botão do menu fica visível e a navegação pode ocupar uma linha separada.

O flex-wrap A declaração também evita que os itens de navegação da área de trabalho sejam forçados a uma única linha transbordante quando o espaço disponível se torna limitado.

A navegação móvel fica oculta através do HTML hidden atributo, que será controlado por JavaScript na próxima seção.

Um ponto de interrupção de 48rem é apenas um exemplo. O melhor ponto de interrupção depende da largura real dos links de navegação, da fonte e do layout circundante.

Um menu responsivo precisa de um comportamento previsível. Os usuários devem ser capazes de abri-lo, fechá-lo e saber se ele está expandido.

O seguinte JavaScript conecta o botão ao elemento de navegação:

const menuButton = document.querySelector(".menu-toggle");
const navigation = document.querySelector("#primary-navigation");

function setMenuOpen(isOpen) {
  menuButton.setAttribute("aria-expanded", String(isOpen));
  navigation.hidden = !isOpen;
}

menuButton.addEventListener("click", () => {
  const isExpanded =
    menuButton.getAttribute("aria-expanded") === "true";

  setMenuOpen(!isExpanded);
});

O setMenuOpen() A função atualiza o estado visual e o estado de acessibilidade juntos. Isto é preferível a alterar as classes CSS sem atualizar aria-expandedo que poderia deixar as tecnologias assistivas com informações incorretas.

Porque a navegação começa com aria-expanded="false"os estados iniciais de HTML e JavaScript concordam.

O hidden propriedade controla se a navegação é exibida. Quando o menu é aberto, a propriedade é removida; quando fecha, a propriedade é definida como true.

Esta implementação simples é adequada para um menu responsivo básico. Menus mais avançados podem precisar de comportamento adicional, como fechar quando um link de navegação é selecionado ou lidar com alterações na janela de visualização quando o layout alterna entre os modos desktop e móvel.

O ponto importante é manter o estado do menu consistente, em vez de permitir que estilos visuais e atributos de acessibilidade se separem.

4. Suporte para navegação e foco no teclado

A acessibilidade requer mais do que adicionar atributos ARIA. Os desenvolvedores também devem garantir que os usuários do teclado possam operar a interface e entender onde o foco está localizado.

Os botões nativos já suportam ativação através do teclado. Os links podem ser acessados ​​usando a tecla Tab, e os estilos de foco no exemplo anterior facilitam a identificação do elemento ativo.

Para um menu de navegação básico, os desenvolvedores geralmente devem evitar adicionar comportamento personalizado de teclas de seta ou atribuir role="menu" para uma lista comum de links de sites. A função de menu ARIA descreve um padrão de interação mais especializado comumente associado a menus de aplicativos e introduz expectativas adicionais de teclado.

A navegação convencional do site geralmente funciona melhor com um ponto de referência de navegação, uma lista de links e um botão que expande ou recolhe a lista.

O comportamento da tecla Escape também pode ser útil para descartar uma navegação móvel expandida. Por exemplo:

document.addEventListener("keydown", (event) => {
  const isExpanded =
    menuButton.getAttribute("aria-expanded") === "true";

  if (event.key === "Escape" && isExpanded) {
    setMenuOpen(false);
    menuButton.focus();
  }
});

Este ouvinte fecha o menu e retorna o foco para o botão quando Escape é pressionado.

Para um sistema de navegação mais complexo, o comportamento do teclado deve ser projetado em torno do modelo de interação completo, incluindo divulgações aninhadas, movimento de foco e quaisquer controles dentro do painel.

Evite adicionar atalhos de teclado simplesmente porque parecem convenientes. Cada comportamento adicional deve ter um propósito claro e deve ser testado tanto com navegação por teclado quanto com tecnologia assistiva.

5. Evite problemas comuns de navegação responsiva

Vários problemas podem prejudicar um menu bem estruturado.

Estado inconsistente: Se o botão indicar que o menu está expandido enquanto a navegação está oculta, os usuários receberão informações conflitantes. Atualize o estado visual e os atributos ARIA por meio da mesma função.

Armadilhas de teclado: Abrir um painel de navegação não deve impedir que os usuários acessem outras partes da interface ou retornem ao botão do menu.

Indicadores de foco insuficientes: Remover os contornos do navegador sem fornecer um substituto acessível dificulta a navegação pelo teclado.

Overflow em larguras intermediárias: Um menu pode funcionar em tamanhos comuns de desktop e dispositivos móveis, mas fica dividido entre eles. Teste o layout continuamente em vez de depender de algumas larguras de dispositivos predefinidas.

Rótulos pouco claros: Um botão denominado “Menu” comunica sua finalidade com mais clareza do que um ícone sem rótulo. Se um ícone for usado, certifique-se de que o botão tenha um nome acessível.

Movimento de foco inesperado: Abrir um painel de navegação simples geralmente não requer movimentação automática do foco. O foco deve mudar apenas quando o design de interação dá aos usuários uma razão clara para esperá-lo.

Esses problemas são mais fáceis de prevenir quando a acessibilidade e o comportamento responsivo são incluídos no design inicial.

6. Teste o componente em condições realistas

Um menu de navegação deve ser testado como um componente interativo e não apenas inspecionado como um elemento visual estático.

Comece verificando os seguintes comportamentos:

  • Em uma tela ampla, todos os links de navegação ficam visíveis e utilizáveis.

  • Em uma tela estreita, o botão de menu aparece e informa com precisão seu estado expandido.

  • As teclas Tab e Shift+Tab movem-se pelos elementos interativos em uma ordem lógica.

  • Enter e Espaço ativam o botão de menu.

  • Escape fecha o menu aberto e retorna o foco para o botão.

  • O texto permanece legível com maior zoom do navegador.

  • Links e controles têm contraste suficiente e indicadores de foco visíveis.

  • O layout permanece utilizável quando os rótulos de navegação ficam mais longos.

As ferramentas de desenvolvedor do navegador podem ajudar a simular diferentes tamanhos de viewport e inspecionar os atributos de acessibilidade do menu. O teste do leitor de tela pode revelar problemas que não são óbvios apenas pela inspeção visual.

Os testes também devem abranger a transição entre layouts de desktop e móveis. Se o navegador for redimensionado enquanto o menu estiver aberto, o aplicativo não deverá deixar para trás um estado oculto ou expandido inesperado.

Para aplicações maiores, estas verificações podem ser incorporadas em testes automatizados. No entanto, os testes automatizados devem complementar os testes manuais de acessibilidade, em vez de substituí-los.

Conclusão

A navegação acessível não requer uma estrutura complicada ou uma grande biblioteca JavaScript. O HTML semântico fornece a estrutura, o CSS adapta o layout ao espaço disponível e uma pequena quantidade de JavaScript gerencia o estado interativo.

A decisão de design mais importante é tratar a acessibilidade, a capacidade de resposta e a interação como partes do mesmo componente. Um menu não deve parecer correto apenas em dispositivos diferentes; ele também deve comunicar seu estado com precisão e permanecer utilizável com teclado e tecnologias assistivas.

Ao usar controles HTML nativos, manter um estado consistente e testar cenários de interação realistas, os desenvolvedores podem criar sistemas de navegação mais fáceis de manter e mais confiáveis ​​para uma gama mais ampla de usuários.



Source link