HTML Semântico: O que, por quê e como
Tags: webdev, html, a11y, braziliandevs
Published: 2024-07-16 15:36:03

_**Nota:** apenas traduzi o texto abaixo e postei aqui. As referências estão no fim deste artigo._

## O que

1.    Use elementos HTML elements para a finalidade pretendida deles.
2.    Separe o conteúdo da apresentação

## Por quê

É mais fácil de ler e naturalmente leva a um código mais consistente. O código HTML consistente é mais fácil de estilizar.

Isso ajudará o seu SEO.

O HTML literalmente fará o seu trabalho para você, inclusive tornando sua página muito mais acessível. Basicamente, uma web page é um document que você deseja que qualquer pessoa possa ler. Use HTML para criar esse document. Javascript e CSS são complementos.

## Como

Pergunte a si mesmo se existe uma tag com mais significado que você pode usar ao acessar uma `<div>` ou `<span>`.

Pesquise no Google se o HTML faz isso antes de construí-lo.

## Estrutura raiz de uma página

`<!DOCTYPE html>` e `<html lang="en">` informam às máquinas que este é um HTML document escrito em inglês. O `<head>` element contém seus metadados. `<meta lang="en" charset="utf-8">` é importante. Diz ao navegador como decode e encode seus caracteres para máquinas e humanos. Finalmente, a `<body>` tag envolve o conteúdo da sua página.

```html
<!DOCTYPE html>
<html lang=“en”>
    <head>
        <meta charset="utf-8">
        <meta></meta>
        <title></title>
    </head>
    <body>
        { Seu conteúdo aqui }
    </body>
</html>
```

## SEO

Antes de passarmos para o conteúdo de `<body>`, vamos falar sobre os elements que vão em `<head>`. Primeiro, não esqueça do seu `<title>`! Mantenha-o descritivo e com menos de 60 caracteres. Inclua a marca, se você tiver uma.

Use `<link rel="icon" type="image/x-icon" href="/images/favicon.ico">` para definir seu favicon - o pequeno logotipo na aba do navegador.

Tipos de <meta> tags:

-    description: mantenha isso com menos de 160 caracteres, descritivo, com keywords curtas ou permita que as search engines escrevam isso para você.
-    keywords: se quiser sugerir keywords que você acha que uma search engine não utilizará elas, faça isso.
-    [open graph](https://ahrefs.com/blog/open-graph-meta-tags/): controle como seu conteúdo é exibido em sites de mídia social como Facebook e LinkedIn.
-    [Twitter Cards](https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started): controle a aparência do seu site nos Twitter Cards.
-    [robots](https://www.woorank.com/en/edu/seo-guides/meta-robots-tag-seo): diga aos search engine crawlers o que fazer com as informações do seu site.

Sempre adicione sua `viewport meta tag` - ela informa às search engines que você tem um site responsivo e evita que os dispositivos redimensionem sua viewport.

```html
<meta name="viewport" content="width=device-width, initial-scale=1">
```

Por fim, use uma `<script>` tag para adicionar [schema markup](https://www.link-assistant.com/news/structured-data-for-seo.html) para controlar como seu site é exibido nas search engines.

## Colocando o conteúdo em seções

Começando:

1.    Coloque no topo de sua página coisas como logo, main navigation e uma heading em `<header>`.
2.    Qualquer navigation menu fica em `<nav>`.
3.    Todo aquele conteúdo bom e exclusivo da página vai para `<main>`. O ponto principal da sua página, se preferir.
4.    Na parte inferior da página, coisas como copyright, autoria, contato e talvez um pouco mais de navegação (algo como um link que volte ao topo da página) vão em `<footer>`.
5.    Use `<p>` para o seu texto.
6.    Use `<ul>` ou `<ol>` contendo `<li>`s para suas listas.

**Lembre-se**: separe o conteúdo e a apresentação. `<nav>` é para navegação no site, não para listas de links. `<header>` e `<footer>` são para "branding" e para o conteúdo de navegação que você teria na parte superior e inferior de cada página do seu site.

### `<article>` vs `<section>` vs `<aside>`

Use `<article>` e `<section>` para agrupar conteúdo em `<main>`.

O conteúdo em `<article>` ainda deve fazer sentido se tiver sido colocado sozinho em uma página completamente diferente.

`<section>` agrupa conteúdo sobre o mesmo tema. Pode até entrar em `<article>`.

O que não é o conteúdo principal vai para `<aside>`. É complementar, mas não vital. Aninhe este element dentro do element que contém o conteúdo ao qual está relacionado. Pode estar dentro de `<main>` desde que esteja dentro de outro "sectioning element" como `<article>`. O conteúdo encapsulado em `<aside>` pode estar em um sidebar, mas "sidebar" é um conceito de apresentação.

![css styling meme](https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fik3j1p7sglaqeuetyxb2.jpeg "css styling meme")

### Headings

Estamos falando de `<h1>` até `<h6>`. Eles devem estar na sua página em ordem crescente, começando com `<h1>`, sem pular níveis. Raramente há motivo para ficar abaixo de `<h3>`.

Usar headings consistentes e "query-like" apenas ajuda ao seu SEO.

Você deve ter UM e APENAS UM `<h1>` por página.

-    **MITO**: `<section>` reinicia a heading order.
-    **VERDADE**: Os navegadores não implementaram essa feature listada nas especificações do HTML5.

### Tables

Já se foram os dias em que se usava tables para criar layout de conteúdo - isso é apresentação. Use o `<table>` element para estruturar dados tabulares.

Uma table básica de 2 colunas e 2 linhas:

```html
<table>
    <caption>My basic table</caption>
    <tr>
        <th>Column 1</th>
        <th>Column 2</th>
    </tr>
    <tr>
        <td>Data 1</td>
        <td>Data 2</td>
    </tr>
</table>
```

Aprimore suas tables com `<col>`, `<colgroup>`, `<tbody>`, `<thead>`, `<tfoot>` e `<scope>`.

### Forms

Encapsule seu formulário em `<form>`. Use `<fieldset>` para agrupar form options juntas e `<legend>` para "label" elas. Você pode usar `<li>`, `<ul>`, `<ol>`, `<p>`, `<section>` e headings dentro do `<form>` element.

Mais sobre form controls mais adiante.

## Verifique sua Outline

Sectioning elements e heading elements trabalham juntos para criar uma document outline para sua página. Quando você achar que configurou sua página, tente navegar nela com um screen reader. Verifique com um [HTML validator](https://validator.w3.org/).

Se você achar que há gaps em sua document outline, você pode adicionar [ARIA landmark roles](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/landmark_role) usando o atributo role="" em seus container elements.

Isso é manualmente adicionado, o que o HTML semântico faz por você. Um screen reader leria "navigation" para um usuário tanto para `<div role="navigation">` quanto para `<nav>`.

Landmark roles como `<main>`, `<header>` e `<footer>` devem aparecer apenas uma vez em uma página.

## Enriqueça seu conteúdo com HTML

`<em>` produzirá texto em itálico. Ele também instrui um screen reader a informar ao usuário que o texto foi enfatizado.

`<strong>` produzirá texto em negrito. Ele também informa a um screen reader para informar ao usuário que o texto tem importância adicional.

Use CSS em vez de `<b>` e `<i>`.

Se o conteúdo da imagem for necessário para a compreensão do conteúdo ao seu redor, use `<figure>` e `<figcaption>`.

Caso contrário, use `<img>` e não se esqueça do texto no atributo `alt`!

`<blockquote>` cria uma "block quote" (como `display: block;`).

`<q>` cria uma "inline quote".

`<blockquote>` e `<q>` dirão ao screen reader para informar ao usuário que é uma "quote".

Use `<cite>` para citar suas fontes (sources).

Se você quisesse usar uma "quote", diga quem a disse e cite sua fonte, ficaria assim:

```html
<figure>
    <blockquote>Separate content and presentation!</blockquote>
    <figcaption>
        <p>Abbey in 
            <cite>
                <a href="https://thispresentation.com">
                    this presentation.
                </a>
            </cite>
        </p>
    </figcaption>
</figure>
```

## Dê mais informações às máquinas

-    `<date>` e `<time>` - seja gentil com o computador e diga que esta é uma date ou time
-    `<abbr>` - defina sempre suas abreviações!
-    `<dd>`, `<dl>`, `<dt>` - defina outras coisas
-    `<pre>` - texto pré-formatado
-    `<code>` - é código!
-    `<var>` - é uma variável!
-    `<data>` - dados legíveis por máquina
-    `<address>` – informações de contato do parent element.

Dentro de `<footer>`, `<address>` é identificado como as informações de contato do proprietário da web page!

## Permita que o HTML faça o trabalho por você

### Form Controls

`<textarea>` permite ao usuário enviar texto de formato livre. Ele tem muitos atributos que você pode usar, incluindo a ativação da spellcheck (verificação ortográfica)!

`<select>` cria um drop down para você e usar o atributo `multiple` permite que os usuários selecionem múltiplas opções.

`<option>` cria uma option para `<select>`. Quando várias `<option>`s são encapsuladas em `<datalist>`, eles criam sugestões para autocomplete.

`<progress>` e `<meter>` criam barras de progresso e medição para você!

Usar os atributos `action` e `method` do `<form>` ativa HTTP messaging integrado. `<button>` ou `<button type="submit">` dentro de `<form>` criará automaticamente um _submit/send button_ para seu HTTP messaging. `<button type="reset">` dentro de `<form>` cria automaticamente um button que irá reset todos os controls do `<form>`.

#### &lt;input type=""&gt;

Sim, HTTP messaging integrado é legal, mas se você tem usuários submitting dados, provavelmente está usando `<input>`. `<input type="image">` cria uma imagem que funciona como um button. Por que criar seus próprios pickers ou file uploader quando você tem `<input type="color">`, `<input type="datetime-local">` e `<input type="file">`? Types como `email` e `password` possuem validation options integradas. Abaixo é demonstrado todos os diferentes tipos de `<input>`:

```html
<input type="checkbox">
<input type="file">
<input type="hidden">
<input type="password">
<input type="radio">
<input type="button" value="Click Me">
<input type="reset">
<input type="submit">
<input type="text">
<input type="url">
<input type="number">
<input type="range">
<input type="datetime-local">
<input type="time">
<input type="month">
<input type="week">
<input type="color">
<input type="search">
<input type="email">
<input type="tel">
<input
    type="image"
    src="https://www.petmd.com/sites/default/files/styles/article_image/public/2022-02/hamster.care_.jpg?itok=vL3xRPq6"
>
```

Veja isso no [codepen](https://codepen.io/abbeyperini/details/mdpJxXV).

#### &lt;label&gt;

Associar uma `<label>` a um `<input>` não é apenas acessível, mas também oferece vantagens programáticas em seu código e em mensagens HTTP. Por exemplo, clicar em um `<label>` é o mesmo que clicar em seu `<input>` associado.

Não associe uma `<label>` a um `<button>` ou `<input>` com `type=button`, `reset` ou `submit`. Nunca coloque um heading no sua `<label>`.

#### &lt;button&gt; vs &lt;a&gt;

Literalmente nunca crie seu próprio button. Basta usar `<button>`.

Um screen reader trata buttons e links de maneira muito diferente. Eles têm diferentes propriedades, comportamentos e estados integrados. Buttons feitos com `<a>` (o que novamente você nunca deve fazer) serão agrupados com outros links.

Os buttons servem para executar uma ação (a menos que essa ação seja navegar para outra página). Buttons e inputs podem ser acionados com "Space" e "Enter" para usuários de teclado. O `<button>` element fornece automaticamente estados de hover e focus.

Anchor tags (`<a>`) são para links e [fornecem SEO útil](https://www.semrush.com/blog/what-is-anchor-text-and-how-can-i-optimize-it/). Anchor tags são acionadas apenas ao "Enter".

#### Menção especial: &lt;button&gt; vs &lt;input type="button"&gt;

Um `<button>` pode ter conteúdo e é mais fácil de estilizar. Um `<button>` dentro de um `<form>` sem um type especificado se tornará automaticamente um `<button type="submit">`. `<input type="button">` não tem comportamento default, tornando-o menos semântico e acessível. Isso faz com que ele se comporte de maneira mais consistente entre os navegadores. Isto foi particularmente importante ao tentar oferecer suporte ao IE6/IE7. `<input type="submit">` e `<input type="reset">` têm o comportamento default de submitting um form ou reset todos os form controls quando dentro de um `<form>`, mas nada mais.

### Outros elements que fazem muito trabalho

`<details>` e `<summary>` trabalham juntos para criar um toggle. `<audio>` e `<video>` possuem players integrados com controls.

```html
<details> 
    <summary>
        Click for more details
    </summary>
    <p>
        I would put a lot more details here if I had them
    </p>
</details>
<audio
    src="//samplelib.com/lib/preview/mp3/sample-3s.mp3"
    controls
></audio>
<video
    src="//samplelib.com/lib/preview/mp4/sample-5s.mp4"
    controls
></video>
```

Veja isso no [codepen](https://codepen.io/abbeyperini/pen/bGadvZo).

`<picture>` encapsula vários elements `<img>` ou `<source>` e escolhe o melhor com base nos cenários de display/device. `<iframe>` pode ser usado para interceptar código remoto ou user input em um contexto separado da sua página por motivos de segurança.

## Conclusão

Aprender e usar HTML semântico oferece muitas funcionalidades sem levantar um dedo. Ele também permite que você incorpore acessibilidade e SEO com muito pouco esforço. Sem mencionar que isso leva a um código mais limpo e um código mais limpo é mais fácil de estilizar. Existem cerca de 100 elements HTML semânticos - não construa o que o HTML lhe entrega em uma bandeja de prata.

## Fonte

[Artigo](https://dev.to/abbeyperini/semantic-html-what-why-and-how-3b34?fbclid=IwZXh0bgNhZW0CMTEAAR29gicxC-LskiVgFJEl-xj8h3oxHS605dQTa_E7E16rriBbRgkB5HglJ5M_aem_XvJ0VYAKXqx0FkFGbM8bQg) escrito por **Abbey Perini**.