Criar a navegação principal de um site

Este tutorial descreve como criar uma navegação principal acessível de um site. Você vai aprender sobre HTML semântico, acessibilidade e como o uso de atributos ARIA às vezes pode ser mais prejudicial do que benéfico.

Manuel Matuzović
Manuel Matuzović

Há muitas maneiras diferentes de criar a navegação principal de um site em termos de estilo, funcionalidade, marcação subjacente e informações semânticas. Se a implementação for muito minimalista, ela vai funcionar para a maioria das pessoas, mas a experiência do usuário (UX) talvez não seja boa. Se houver excesso de engenharia, isso pode confundir os usuários ou até mesmo impedi-los de acessá-lo.

Para a maioria dos sites, o ideal é criar algo que não seja muito simples nem muito complicado.

Como criar camada por camada

Neste tutorial, você começa com uma configuração básica e adiciona recursos camada por camada até fornecer informações, estilo e funcionalidade suficientes para agradar a maioria dos usuários. Para isso, use o princípio do aprimoramento progressivo, que afirma que você começa com a solução mais fundamental e robusta e adiciona progressivamente camadas de funcionalidade. Se uma camada não funcionar por algum motivo, a navegação ainda funcionará porque ela voltará para a camada subjacente.

Estrutura básica

Para uma navegação básica, você precisa de dois elementos: <a> e algumas linhas de CSS para melhorar o estilo e o layout padrão dos seus links.

<a href="/home">Home</a>
<a href="/about-us">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Define variables for your colors */
:root {
  --color-shades-dark: rgb(25, 25, 25);
}

/* Use the alternative box model
Details: <https://web.dev/learn/css/box-model/> */
*{
  box-sizing: border-box;
}

/* Basic font styling */
body {
  font-family: Segoe UI, system-ui, -apple-system, sans-serif;
  font-size: 1.6rem;
}

/* Link styling */
a {
  --text-color: var(--color-shades-dark);
  border-block-end: 3px solid var(--border-color, transparent);
  color: var(--text-color);
  display: inline-block;
  margin-block-end: 0.5rem; /* See note at the bottom of this chapter */
  margin-inline-end: 0.5rem;
  padding: 0.1rem;
  text-decoration: none;
}

/* Change the border-color on :hover and :focus */
a:where(:hover, :focus) {
  --border-color: var(--text-color);
}
Veja a Etapa 1: HTML e CSS básicos" no CodePen.

Isso funciona bem para a maioria dos usuários, independentemente de como eles acessem o site. A navegação pode ser acessada com mouse, teclado, dispositivo touchscreen ou leitor de tela, mas você pode melhorar o recurso. Você pode aprimorar a experiência estendendo esse padrão básico com funcionalidades e informações adicionais.

Veja o que você pode fazer:

  • Destaque a página ativa.
  • Anunciar o número de itens para usuários de leitores de tela.
  • Adicione um ponto de referência e permita que os usuários de leitores de tela acessem a navegação diretamente usando um atalho.
  • Oculte a navegação em janelas de visualização estreitas.
  • Melhore o estilo de foco.
.

Destacar a página ativa

Para destacar a página ativa, você pode adicionar uma turma ao link correspondente.

<a href="/about-us" class="active-page">About us</a>

O problema dessa abordagem é que ela transmite informações com links ativos puramente visuais. Um usuário cego de leitor de tela não conseguia distinguir a página ativa das outras páginas. Felizmente, o padrão Accessible Rich Internet Applications (ARIA) também oferece uma maneira de comunicar essas informações semanticamente. Use o atributo e o valor aria-current=&quot;page&quot; em vez de uma classe.

aria-current (estado) indica o elemento que representa o item atual em um contêiner ou conjunto de elementos relacionados. Um token de página usado para indicar um link em um conjunto de links de paginação, em que o estilo do link é visualmente para representar a página exibida no momento. [Accessible Rich Internet Applications (WAI-ARIA) 1.1](https://www.w3.org/TR/wai-aria/#aria-current) (em inglês)
.

Com o atributo adicional, um leitor de tela agora anuncia algo como "página atual, link, Sobre nós" em vez de apenas "link, Sobre nós".

<a href="/about-us" aria-current="page" class="active-page">About us</a>

Um efeito colateral conveniente é que você pode usar o atributo para selecionar o link ativo no CSS, tornando a classe active-page obsoleta.

<a href="/home">Home</a>
<a href="/about-us" aria-current="page">About us</a>
<a href="/pricing">Pricing</a>
<a href="/contact">Contact</a>
/* Change border-color and color for the active page */
[aria-current="page"] {
  --border-color: var(--color-highlight);
  --text-color: var(--color-highlight);
}
Consulte a Etapa 2: destacar a página ativa no CodePen.

Anunciar o número de itens

Olhando para a navegação, os usuários com visão podem dizer que ela contém apenas quatro links. Um usuário de leitor de tela cego não pode obter essas informações tão rapidamente. Talvez seja necessário percorrer toda a lista de links. Isso pode não ser um problema se a lista for curta como neste exemplo, mas se ela contiver 40 links, a tarefa poderá ser complicada. Se um usuário de leitor de tela souber antecipadamente que a navegação contém muitos links, ele poderá decidir usar uma forma de navegação diferente e mais eficiente, como a pesquisa no site.
Uma boa maneira de comunicar o número de itens antecipadamente é envolver cada link em um item de lista (<li>), aninhado em uma lista não ordenada (<ul>).

<ul>
  <li>
     <a href="/home">Home</a>
  </li>
  <li>
    <a href="/about-us" aria-current="page">About us</a>
  </li>
  <li>
    <a href="/pricing">Pricing</a>
  </li>
  <li>
    <a href="/contact">Contact</a>
  </li>
</ul>

Quando um usuário de leitor de tela encontra a lista, o software anuncia algo como "lista, 4 itens".

Veja aqui uma demonstração da navegação usada com o leitor de tela NVDA no Windows.

Agora você precisa adaptar o estilo para ficar como antes.

/* Remove the default list styling and create a flexible layout for the list */
ul {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Basic link styling */
a {
  --text-color: var(--color-shades-dark);

  border-block-end: 3px solid var(--border-color, transparent);
  color: var(--text-color);
  padding: 0.1rem;
  text-decoration: none;
}

O uso de listas pode ter muitas vantagens para usuários de leitores de tela:

  • Ela pode conferir o número total de itens antes de interagir com eles.
  • Eles podem usar atalhos para passar de um item para outro.
  • Eles podem usar atalhos para passar de uma lista para outra.
  • O leitor de tela pode anunciar o índice do item atual (por exemplo, "item da lista, dois de quatro").

Além disso, se a página for apresentada sem CSS, a lista mostrará os links como um grupo coerente de itens, em vez de apenas uma pilha de links.

Um detalhe importante sobre o VoiceOver no Safari é que você perde todas essas vantagens ao definir list-style: none. Isso ocorre por design. A equipe do WebKit decidiu remover a semântica de lista quando uma lista não se parece com uma lista. Dependendo da complexidade da navegação, isso pode ou não ser um problema. Por um lado, a navegação ainda é utilizável e afeta apenas o VoiceOver no Safari. O VoiceOver com o Chrome ou o Firefox ainda anuncia o número de itens, além de outros leitores de tela, como o NVDA. Por outro lado, as informações semânticas podem ser muito úteis em algumas situações. Para tomar essa decisão, você precisa testar a navegação com usuários reais de leitores de tela e receber seu feedback. Se você decidir que precisa que o VoiceOver no Safari se comporte como todos os outros leitores de tela, defina a função da lista ARIA explicitamente no <ul>. Isso reverte o comportamento para o estado anterior à remoção do estilo de lista. Visualmente, a lista ainda tem a mesma aparência.

<ul role="list">
  <li>
     <a href="/home">Home</a>
  </li>
  ...
</ul>
Consulte a Etapa 3: anunciar o número de itens no CodePen.

Adicionar um ponto de referência

Com pouco esforço, você já fez ótimas melhorias para usuários de leitores de tela, mas há mais uma coisa que pode fazer. semanticamente, a navegação ainda é apenas uma lista de links, e é difícil dizer que essa lista específica é a navegação principal do seu site. Para transformar essa lista comum em uma lista de navegação, envolva o <ul> em um elemento <nav>.

O uso do elemento <nav> tem várias vantagens. Um leitor de tela anuncia algo como "navegação", quando o usuário interage com ele, e adiciona um marco à página. Pontos de referência são regiões especiais na página, como <header>, <footer> ou <main>, para as quais um leitor de tela pode acessar. Ter pontos de referência em uma página pode ser útil, porque permite que usuários de leitores de tela acessem regiões importantes diretamente na página, sem precisar interagir com o restante da página. Por exemplo, você pode ir de um ponto de referência para outro pressionando a tecla D no NVDA. No Voice Over, é possível usar o rotor para listar todos os pontos de referência na página pressionando VO U.

Uma lista de quatro pontos de referência: banner, navegação, principal e informações de conteúdo.
Rotor no VoiceOver listando todos os pontos de referência em uma página.

Nessa lista, são mostrados quatro pontos de referência: banner, que é o elemento <header>, navigation é o <nav>; main: o elemento <main> e content information é o <footer>. Essa lista não precisa ser muito longa. Marque apenas as partes essenciais da interface como pontos de referência, como a pesquisa no site, uma navegação local ou uma paginação.

Se você tiver uma navegação em todo o site, uma navegação local para a página e uma paginação em uma única página, também poderá ter três elementos <nav>. Tudo bem, mas agora há três pontos de referência de navegação e, semanticamente, todos têm a mesma aparência. Será difícil diferenciá-los, a menos que você conheça muito bem a estrutura da página.

Imagem mostrando três pontos de referência com o texto &quot;navegação&quot;.
O rotor do VoiceOver listando três pontos de referência de navegação sem rótulos.

Para torná-las distinguíveis, você precisa rotulá-las usando aria-labelledby ou aria-label.

<nav aria-label="Main">
    <ul>
      <li>
         <a href="/home">Home</a>
      </li>
      ...
  </ul>
</nav>
...
<nav aria-label="Select page">
    <ul>
      <li>
         <a href="/page-1">1</a>
      </li>
      ...
    </ul>
</nav>

Se o rótulo escolhido já existir em algum lugar da página, você poderá usar aria-labelledby e fazer referência ao rótulo existente usando o atributo id.

<nav aria-labelledby="pagination_heading">
  <h2 id="pagination_heading">Select a page</h2>
  <ul>
    <li>
       <a href="/page-1">1</a>
    </li>
    ...
  </ul>
</nav>

Um rótulo conciso é suficiente, não exagere. Omitir expressões como "navegação" ou "cardápio" porque o leitor de tela já fornece essas informações aos usuários.

Pontos de referência
VoiceOver listando os pontos de referência "banner", "navegação principal", "principal", "navegação na página", "seleção de navegação na página" e "informações do conteúdo".
Consulte a Etapa 4: como adicionar um ponto de referência no CodePen.

Ocultar a navegação em janelas de visualização estreitas

Pessoalmente, não gosto muito de ocultar a navegação principal em janelas de visualização estreitas, mas se a lista de links ficar muito longa, não haverá como contornar. Se esse for o caso, em vez da lista, os usuários verão um botão "Menu" um ícone de hambúrguer ou uma combinação delas. Ao clicar no botão, a lista é exibida e oculta. Se você tem noções básicas de JavaScript e CSS, essa tarefa é viável, mas há vários aspectos a serem considerados em termos de UX e acessibilidade.

  • É necessário ocultar a lista de modo acessível.
  • A navegação precisa ser acessível pelo teclado.
  • A navegação precisa informar se está ou não visível.

Adicionando um botão de hambúrguer

Como você está seguindo o princípio do aprimoramento progressivo, é importante garantir que a navegação ainda funcione e faça sentido mesmo com o JavaScript desativado.
A primeira coisa que a navegação precisa é um botão de hambúrguer. Você o cria em HTML em um elemento de modelo, clona-o em JavaScript e o adiciona à navegação.

Uma página mostrando um botão de hambúrguer.
Resultado: em vez de links, a navegação mostra um botão de navegação em janelas de visualização estreitas.
<nav id="mainnav">
  ...
</nav>

<template id="burger-template">
  <button type="button" aria-expanded="false" aria-label="Menu" aria-controls="mainnav">
    <svg width="24" height="24" aria-hidden="true">
      <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z">
    </svg>
  </button>
</template>
  1. O atributo aria-expanded informa ao software do leitor de tela se o elemento controlado pelo botão está aberto ou não.
  2. A aria-label dá ao botão um nome chamado "acessível", uma alternativa de texto para o ícone de hambúrguer.
  3. Você oculta a <svg> da tecnologia adaptativa usando aria-hidden porque ela já tem um rótulo de texto fornecido por aria-label.
  4. aria-controls informa à tecnologia adaptativa, que oferece suporte ao atributo (por exemplo, JAWS), qual elemento o botão controla.
const nav = document.querySelector('#mainnav')
const list = nav.querySelector('ul');
const burgerClone = document.querySelector('#burger-template').content.cloneNode(true);
const button = burgerClone.querySelector('button');

// Toggle aria-expanded attribute
button.addEventListener('click', e => {
  // aria-expanded="true" signals that the menu is currently open
  const isOpen = button.getAttribute('aria-expanded') === "true"
  button.setAttribute('aria-expanded', !isOpen);
});

// Hide list on keydown Escape
nav.addEventListener('keyup', e => {
  if (e.code === 'Escape') {
    button.setAttribute('aria-expanded', false);
  }
});

// Add the button to the page
nav.insertBefore(burgerClone, list);
  1. É conveniente para os usuários poderem fechar a navegação sempre que quiserem, por exemplo, pressionando a tecla Esc.
  2. É importante usar insertBefore em vez de appendChild porque o botão precisa ser o primeiro elemento da navegação. Se um usuário de teclado ou leitor de tela pressionar Tab depois de clicar no botão, ele espera focar no primeiro item da lista. Se o botão estiver depois da lista, esse não será o caso.

Em seguida, redefina o estilo padrão do botão e garanta que ele seja visível apenas em janelas de visualização estreitas.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
  }
}

/* Reset button styling */
button {
  all: unset;
  display: var(--nav-button-display, flex);
}
Consulte a Etapa 5: adicionar um botão de hambúrguer no CodePen.

Ocultar a lista

Antes de ocultar a lista, posicione e estilize a navegação e a lista para que o layout seja otimizado para janelas de visualização estreitas, mas ainda tenha uma boa aparência em telas maiores.
Primeiro, remova o <nav> do fluxo natural da página e coloque-o no canto superior da janela de visualização.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }
}

nav {
  position: var(--nav-position, fixed);
  inset-block-start: 1rem;
  inset-inline-end: 1rem;
}

Em seguida, mude o layout em janelas de visualização estreitas adicionando uma nova propriedade personalizada (—-nav-list-layout). O layout é de colunas por padrão e muda para linha em telas maiores.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }

  ul {
    --nav-list-layout: row;
  }
}

ul {
  display: flex;
  flex-direction: var(--nav-list-layout, column);
  flex-wrap: wrap;
  gap: 1rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

A navegação será semelhante a esta em janelas de visualização estreitas.

A página mostrando a lista de navegação e o botão de navegação.
O botão de navegação e a lista são posicionados no canto superior da janela de visualização.

A lista obviamente precisa de algum CSS. Vamos movê-la para o canto superior, fazer com que ela preencha toda a tela verticalmente, aplicar uma background-color e uma box-shadow.

@media (min-width: 48em) {
  nav {
    --nav-button-display: none;
    --nav-position: static;
  }
  
  ul {
    --nav-list-layout: row;
    --nav-list-position: static;
    --nav-list-padding: 0;
    --nav-list-height: auto;
    --nav-list-width: 100%;
    --nav-list-shadow: none;
  }
}

ul {
  background: rgb(255, 255, 255);
  box-shadow: var(--nav-list-shadow, -5px 0 11px 0 rgb(0 0 0 / 0.2));
  display: flex;
  flex-direction: var(--nav-list-layout, column);
  flex-wrap: wrap;
  gap: 1rem;
  height: var(--nav-list-height, 100vh);
  list-style: none;
  margin: 0;
  padding: var(--nav-list-padding, 2rem);
  position: var(--nav-list-position, fixed);
  inset-block-start: 0; /* Logical property. Equivalent to top: 0; */
  inset-inline-end: 0; /* Logical property. Equivalent to right: 0; */
  width: var(--nav-list-width, min(22rem, 100vw));
}

button {
  all: unset;
  display: var(--nav-button-display, flex);
  position: relative;
  z-index: 1;
}

A lista deve ser semelhante a esta em janelas de visualização estreitas, mais como uma barra lateral do que uma lista simples.

A lista de navegação é aberta.

Por fim, oculte a lista, mostre-a apenas quando o usuário clicar no botão uma vez e oculte-a quando clicar novamente. É importante ocultar apenas a lista, e não toda a navegação, porque ocultar a navegação também significa ocultar um ponto de referência importante.

Anteriormente, você adicionou um evento de clique ao botão para alternar o valor do atributo aria-expanded. Use essas informações como uma condição para mostrar e ocultar a lista no CSS.

@media (min-width: 48em) {
  ul {
    --nav-list-visibility: visible;
  }
}

ul {
  visibility: var(--nav-list-visibility, visible);
}

/* Hide the list on narrow viewports, if it comes after an element with
   aria-expanded set to "false". */
[aria-expanded="false"]   ul {
  visibility: var(--nav-list-visibility, hidden);
}

É importante usar uma declaração de propriedade, como visibility: hidden ou display: none, em vez de opacity: 0 ou translateX(100%) para ocultar a lista. Essas propriedades garantem que os links não sejam focalizáveis quando a navegação estiver oculta. Usar opacity ou translate vai remover o conteúdo visualmente para que os links fiquem invisíveis, mas ainda possam ser acessados usando o teclado, o que seria confuso e frustrante. O uso de visibility ou display oculta esse elemento visualmente e o torna inacessível, ocultando para todos os usuários.

Consulte a Etapa 6: ocultar a lista.

Como animar a lista

Você está se perguntando por que usar visibility: hidden; em vez de display: none;, porque é possível animar a visibilidade. Ela tem apenas dois estados, hidden e visible, mas é possível combiná-lo com outra propriedade, como transform ou opacity, para criar um efeito deslizante ou de esmaecimento. Isso não funcionaria com display: none porque a propriedade display não é animatable.

O CSS a seguir faz a transição de opacity para criar um efeito de esmaecimento e exibição gradual.

ul {
  transition: opacity 0.6s linear, visibility 0.3s linear;
  visibility: var(--nav-list-visibility, visible);
}

[aria-expanded="false"]   ul {
  opacity: 0;
  visibility: var(--nav-list-visibility, hidden);
}

Se você quiser animar o movimento, considere unir a propriedade transition em uma consulta de mídia prefer-reduced-motion, porque as animações podem causar náuseas, tonturas e dores de cabeça em alguns usuários.

ul {
  visibility: var(--nav-list-visibility, visible);
}

@media (prefers-reduced-motion: no-preference) {
  ul {
    transition: transform 0.6s cubic-bezier(.68,-0.55,.27,1.55), visibility 0.3s linear;
  }
}

[aria-expanded="false"]   ul {
  transform: var(--nav-list-transform, translateX(100%));
  visibility: var(--nav-list-visibility, hidden);
}

Isso garante que apenas as pessoas que não têm preferência por movimento reduzido vejam a animação.

Consulte a Etapa 7: como animar a lista no CodePen.

Melhorar o estilo de foco

Os usuários de teclado dependem dos estilos de foco dos elementos para orientação e navegação em uma página. Os estilos de foco padrão são melhores do que os estilos sem foco (o que acontece se você definir outline: none), mas ter estilos de foco personalizados mais visíveis melhora a experiência do usuário.

Veja como ficam os estilos de foco padrão no link no Chrome 103.

Um contorno azul de 2 px ao redor de um link em foco no Chrome 103.

Você pode melhorar isso fornecendo seus próprios estilos com suas próprias cores. Ao usar :focus-visible em vez de :focus, você permite que o navegador decida quando é apropriado mostrar estilos de foco. Os estilos :focus estarão visíveis para todos, usuários de mouse, teclado e toque, independentemente da necessidade deles ou não. Com o :focus-visible, o navegador usa heurística interna para decidir se ele será mostrado apenas para usuários do teclado ou para todos.

/* Remove the default :focus outline */
*:focus {
  outline: none;
}

/* Show a custom outline on :focus-visible */
*:focus-visible {
  outline: 2px solid var(--color-shades-dark);
  outline-offset: 4px;
}

Suporte do navegador para :focus-visible

Compatibilidade com navegadores

  • Chrome: 86.
  • Borda: 86.
  • Firefox: 85.
  • Safari: 15.4.

Origem

Contorno escuro de 2 px claramente visível com espaçamento interno.

Há diferentes maneiras de destacar itens quando eles estão em foco. O uso da propriedade outline é recomendado porque ela não interrompe o layout, o que pode acontecer com border, e funciona bem com o modo de alto contraste no Windows. As propriedades que não funcionam bem são background-color ou box-shadow, porque podem não ser exibidas com as configurações de contraste personalizadas.

Um site com um fundo escuro com o foco destacado em roxo.
Consulte a Etapa 8: melhorar estilos de foco no CodePen.

Parabéns! Você criou uma navegação principal progressivamente aprimorada, semanticamente avançada, acessível e compatível com dispositivos móveis.

Sempre há algo que pode ser melhorado, por exemplo:

  • É possível manter o foco na navegação ou tornar o restante da página inerte em janelas de visualização estreitas.
  • É possível adicionar um link de pular na parte de cima da página para permitir que os usuários do teclado ignorem a navegação.

Se você se lembra de como este artigo começou, com o objetivo de que a solução "não deve ser muito simples, nem muito complicada", é aqui que estamos agora. No entanto, a navegação pode ser engenhosa demais.

Há uma diferença clara entre navegações e menus. Navegações são coleções de links para navegar em documentos relacionados. Menus são coleções de ações a serem realizadas em um documento. Às vezes, essas tarefas se sobrepõem. Você pode ter uma navegação que também inclui um botão que realiza uma ação, como abrir uma janela modal, ou um menu em que uma ação navega para outra página, como uma página de ajuda. Quando esse for o caso, é importante não misturar funções ARIA, mas identificar a finalidade principal do seu componente e escolher a marcação e as funções de acordo.

O elemento <nav> tem uma função ARIA implícita de navegação que é suficiente para comunicar que o elemento é uma navegação, mas muitas vezes os sites também usam menu, barra de menu e item de menu. Como às vezes usamos esses termos de forma intercambiável, pensar que combiná-los para melhorar a experiência de usuários de leitores de tela pode fazer sentido. Antes de entender por que isso geralmente não é o caso, vamos dar uma olhada na definição oficial dessas funções.

Função de navegação

Uma coleção de elementos de navegação (geralmente links) para navegar pelo documento ou documentos relacionados.

navegação (função) WAI-ARIA 1.1

Função do menu

Um menu geralmente é uma lista de ações ou funções comuns que o usuário pode invocar. A role de menu é apropriada quando uma lista de itens de menu é apresentada de maneira semelhante a um menu em um aplicativo para computador.

menu (função) WAI-ARIA 1.1

Função da barra de menus

Uma apresentação de menu que geralmente permanece visível e geralmente é apresentada horizontalmente. A função da barra de menus é usada para criar uma barra de menus semelhante às encontradas nos aplicativos para computador Windows, Mac e Gnome. Uma barra de menu é usada para criar um conjunto consistente de comandos usados com frequência. Os autores devem garantir que a interação da barra de menus seja semelhante à interação típica da barra de menus em uma interface gráfica do usuário em um computador.

menubar (função) WAI-ARIA 1.1

Função "item de menu"

Uma opção em um conjunto de opções contido em um menu ou barra de menus.

menuitem (função) WAI-ARIA 1.1

A especificação é muito clara aqui. Use a navegação para navegar pelo documento ou documentos relacionados e menu apenas para uma lista de ações ou funções semelhantes a menus em aplicativos de computador. Se você não estiver criando o próximo Google Docs, provavelmente não precisará de nenhuma das funções de menu para a navegação principal.

Quando um cardápio é apropriado?

O principal uso dos itens de menu não é a navegação, mas sim para realizar ações. Digamos que você tenha uma lista ou tabela de dados e os usuários possam realizar determinadas ações em cada item da lista. É possível adicionar um botão a cada linha e mostrar as ações quando os usuários clicam no botão.

<ul>
  <li>
    Product 1

    <button aria-expanded="false" aria-controls="options1">Edit</button>

    <div role="menu" id="options1">
      <button role="menuitem">
        Duplicate
      </button>
      <button role="menuitem">
        Delete
      </button>
      <button role="menuitem">
        Disable
      </button>
    </div>
  </li>
  <li>
    Product 2
    ...
  </li>
</ul>

Implicações do uso de papéis de menu

É muito importante usar essas funções de menu com sabedoria, porque muitas coisas podem dar errado.

Os menus esperam uma determinada estrutura DOM. menuitem precisa ser um item filho direto de menu. O código a seguir pode interromper o comportamento semântico:

 <!-- Wrong, don't do this -->
<ul role="menu">
  <li>
    <a href="#" role="menuitem">Item 1</a>
  </li>
</ul>

Os usuários experientes esperam que determinados atalhos do teclado funcionem com menus e barras de menu. Com base no Guia de práticas de criação de ARIA (APG, na sigla em inglês), isso inclui:

  • Pressione Enter e espaço para selecionar os itens do menu.
  • Use as teclas de seta em todas as direções para navegar entre os itens.
  • Use as teclas Home e End para mover o foco para o primeiro ou o último item, respectivamente.
  • a-z para mover o foco para o próximo item de menu com um rótulo que começa com o caractere digitado.
  • Esc para fechar o menu.

Se um leitor de tela detectar um menu, o software poderá alterar automaticamente o modo de navegação, ativando o uso dos atalhos mencionados anteriormente. Usuários inexperientes de leitores de tela podem não conseguir usar o menu porque não conhecem esses atalhos ou como usá-los.

O mesmo acontece com usuários de teclado, que provavelmente esperam usar Shift e Shift Tab.

Há muito a se considerar ao criar menus e barras de menus, com se é apropriado usá-los em primeiro lugar. Ao criar um site comum, você só precisa do elemento de navegação com uma lista e links. Isso também inclui aplicativos de página única (SPA) ou aplicativos da Web. A pilha subjacente não importa. A menos que você esteja criando algo muito próximo a um aplicativo para computador, evite as funções de menu.

Outros recursos

Imagem principal de Mick Haupt