Conteúdo Acessível em Abas utilizando WAI-ARIA

Postado em 12/06/2017 por Luiz Volso

Uma ótima forma de ganhar espaço em páginas Web é separando o conteúdo em abas. Por muito tempo isso foi um problema quando nos preocupamos com acessibilidade. A necessidade do uso de Javascript para trocar a aba que será mostrada dificultava uma boa usabilidade por leitores de telas.

A boa notícia é que conseguimos controlar esses problemas utilizando ARIA para identificar corretamente a marcação tornando tudo acessível.

Primeiramente vamos à marcação básica:

A primeira parte do HTML é referente as abas propriamente ditas, atenção à primeira aba que já vem marcada com o atributo aria-selected em true pois essa estará visível por padrão.

<h2 id="abas">Conteúdo em Abas</h2>
<ul role="tablist">
  <li tabindex="0" role="tab" aria-controls="painel1" id="aba1" aria-selected="true">Desenvolvimento Web</li>
  <li tabindex="0" role="tab" aria-controls="painel2" id="aba2" aria-selected="false">Identidade Visual</li>
  <li tabindex="0" role="tab" aria-controls="painel3" id="aba3" aria-selected="false">Lojas Virtuais</li>
</ul>

O atributo tabindex="0" serve para que os elementos <li> entrem no fluxo de navegação por TAB. Os atributos role="tablist" no <ul> e role="tab" no <li> informam ao leitor de tela que se trata de um conteúdo separado em abas.

O atributo aria-controls indica qual painel que cada aba controla, a marcação dos painéis será vista a seguir:

<div role="tabpanel" id="painel1" aria-hidden="false" aria-labelledby="aba1">
  <h2 tabindex="0">Desenvolvimento Web</h2>
  <p>Na Era da informação a internet é um dos principais meios de marketing e promoção para as empresas. É fundamental ser pesquisado...</p>
</div>
<div role="tabpanel" id="painel2" aria-hidden="true" aria-labelledby="aba2">
  <h2 tabindex="0">Identidade Visual</h2>
  <p>A identidade visual é a imagem que sua empresa passa ao público no primeiro contato, por isso é necessário representá-la como...</p>
</div>
<div role="tabpanel" id="painel3" aria-hidden="true" aria-labelledby="aba3">
  <h2 tabindex="0">Lojas Virtuais</h2>
  <p>Com crescimentos exponenciais ano a ano nas vendas pela internet a criação de um canal de vendas on-line é mais uma oportunidade de...</p>
</div>

O atributo role="tabpanel" indica que cada elemento com essa marcação é um painel e o atributo id relaciona esse painel com a aba correspondente.

Incluiremos um pouco de CSS para que somente a aba ativa fique visível e dar uma ajeitada no visual:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">

ul[role="tablist"]:after{
  content: '';
  display: block;
  clear: both;
}

li[role="tab"]{
  width: 30%;
  float: left;
  font-size: 2em;
  border-radius: 5px 5px 0 0;
  border: 1px solid #CCC;
  padding: 0 16px;
  line-height: 40px;
  cursor: pointer;
}

li[aria-selected="false"]{
  background-color: #ECECEC;
}

li[aria-selected="true"]{
  border-bottom: none;
}

li[role="tab"]:focus{
  background-color: #FFF;
}

*[aria-hidden="true"]{
  display: none;
}

div[role="tabpanel"]{
  padding: 12px;
  border: 1px solid #CCC;
  border-top: none;
}

Agora vamos lidar com a camada de comportamento em Javascript, mais especificamente JQuery. Após incluir a biblioteca corretamente, vamos ao código.

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

Resumidamente, escondemos as abas e painéis inativos e mostramos os ativos (referente à aba clicada), depois uma pequena correção para que tudo funcione corretamente via teclado.

$(function(){
  // Controle das Abas
  $('li').bind('click', function(){
    $('li').attr({'aria-selected': false});
    $(this).attr({'aria-selected': true});
    var painel = $(this).attr('aria-controls');
    $('div[role="tabpanel"]').attr('aria-hidden', true);
    $('#'+painel).attr('aria-hidden', false);
  });

// Adiciona uma funcionalidade de clique quando o usuário pressionar ENTER na aba
  $("li[role='tab']").keydown(function(ev){
    if (ev.which ==13) {
      $(this).click()
    }
  });
});

Espero que o conteúdo tenha sido útil, em caso de dúvidas é só usar o formulário abaixo. Um grande abraço.