HTML semântico: como estruturar páginas mais acessíveis
Tags como header, nav, main e article não são só organização visual — definem o que cada parte da página significa para leitores de tela, crawlers e SEO.
Abri o DevTools numa landing page de um cliente semana passada e o que vi foi uma parede de <div>. Div com classe header, div com classe nav, div com classe content, div com classe footer. Tudo funcionando perfeitamente no Chrome. Nenhum leitor de tela conseguia navegar direito. Nenhum crawler conseguia distinguir o conteúdo editorial do menu. Isso é div-soup — e é mais comum do que deveria ser.
HTML semântico é a prática de usar os elementos certos pro que eles representam. Não é sobre CSS, não é sobre JavaScript. É sobre o significado que você comunica ao navegador, ao Google, e a qualquer tecnologia assistiva que tenta entender sua página.
Por que div e span não são suficientes
<div> e <span> são elementos sem significado. Eles existem pra agrupar conteúdo com propósito estético ou de scripting — e só. O navegador, o leitor de tela, e o crawler sabem que um <div> contém algo, mas não fazem a menor ideia do quê.
Quando você usa <nav>, você está dizendo: isso é navegação. Quando usa <main>, está dizendo: esse é o conteúdo principal da página. Quando usa <article>, está dizendo: isso é uma unidade de conteúdo auto-suficiente que faz sentido fora de contexto.
A diferença parece pequena até você abrir um leitor de tela como NVDA ou VoiceOver. Usuários cegos navegam por landmarks — eles pressionam uma tecla e pulam diretamente para <main>, ou listam todos os <nav> da página. Com div-soup, esse atalho simplesmente não existe.
As tags que resolvem a maioria dos casos
O HTML5 adicionou um conjunto de elementos estruturais que cobrem praticamente qualquer layout de site moderno. A maioria dos devs conhece os nomes, poucos usam corretamente.
<header> e <footer>
Podem aparecer dentro de <body> (cabeçalho/rodapé da página) ou dentro de <article> e <section> (cabeçalho/rodapé de uma seção). Não são elementos únicos por página — você pode ter múltiplos <footer>, cada um com escopo diferente.
<body>
<header>
<a href="/">Logo</a>
<nav>...</nav>
</header>
<main>
<article>
<header>
<h1>Título do artigo</h1>
<time datetime="2026-06-13">13 de junho de 2026</time>
</header>
<!-- conteúdo -->
<footer>
<p>Autor: Rafael Duarte</p>
</footer>
</article>
</main>
<footer>
<p>© 2026 Quick Tools</p>
</footer>
</body>
<nav>
Para blocos de navegação — menu principal, breadcrumbs, paginação. Não precisa de um aria-label se há só um na página. Se houver mais de um <nav>, adicione aria-label="Menu principal" e aria-label="Navegação do artigo" para diferenciá-los.
<main>
Deve existir exatamente uma vez por página. Contém o conteúdo único daquela página — o que diferencia ela de todas as outras. Não entra dentro de <header>, <footer>, <aside> ou <nav>.
<article> vs <section>
Essa é a confusão mais comum. O teste prático:
<article>: faria sentido como post independente num feed RSS? Sim → use<article>. Post de blog, card de produto, comentário, widget de clima.<section>: é um grupo temático de conteúdo que não faz sentido sozinho fora da página? Use<section>.
Um post de blog é um <article>. Os capítulos dentro desse post são <section>. Os comentários lá embaixo são vários <article> dentro de uma <section>.
<main>
<article>
<h1>HTML semântico: estrutura que importa</h1>
<section>
<h2>Por que div não é suficiente</h2>
<p>...</p>
</section>
<section>
<h2>As tags principais</h2>
<p>...</p>
</section>
<section aria-label="Comentários">
<h2>Comentários</h2>
<article>
<p><strong>João:</strong> Ótimo post!</p>
</article>
</section>
</article>
</main>
<aside>
Conteúdo relacionado mas dispensável — sidebar, caixas de "Você também pode gostar", notas de rodapé, publicidade. Se remover o <aside>, o conteúdo principal ainda deve fazer sentido completo.
A hierarquia de headings é tão importante quanto as tags
Tags semânticas estruturam a página, mas os headings estruturam o conteúdo. A regra é simples: deve existir exatamente um <h1> por página, e os headings não devem pular níveis.
Isso significa: não use <h3> depois de <h1> só porque você quer um texto menor. Use CSS pra tamanho, use headings para hierarquia.
<!-- errado -->
<h1>Título principal</h1>
<h3>Subtítulo (pulou h2)</h3>
<!-- certo -->
<h1>Título principal</h1>
<h2>Subtítulo</h2>
<h3>Sub-subtítulo</h3>
Leitores de tela geram um outline da página a partir dos headings. Quando você pula níveis, esse outline fica quebrado — e o usuário que depende dele perde a estrutura navegável do conteúdo.
Se você ainda está aprendendo como o navegador interpreta e renderiza esse HTML antes mesmo dos estilos entrarem, o post Como funciona uma página web cobre o ciclo completo desde o DNS até o paint da página.
O impacto real em SEO
O Google não é um leitor de tela, mas usa a estrutura semântica de forma semelhante. O <main> sinaliza onde está o conteúdo principal. O <article> sugere que aquilo é conteúdo editorial. Os <h1>–<h6> constroem o esqueleto temático da página.
O efeito não é mágico. Semântica correta não substitui conteúdo relevante, links de qualidade ou velocidade de página. Mas ela remove ruído — ajuda o crawler a entender o que é conteúdo e o que é UI. Em sites grandes, isso tem impacto no crawl budget.
Um ponto prático: o Google usa o <title> e o primeiro <h1> para entender o tema da página. Se esses dois não estiverem alinhados — ou se você tiver vários <h1> na mesma página porque o framework injetou um no header e outro no main — você está mandando sinal contraditório.
ARIA: quando usar e quando não usar
ARIA (Accessible Rich Internet Applications) são atributos que adicionam semântica onde o HTML nativo não cobre — como componentes customizados (role="dialog", role="tabpanel").
A regra número um do ARIA é: não use ARIA onde HTML nativo funciona. Se você pode usar <button>, use <button>. Não crie <div role="button"> — você vai precisar implementar manualmente o comportamento de teclado, foco e estado que <button> dá de graça.
<!-- ruim: div pretendendo ser botão -->
<div class="btn" role="button" onclick="...">Enviar</div>
<!-- bom: elemento nativo com toda a semântica embutida -->
<button type="submit">Enviar</button>
O <button> nativo é focável por teclado, ativável por Enter e Espaço, anunciado corretamente por leitores de tela, e recebe estilos de :focus automaticamente. O <div> precisa de uns 30 linhas de JavaScript pra chegar no mesmo lugar.
Validando sua estrutura antes de subir
Depois de montar a estrutura semântica, o Meta Tag Generator ajuda a conferir o que o Google vai ler no <head> da sua página — title, description, og:image, canonical — que complementam a semântica do corpo.
Para o outline de headings e landmarks, o plugin WAVE no Chrome ou o painel de Accessibility no DevTools do Firefox mostram a estrutura como um leitor de tela enxerga. Vale checar antes de ir pra produção.
Perguntas frequentes
Qual é a diferença entre <section> e <div>?
<div> não tem significado semântico — é um container genérico para agrupamento visual ou scripting. <section> indica uma seção temática do documento e tipicamente inclui um heading. Leitores de tela podem listar sections como landmarks; divs são invisíveis para esse tipo de navegação. A regra prática: se você não tem um heading pra colocar dentro, provavelmente um <div> é mais honesto.
HTML semântico realmente afeta o SEO na prática?
Sim, mas de forma indireta e difícil de isolar. O Google afirma que usa a estrutura HTML para entender o conteúdo — <article>, <main>, headings bem hierarquizados. O que está documentado concretamente: Google usa o <h1> como sinal de tema; rich results para artigos dependem de structured data que complementa a semântica HTML; erros de marcação (como múltiplos <h1>) são capturados no Search Console. O impacto é mais sobre clareza do que sobre ranking direto.
Posso ter mais de um <main> na página?
Não. A spec do HTML define que só pode haver um <main> visível por página. Você pode ter múltiplos <main> se os extras tiverem o atributo hidden, mas apenas um deve estar ativo e visível por vez. Frameworks de SPA que montam layouts complexos às vezes violam essa regra sem querer — vale conferir no DevTools.
<header> dentro de <article> é diferente do <header> da página?
Sim. O <header> tem escopo do ancestral mais próximo — se estiver dentro de um <article> ou <section>, ele é o cabeçalho daquele elemento, não da página. O <header> no nível do <body> é o cabeçalho da página. Leitores de tela distinguem os dois e anunciam o contexto corretamente.
Estrutura é comunicação
HTML semântico não é formalismo. É a diferença entre uma página que qualquer agente — humano, crawler, leitor de tela, LLM fazendo scraping — consegue entender sem precisar inferir da aparência visual.
Div-soup funciona no Chrome. Funciona no Firefox. Não funciona pra quem usa teclado pra navegar, não funciona pra quem precisa de contraste alto, não funciona pra quem usa leitor de tela. Esses usuários existem — e em projetos corporativos, acessibilidade é obrigação legal em vários países.
O esforço é baixo: trocar os <div class="header"> pelos elementos certos leva menos de uma hora num projeto existente. O retorno é estrutura que funciona pra todos, SEO mais limpo, e um código que qualquer dev entende sem precisar ler o CSS.
- 01 O que é DevOps além das ferramentas DevOps não é um pipeline nem um cargo. É responsabilidade compartilhada entre quem escreve código e quem coloca em produção — e por que a maioria dos times erra nisso.
- 02 VPS, VPC e servidor dedicado: diferenças VPS, VPC e servidor dedicado aparecem juntos em toda comparação de hospedagem — mas significam coisas bem diferentes. Entenda onde o dinheiro vai e como decidir.