HTML semântico

Com mais de 100 elementos HTML e a capacidade de criar elementos personalizados, há infinitas formas de marcar seu conteúdo. No entanto, algumas maneiras (especialmente semanticamente) são melhores que outras.

Semântica significa "relacionado ao significado". Escrever HTML semântico significa usar elementos HTML para estruturar seu conteúdo com base no significado de cada elemento, não na aparência dele.

Essa série ainda não abordou muitos elementos HTML, mas, mesmo sem saber HTML, os dois snippets de código a seguir mostram como a marcação semântica pode dar contexto ao conteúdo. Ambos usam uma contagem de palavras em vez de ipsum lorem para poupar tempo. Use sua imaginação para expandir "trinta palavras" em 30 palavras:

O primeiro snippet de código usa <div> e <span>, dois elementos sem valor semântico.

<div>
  <span>Three words</span>
  <div>
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
  </div>
</div>
<div>
  <div>
    <div>five words</div>
  </div>
  <div>
    <div>three words</div>
    <div>forty-six words</div>
    <div>forty-four words</div>
  </div>
  <div>
    <div>seven words</h2>
    <div>sixty-eight words</div>
    <div>forty-four words</div>
  </div>
</div>
<div>
   <span>five words</span>
</div>

Você consegue ter uma noção do que essas palavras se expandem? Na verdade, não.

Vamos reescrever esse código com elementos semânticos:

<header>
  <h1>Three words</h1>
  <nav>
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
  </nav>
</header>
<main>
  <header>
    <h1>five words</h1>
  </header>
  <section>
    <h2>three words</h2>
    <p>forty-six words</p>
    <p>forty-four words</p>
  </section>
  <section>
    <h2>seven words</h2>
    <p>sixty-eight words</p>
    <p>forty-four words</p>
  </section>
</main>
<footer>
  <p>five words</p>
</footer>

Qual bloco de código transmitiu um significado? Usando apenas os elementos não semânticos de <div> e <span>, não é possível dizer o que o conteúdo no primeiro bloco de código representa. O segundo exemplo de código, com elementos semânticos, fornece contexto suficiente para que um não codificador possa decifrar a finalidade e o significado sem jamais encontrar uma tag HTML. Ela definitivamente fornece contexto suficiente para que o desenvolvedor entenda o contorno da página, mesmo que ele não entenda o conteúdo, como em um idioma estrangeiro.

No segundo bloco de código, podemos entender a arquitetura mesmo sem entender o conteúdo, porque os elementos semânticos fornecem significado e estrutura. O primeiro cabeçalho é o banner do site, e <h1> provavelmente é o nome do site. O rodapé é o rodapé do site: as cinco palavras podem ser uma declaração de direitos autorais ou um endereço comercial.

A marcação semântica não se resume a tornar a marcação mais fácil de ler para os desenvolvedores; ela se trata principalmente de facilitar a decifração da marcação por ferramentas automatizadas. As ferramentas para desenvolvedores também demonstram como os elementos semânticos oferecem uma estrutura legível por máquina.

Modelo de objeto de acessibilidade (AOM, na sigla em inglês)

À medida que o navegador analisa o conteúdo recebido, ele cria o Modelo de objeto de documento (DOM) e o modelo de objeto CSS (CSSOM). Em seguida, ele também cria uma árvore de acessibilidade. Dispositivos assistivos, como leitores de tela, usam o AOM para analisar e interpretar conteúdo. O DOM é uma árvore de todos os nós do documento. A AOM é como uma versão semântica do DOM.

Vamos comparar como essas duas estruturas de documentos são renderizadas no painel de acessibilidade do Firefox:

Uma lista de nós que são todos links ou folhas de texto.
O primeiro snippet de código.
Uma lista de nós com pontos de referência claros.
O segundo snippet de código.

Na segunda captura de tela, há quatro papéis importantes no segundo bloco de código. Ela usa pontos de referência semânticos, convenientemente nomeados <header>, <main>, <footer> e <nav> para "navegação". Os pontos de referência oferecem estrutura para o conteúdo da Web e garantem que seções importantes de conteúdo sejam facilmente navegáveis pelo teclado para usuários de leitores de tela.

<header> e <footer> são pontos de referência, com os papéis de banner e contentinfo, respectivamente, quando não estão aninhados em outros pontos de referência. A AOM do Chrome mostra isso da seguinte maneira:

Todos os nós de texto são listados como texto estático.
O primeiro snippet de código.
Todos os nós de texto têm descrições.
O segundo snippet de código.

Analisando as ferramentas para desenvolvedores do Chrome, você vai notar uma diferença significativa entre o modelo de objeto de acessibilidade ao usar elementos semânticos e quando não usa.

É bastante claro que o uso de elementos semânticos ajuda a acessibilidade, e o uso de elementos não semânticos reduz a acessibilidade. Por padrão, o HTML geralmente é acessível. Nosso trabalho como desenvolvedores é proteger a natureza acessível padrão do HTML e garantir que maximizemos a acessibilidade. É possível inspecionar a AOM nas ferramentas para desenvolvedores.

O atributo role

O atributo role descreve a função que um elemento tem no contexto do documento. O role é um atributo global, ou seja, válido em todos os elementos, definido pela especificação ARIA em vez da especificação HTML WHWG (em inglês), em que quase todo o restante da série é definido.

Cada elemento semântico tem um papel implícito, alguns dependendo do contexto. Como vimos na captura de tela das ferramentas para desenvolvedores de acessibilidade do Firefox, os <header>, <main>, <footer> e <nav> de nível superior eram todos pontos de referência, enquanto o <header> aninhado em <main> era uma seção. A captura de tela do Chrome lista as funções ARIA destes elementos: <main> é main, <nav> é navigation e <footer>, como era o rodapé do documento, é contentinfo. Quando <header> é o cabeçalho do documento, o papel padrão é banner, que define a seção como o cabeçalho global do site. Quando uma <header> ou uma <footer> está aninhada em um elemento de seção, ela não é uma função de ponto de referência. As capturas de tela das duas ferramentas para desenvolvedores mostram isso.

Os nomes das funções dos elementos são importantes na criação do AOM. A semântica de um elemento, ou "papel", é importante para tecnologias assistivas e, em alguns casos, mecanismos de pesquisa. Os usuários de tecnologia assistiva dependem da semântica para navegar e entender o significado do conteúdo. A função do elemento permite que o usuário acesse o conteúdo que procura rapidamente e, possivelmente, o mais importante, informa ao usuário do leitor de tela como interagir com um elemento interativo depois que ele está em foco.

Elementos interativos, como botões, links, intervalos e caixas de seleção, têm funções implícitas, são adicionados automaticamente à sequência de guias do teclado e todos têm suporte padrão esperado para ações do usuário. O papel implícito, ou o valor role explícito, informa ao usuário o que é esperado de interações de usuário padrão específicas do elemento.

Com o atributo role, é possível atribuir uma função a qualquer elemento, incluindo uma função diferente da indicada pela tag. Por exemplo, <button> tem o papel implícito de button. Com role="button", é possível transformar qualquer elemento semanticamente em um botão: <p role="button">Click Me</p>.

Embora a adição de role="button" a um elemento informe aos leitores de tela que o elemento é um botão, ela não muda a aparência ou a funcionalidade do elemento. O elemento button oferece muitos recursos sem que você precise fazer nada. O elemento button é adicionado automaticamente à sequência de ordenação de guias do documento, o que significa que ele pode ser focado pelo teclado por padrão. As teclas Enter e a barra de espaço ativam o botão. Os botões também têm todos os métodos e propriedades fornecidos pela interface HTMLButtonElement. Se você não usar o botão semântico, será necessário programar todos esses recursos novamente. É muito mais fácil usar o <button>.

Volte para a captura de tela do AOM para o bloco de código não semântico. Elementos não semânticos não têm papéis implícitos. É possível tornar a versão não semântica semântica atribuindo a cada elemento um papel:

<div role="banner">
  <span role="heading" aria-level="1">Three words</span>
  <div role="navigation">
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
    <a>one word</a>
  </div>
</div>

O atributo role pode ser usado para adicionar semântica a qualquer elemento, mas você pode usar elementos com o papel implícito necessário.

Elementos semânticos

Perguntar a si mesmo: "Qual elemento melhor representa a função dessa seção da marcação?" geralmente resultará na escolha do melhor elemento para o trabalho. O elemento escolhido e as tags usadas precisam ser apropriados para o conteúdo exibido, já que as tags têm significado semântico.

O HTML deve ser usado para estruturar o conteúdo, não para definir a aparência dele. A aparência é o domínio do CSS. Embora alguns elementos sejam definidos para aparecer de uma determinada maneira, não use um elemento com base em como a folha de estilo do user agent faz com que esse elemento apareça por padrão. Em vez disso, selecione cada elemento com base no significado semântico e na funcionalidade dele. Codificar HTML de maneira lógica, semântica e significativa ajuda a garantir que o CSS seja aplicado conforme o esperado.

Escolher os elementos certos para o trabalho enquanto você codifica o código significa que não será necessário refatorar ou comentar seu HTML. Se você pensar em usar o elemento certo para a vaga, na maioria das vezes escolherá o elemento certo para a tarefa. Caso contrário, provavelmente não o fará. Quando você entende a semântica de cada elemento e sabe por que escolher o elemento certo é importante, geralmente é possível fazer a escolha certa sem muito esforço adicional.

Na próxima seção, você vai usar os elementos semânticos para criar a estrutura do documento.

Teste seu conhecimento

Teste seus conhecimentos sobre HTML semântico.

Sempre adicione role="button" a um elemento <button>.

Falso
Correto. O elemento <button> já tem essa função.
Verdadeiro
Tente de novo.