Skip to content
This page has been auto-translated and may contain errors.View in English

HTML Semântico

docs.scrimba.com

Duas páginas podem parecer idênticas e serem construídas de formas muito diferentes por baixo. Uma usa elementos nomeados de acordo com o que contêm: um cabeçalho, uma navegação, uma área principal. A outra envolve tudo na mesma caixa anônima e depende de nomes de classes para diferenciá-los. Na tela, você não consegue diferenciá-los. Em todos os outros aspectos, não são a mesma página. Escolher elementos pelo seu significado é sobre o que é HTML semântico.

O que semântico significa

Semântico significa "relacionado a significado". Um elemento semântico é aquele cujo nome diz o que seu conteúdo é. Um parágrafo vai em um <p> porque é um parágrafo. Um menu de navegação vai em uma <nav> porque é navegação. A tag nomeia a coisa.

Você poderia construir quase qualquer página a partir de uma caixa única de propósito geral e fazê-la parecer certa com estilos. Mas então nada na página diria o que é. Escolher o elemento que nomeia o conteúdo é como etiquetar as caixas quando você se muda. Tudo ainda caberia em caixas simples sem rótulo, mas os rótulos são o que permite que qualquer outra pessoa, ou um navegador, entenda o que está dentro sem abrir cada uma.

Um elemento é semântico quando seu nome descreve o significado de seu conteúdo, não como o conteúdo se parece. <nav>, <article> e <button> são semânticos: eles dizem para que o conteúdo serve. <div> e <span> não são: são contêineres genéricos que não significam nada por si sós.

A vantagem é que o significado fica na marcação, onde outras ferramentas podem lê-lo. Um navegador sabe que um <button> é clicável e focável com o teclado sem você adicionar nada. Um leitor de tela pode anunciar uma <nav> como uma região de navegação. Os mecanismos de busca tratam um <article> como um conteúdo independente. Nada disso funciona se o elemento é uma <div> estilizada, porque uma <div> não promete nada sobre o que contém.

Semântica é a diferença entre um elemento que carrega significado e um que apenas carrega pixels. Quando você escreve <nav>, você não está apenas desenhando uma caixa, está afirmando um fato sobre o documento: esta região é navegação. Esse fato é registrado na árvore de acessibilidade (a estrutura paralela que o navegador constrói junto com o DOM, descrevendo o papel e estado de cada elemento para tecnologia assistiva), e é sobre o que ferramentas outras que não um usuário de mouse com visão atuam.

O teste prático é substituição. Se você substituísse um elemento por um <div> simples e o estilizasse para parecer idêntico, o que você perderia? Para um <p> ou um wrapper decorativo, nada significativo. Para um <button>, você perderia o foco do teclado, o tratamento das teclas Enter e Space, e o anúncio "botão" para um leitor de tela, e teria que reconstruir tudo manualmente. Essa lacuna é a semântica: o comportamento e significado que o navegador te dá de graça porque o nome do elemento disse a ele o que o conteúdo é. Escolher o elemento nomeado não é uma preferência de estilo, é a forma mais barata de obter comportamento correto.

JunoO que semântico significa Semântico significa que a tag é nomeada depois do que contém: um parágrafo em um <p>, um menu em uma <nav>. Você poderia colocar tudo em caixas simples e estilizar para parecer o mesmo, mas então nada diz o que é. Pense em etiquetar suas caixas de mudança para que qualquer um possa dizer o que está dentro.
JunoO que semântico significa Um elemento semântico nomeia seu significado, uma <div> não nomeia nada. A vantagem é que navegadores, leitores de tela e mecanismos de busca podem ler o significado direto da marcação. Busque o elemento que descreve o conteúdo e mantenha <div> para quando realmente não há nada para descrever.
JunoO que semântico significa Execute o teste de substituição: troque o elemento por uma <div> estilizada e pergunte o que você perdeu. Se a resposta é foco do teclado, um papel na árvore de acessibilidade ou um anúncio de leitor de tela, essa é a semântica que você estava obtendo de graça. Reconstruir manualmente é sempre mais trabalho do que usar o elemento nomeado.

Os elementos de referência

Um punhado de elementos existe para marcar as grandes regiões de uma página. Esses são os que você busca primeiro:

  • <header> é o topo de uma página ou seção: um logotipo, um título, uma introdução.
  • <nav> é um conjunto de links de navegação, como o menu principal.
  • <main> é o conteúdo principal, a razão pela qual a página existe.
  • <section> é um pedaço agrupado de conteúdo relacionado, geralmente com seu próprio título.
  • <article> é uma peça independente que ainda faria sentido por conta própria, como um post de blog ou uma notícia.
  • <aside> é conteúdo de lado: links relacionados, uma nota, um anúncio.
  • <footer> é o fundo de uma página ou seção: direitos autorais, detalhes de contato, texto pequeno.

A regra é a mesma toda vez. Se uma região é navegação, vai em uma <nav>, não em uma <div>. Se é o rodapé, vai em um <footer>. Você nomeia a região com o elemento que a corresponde.

html
<header>
  <h1>Cozinha da Marina</h1>
  <nav>
    <a href="/recipes">Receitas</a>
    <a href="/about">Sobre</a>
  </nav>
</header>
<main>
  <h2>Jantares simples</h2>
  <p>Refeições rápidas que você pode fazer depois do trabalho.</p>
</main>
<footer>
  <p>Feito em São Paulo.</p>
</footer>

Sete elementos dividem uma página em suas regiões principais, e juntos são chamados de elementos de referência porque cada um marca uma região para a qual um leitor ou ferramenta pode navegar:

  • <header> apresenta seu contêiner mais próximo: no topo da página, mantém a marca do site, dentro de um <article> mantém o título e byline daquele artigo.
  • <nav> envolve um bloco de links de navegação. Use-o para os significativos, o menu principal ou um índice, não para cada link solto na página.
  • <main> mantém o conteúdo principal do documento, a parte única desta página em vez de repetida em todo o site.
  • <section> agrupa conteúdo relacionado que pertence junto, normalmente apresentado por um título.
  • <article> é uma unidade completa e independente: um post, um comentário, um card de produto. O teste é se ainda faria sentido ser retirado e mostrado por conta própria.
  • <aside> mantém conteúdo tangencial ao que o circunda: uma barra lateral, uma citação em destaque, links relacionados.
  • <footer> fecha seu contêiner mais próximo com o material de encerramento: autoria, links, texto legal.

A ideia-chave é que a maioria desses são contextuais. Um <header> e um <footer> descrevem o que quer que se sentem dentro, então uma página única pode manter vários de cada um, um par para a página e um para cada <article>. <main> é a exceção, coberta na próxima seção.

html
<article>
  <header>
    <h2>Sopa de tomate assado</h2>
    <p>Por Lucas, 20 minutos</p>
  </header>
  <p>Corte os tomates ao meio e asse-os até ficarem macios.</p>
  <footer>
    <p>Serve quatro pessoas.</p>
  </footer>
</article>

Os sete elementos de região são os marcos do HTML: elementos que expõem uma região navegável na árvore de acessibilidade. Cada um mapeia para um papel que a tecnologia assistiva pode listar e navegar, que é a razão inteira pela qual importam além de parecer arrumado na fonte.

  • <header> mapeia para o papel banner no nível da página, mas não quando está aninhado dentro de um <article>, <aside>, <main>, <nav> ou <section>, onde é apenas um grupo introdutório sem papel de marco.
  • <footer> reflete isso: contentinfo no nível da página, e um grupo simples quando aninhado dentro de um desses elementos de seção.
  • <nav> é o papel navigation. Uma página comumente tem mais de um, um menu primário e uma lista de conteúdos na página, que é onde a rotulagem entra abaixo.
  • <main> é o papel main e marca o conteúdo principal. Há um por página.
  • <aside> é o papel complementary: conteúdo que suporta o conteúdo principal mas se destaca dele.
  • <section> torna-se um marco region apenas quando tem um nome acessível, normalmente de um título vinculado a ele; uma <section> sem nome não expõe um marco e é, para a árvore de acessibilidade, perto de uma <div>.
  • <article> carrega o papel article, uma composição independente, que ferramentas podem enumerar mas que não é um marco de navegação no mesmo sentido que os outros.

O objetivo do design é um documento que um usuário não-visual pode pesquisar tão rápido quanto um usuário com visão escaneia o layout. Um leitor de tela pode produzir uma lista de cada marco e deixar o usuário pular direto para "main" ou "navigation" sem ouvir o conteúdo intermediário. Isso só funciona se as regiões são marcadas com elementos de marco reais. <div>s de parede a parede produzem um documento sem marcos algum, então o único jeito através dele é de cima para baixo.

html
<body>
  <header>            <!-- banner: nível de página -->
    <nav>...</nav>    <!-- navigation -->
  </header>
  <main>              <!-- main: a uma região primária -->
    <article>...</article>
    <aside>...</aside> <!-- complementary -->
  </main>
  <footer>...</footer> <!-- contentinfo: nível de página -->
</body>
JunoOs elementos de referência Há sete tags de região que vale a pena conhecer: <header>, <nav>, <main>, <section>, <article>, <aside> e <footer>. Cada uma nomeia uma parte da página, e você escolhe a que corresponde à região que está construindo. Você não tem que memorizá-las hoje, elas surgem de novo e de novo até grudar.
JunoOs elementos de referência Sete elementos dividem uma página em regiões, e a maioria delas descreve o que quer que se sentem dentro, então <header> e <footer> podem aparecer mais de uma vez. O teste <article> que me economizou muitas segundas confusões: isso poderia se manter sozinho se você o puxasse? Se sim, é um artigo; se é um pedaço agrupado com um título, é uma seção.
JunoOs elementos de referência Esses são os marcos, e cada um mapeia para um papel que um leitor de tela pode pular para, que é por que batem uma pilha de <div>s. Dois pontos que valem a pena guardar: <header> e <footer> só se tornam os marcos banner e contentinfo no nível superior, e um <section> só é um marco uma vez que tem um nome acessível. Uma seção sem nome é basicamente uma div para tecnologia assistiva.

div e span, o fallback não-semântico

Nem toda parte de uma página tem um significado que vale a pena nomear. Às vezes você apenas precisa de uma caixa para agrupar coisas para que você possa estilizá-las, ou envolver algumas palavras para colori-las. Para isso há dois elementos simples sem significado próprio.

<div> é um bloco genérico: um contêiner vazio que você usa quando nenhum outro elemento se encaixa. <span> é a mesma ideia para uma pequena série de texto dentro de uma linha. Nenhum deles diz nada sobre seu conteúdo. Eles existem puramente como ganchos para estilização e agrupamento.

html
<p>O total de hoje é <span class="price">R$ 42,00</span>.</p>

<div class="card">
  <h2>Oferta especial</h2>
  <p>Dois por um em toda massa.</p>
</div>

O <span> envolve um preço para que você possa colori-lo. O <div> agrupa um card para que você possa colocar uma borda ao redor. Busque esses apenas quando nada mais significativo se encaixa, porque eles não dizem ao navegador nada sobre o que está dentro.

<div> e <span> são os dois elementos sem significado algum, e é exatamente para o que são. Um <div> é um contêiner genérico de nível de bloco; um <span> é um genérico embutido. Você os usa como ganchos de estilização: um lugar para pendurar uma classe ou um id quando você precisa agrupar ou direcionar conteúdo mas não há nada significativo para dizer sobre isso.

html
<div class="grid">
  <article class="card">...</article>
  <article class="card">...</article>
</div>

O <div class="grid"> existe apenas para colocar os cards em um grid. Esse é um trabalho apresentacional, não um significativo, então um <div> é a escolha correta, não um fallback que você deveria se sentir mal. O erro é o reverso: usar um <div> para algo que tem significado. Um <div> clicável deveria ser um <button>, um <div> cheio de links de navegação deveria ser uma <nav>, um <div> envolvendo um post inteiro deveria ser um <article>. Quando não há significado, apenas uma necessidade de layout ou estilo, <div> e <span> são a resposta certa.

<div> e <span> são os elementos semanticamente vazios: um contêiner genérico de bloco e um genérico embutido, respectivamente, sem papel na árvore de acessibilidade e nenhum significado para qualquer ferramenta. Eles são a escolha correta para um trabalho, um gancho apresentacional: um elemento que existe apenas para anexar estilo ou para agrupar filhos para layout, e que não carrega nenhuma informação que um leitor de tela ou mecanismo de busca deveria anunciar.

O valor de ter um elemento sem significado algum é que mantém os elementos significativos verdadeiros. Um wrapper de grid, uma linha de flexbox, um contexto de posicionamento: essas são necessidades reais sem conteúdo semântico, e forçar um elemento significativo sobre eles seria uma mentira na marcação. Uma <section> usada apenas para uma cor de fundo afirma ser uma região que não é. Então a regra vai nos dois sentidos. Não busque um <div> quando um elemento nomeado se encaixa, e não busque um elemento nomeado quando tudo que você precisa é uma caixa.

O modo de falha a ficar atento é o <div> interativo: um elemento recebido um manipulador de clique em JavaScript para agir como um botão ou um link. Renderiza e clica com um mouse, então parece acabado, mas não tem papel, não está na ordem de tabulação, não responde a Enter ou Space, e um leitor de tela não anuncia nada. Recriar tudo isso com tabindex, role e manipuladores de chave é uma reimplementação frágil de um <button> que já existe. Se uma coisa se comporta como um controle, use o elemento de controle; mantenha <div> e <span> para as partes que são apenas pixels.

Junodiv e span, o fallback não-semântico<div> é uma caixa simples e <span> é um wrapper simples para algumas palavras, e nenhum deles significa nada. Use-os quando você apenas precisa agrupar ou estilizar algo e nenhum elemento nomeado se encaixa. Se a coisa tem um significado, como um menu ou um botão, use o elemento para isso em vez disso.
Junodiv e span, o fallback não-semântico Um <div> ou <span> é a escolha certa quando o único trabalho é layout ou estilo, sem significado para afirmar. Não se sinta mal sobre eles, se sinta mal sobre o reverso: um <div> clicável que deveria ser um <button>, ou um wrapper <div> que deveria ser um <article>. Elemento vazio para significado vazio, elemento nomeado para significado real.
Junodiv e span, o fallback não-semântico<div> e <span> não têm papel na árvore de acessibilidade, que é precisamente por que são certos para ganchos de estilo puro e errados para qualquer coisa significativa. O que vai te morder é o <div> interativo com um manipulador de clique: sem foco, sem teclado, sem anúncio, e uma pilha de correções de tabindex e role para fingir o que <button> te dá de graça. Se se comporta como um controle, torne-o o controle.

Escolhendo o elemento certo

Quando você não tem certeza de qual elemento usar, faça uma pergunta clara: o que é essa coisa? Não o que parece, mas o que é. A resposta geralmente nomeia o elemento para você. Uma fileira de links no topo é navegação, então é uma <nav>. Um bloco de texto pequeno no fundo é um rodapé, então é um <footer>. Um preço que você quer colorir não é realmente nada, então é um <span>.

Comece pelo significado e apenas retroceda para um <div> ou <span> quando a resposta real é "é apenas uma caixa". Entrar nesse hábito cedo significa que suas páginas se descrevem, e isso compensa no momento em que você ou qualquer outra pessoa tiver que ler a marcação de novo.

Escolher o elemento certo é uma breve decisão que você pode executar toda vez. Pergunte o que o conteúdo é, e deixe a resposta escolher o elemento:

  • É sua própria coisa completa que faria sentido por conta própria? <article>.
  • É um pedaço agrupado de conteúdo relacionado com um título? <section>.
  • É navegação? <nav>. Uma apresentação para uma região? <header>. Um encerramento? <footer>.
  • É conteúdo lateral que suporta o conteúdo principal? <aside>.
  • Não há significado, apenas uma necessidade de layout ou estilo? <div> ou <span> dentro de uma linha.

O bifurcação mais complicada é <section> versus <article> versus <div>. Caminhe em ordem. Se o bloco poderia se manter sozinho, é um <article>. Se não, mas é um grupo temático com seu próprio título, é um <section>. Se não tem título e nenhum significado, e existe apenas para ser estilizado ou disposto, é um <div>. Um <section> deveria quase sempre ter um título; se você não consegue pensar em um, esse é um sinal forte de que você queria um <div>.

html
<main>
  <section>
    <h2>Posts recentes</h2>
    <article>
      <h3>Por que mudei para HTML simples</h3>
      <p>...</p>
    </article>
    <article>
      <h3>O caso contra frameworks pesados</h3>
      <p>...</p>
    </article>
  </section>
</main>

Aqui o <section> é um grupo temático, "posts recentes", e cada post dentro dele é um <article> porque se manter por conta própria. O aninhamento reflete o significado.

Escolher bem se reduz a ler o significado primeiro e o layout nunca, mas algumas regras tornam as decisões comuns mecânicas.

Há exatamente um <main> por página. Ele marca o conteúdo principal, a parte única desta página em vez do cabeçalho, navegação e rodapé repetidos em todo o site. Mais de um <main> na árvore de acessibilidade dá a um usuário de leitor de tela dois alvos "main" e nenhuma maneira de saber qual é o real, então mantenha-o singular. Tudo em todo o site pertence fora dele.

A outra regra que importa repetidamente é rotular marcos repetidos. Quando uma página tem dois elementos do mesmo tipo de marco, uma <nav> primária e um índice de página em página, ambos anunciam como "navegação" e o usuário não consegue diferenciá-los. Você desambigua com aria-label, um atributo que fornece um nome acessível curto para uma região sem mostrar nada na tela:

html
<nav aria-label="Principal">
  <a href="/">Início</a>
  <a href="/blog">Blog</a>
</nav>

<nav aria-label="Nesta página">
  <a href="#intro">Introdução</a>
  <a href="#setup">Configuração</a>
</nav>

Agora as duas regiões anunciam como "Navegação principal" e "Navegação nesta página", e a lista de marcos é utilizável. Aplique a mesma rotulagem a qualquer marco repetido, <aside> ou <section> incluídos. Para <section>, lembre-se que só se torna um marco uma vez que tem um nome acessível em tudo, seja a partir de um título associado ou um aria-label.

A meta-regra por trás de tudo isso: a marcação é uma descrição legível por máquina do documento, lida por leitores de tela, crawlers de busca, ferramentas de modo de leitura e seu eu futuro. Escolher elementos por significado é o que torna essa descrição verdadeira. Layout é trabalho do CSS, e toda vez que você se encontra escolhendo um elemento por como se parece, você cruzou para o caminho do CSS usando a ferramenta errada.

JunoEscolhendo o elemento certo Quando você está preso, pergunte o que a coisa é, não o que parece. Navegação é uma <nav>, texto pequeno é um <footer>, uma caixa simples que você quer estilizar é um <div>. Comece pelo significado toda vez, e suas páginas acabam se descrevendo.
JunoEscolhendo o elemento certo Execute a pequena lista de verificação: se manter por conta própria é um <article>, grupo temático com um título é um <section>, nenhum significado e apenas estilo é um <div>. O desempate que resolve a maioria dos argumentos section-versus-div: se você não consegue nomear um título para isso, você queria um <div>. Deixe o significado escolher a tag e o aninhamento se ordena.
JunoEscolhendo o elemento certo Duas regras carregam a maioria do peso: exatamente um <main> por página, e rotule marcos repetidos com aria-label para que duas navs não digam ambas "navegação". Mantenha em mente um <section> é apenas um marco uma vez que tem um nome acessível. Escolha elementos por significado e deixe as aparências para o CSS, porque no momento em que você escolhe uma tag por como renderiza, você está fazendo o trabalho do CSS com a ferramenta errada.