DevTools

Cheatsheet HTML

Linguagem de marcação para páginas web

Voltar às linguagens
HTML
103 cards encontrados
Categorias:
Versões:

Estrutura Básica


11 cards
Documento HTML5 Completo
<!DOCTYPE html>
<html lang="pt">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
    content="width=device-width, initial-scale=1.0">
  <title>Minha Página</title>
</head>
<body>
  <h1>Olá Mundo</h1>
</body>
</html>

Estrutura mínima obrigatória. O <!DOCTYPE html> declara HTML5. O lang="pt" define o idioma. O <meta charset> garante acentos corretos. O <meta viewport> torna a página responsiva.

Body — Conteúdo Visível
<body>
  <header>Topo</header>
  <main>
    <h1>Conteúdo principal</h1>
    <p>Texto visível ao utilizador.</p>
  </main>
  <footer>Rodapé</footer>
</body>

O <body> contém todo o conteúdo visível. Tudo o que o utilizador vê está aqui. Use tags semânticas como <header>, <main> e <footer> para organizar.

Atributos data-*
<li data-id="42" data-nome="Ana"
    data-ativo="true">
  Item personalizado
</li>

<!-- JavaScript: -->
<!-- el.dataset.id → "42" -->
<!-- el.dataset.nome → "Ana" -->

Atributos data-* guardam dados personalizados no HTML. Aceda via element.dataset.nome em JavaScript. Úteis para passar informação sem APIs externas.

DOCTYPE
<!DOCTYPE html>

Deve ser sempre a primeira linha do ficheiro. Informa o browser que o documento é HTML5. Sem ele, o browser entra em quirks mode (modo de compatibilidade antigo).

Comentários
<!-- Comentário simples -->

<!--
  Comentário
  multi-linha
-->

<!-- [if IE]>
  Só no Internet Explorer
<![endif] -->

Comentários são ignorados pelo browser. Úteis para documentar o código. Não use para "esconder" conteúdo — é visível no View Source. O formato é <!-- texto -->.

Atributos Globais
<div id="app" class="box" style="color:red"
     title="Tooltip" hidden tabindex="0"
     contenteditable="true" draggable="true"
     data-info="extra" lang="pt" dir="ltr">
  Editável e arrastável
</div>

Atributos globais funcionam em qualquer tag. hidden oculta, title mostra tooltip, tabindex define ordem de tab, contenteditable torna editável, draggable permite arrastar.

Elemento html e lang
<html lang="pt">
<html lang="pt-BR">
<html lang="en">

O atributo lang define o idioma da página. Essencial para SEO, leitores de ecrã e tradução automática. Use códigos ISO 639-1 (pt, en, es).

Div e Span
<div class="container">
  <p>Bloco genérico (block-level)</p>
</div>

<span class="destaque">Inline genérico</span>

<div> é um contentor de bloco (ocupa a linha toda). <span> é inline (só ocupa o conteúdo). Ambos não têm significado — use com CSS e JavaScript.

Entidades HTML
&lt; = <    &gt; = >
&amp; = &   &quot; = "
&nbsp; = espaço
&copy; = ©  &reg; = ®
&rarr; = →  &hearts; = ♥
&#128512; = 😀

Entidades representam caracteres especiais. &lt; e &gt; para < e >. &nbsp; é um espaço que não quebra. Use códigos numéricos (&#128512;) para emojis.

Head — Metadados
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
    content="width=device-width, initial-scale=1.0">
  <meta name="description" content="Resumo da página">
  <title>Título da Aba</title>
  <link rel="stylesheet" href="estilo.css">
</head>

O <head> contém metadados invisíveis. O <title> aparece na aba e no Google. O <link> importa CSS. Metadados não aparecem na página.

Atributos id e class
<div id="topo" class="caixa destaque">
  <p id="intro" class="texto grande">
    Conteúdo
  </p>
</div>

id é único na página (1 elemento). class pode repetir-se e um elemento pode ter várias classes. Use id para âncoras e JS; class para estilos CSS reutilizáveis.

Texto e Formatação


10 cards
Títulos h1 a h6
<h1>Título principal (1 por página)</h1>
<h2>Subtítulo de secção</h2>
<h3>Sub-secção</h3>
<h4>Detalhe</h4>
<h5>Sub-detalhe</h5>
<h6>Menor título</h6>

Seis níveis hierárquicos. Use apenas um <h1> por página. Não salte níveis (ex: h2 → h4). A hierarquia é importante para SEO e acessibilidade.

Sobrescrito e Subscrito
<p>E = mc<sup>2</sup></p>
<p>H<sub>2</sub>O</p>
<p>10<sup>3</sup> = 1000</p>
<p>CO<sub>2</sub> é dióxido de carbono</p>

<sup> eleva o texto (expoentes, notas). <sub> rebaixa (fórmulas químicas). Essenciais para notação matemática e científica.

Direção de Texto e Unicode
<p dir="rtl">Texto da direita para esquerda</p>
<p dir="ltr">Texto normal (esquerda→direita)</p>

<bdo dir="rtl">Texto invertido</bdo>

<!-- Unicode direto: -->
<p>© 2024 — Café ☕ → 🚀</p>

dir="rtl" inverte a direção do texto (árabe, hebraico). <bdo> força a direção. Para caracteres Unicode (emojis, símbolos), basta usar UTF-8 no <meta charset>.

Parágrafo e Quebras
<p>Primeiro parágrafo de texto.</p>

<p>Segundo parágrafo.<br>
Com quebra de linha forçada.</p>

<hr>

<p>Novo tema após linha horizontal.</p>

<p> cria parágrafos com espaçamento automático. <br> força quebra de linha sem novo parágrafo. <hr> insere uma separação temática horizontal.

Código e Pré-formatado
<p>Use <code>console.log()</code> para debug.</p>

<pre><code>
function ola() {
  return "Olá";
}
</code></pre>

<kbd>Ctrl</kbd> + <kbd>C</kbd> = copiar
<samp>Output do programa</samp>

<code> formata código inline. <pre> preserva espaços e quebras. <kbd> representa teclas. <samp> mostra output de programas. Combine <pre><code> para blocos.

WBR e Hyphenation
<p>
  http://site.com/muito/<wbr>longo/<wbr>caminho
</p>

<p lang="de">
  Straßen&shy;bahn&shy;haltestelle
</p>

<p style="hyphens: auto" lang="pt">
  Paralelepípedo é uma palavra longa
</p>

<wbr> sugere um ponto de quebra em URLs longas. &shy; é um hífen suave (só aparece se quebrar). hyphens: auto em CSS separa sílabas automaticamente.

Negrito, Itálico e Ênfase
<strong>Importante (negrito semântico)</strong>
<em>Ênfase (itálico semântico)</em>
<b>Negrito visual (sem semântica)</b>
<i>Itálico visual (termo técnico)</i>

<strong> indica importância (negrito). <em> indica ênfase (itálico). <b> e <i> são apenas visuais. Prefira <strong>/<em> para acessibilidade.

Citações
<blockquote cite="https://exemplo.com">
  <p>Citação longa em bloco.</p>
</blockquote>

<p>Como disse: <q>citação curta inline</q>.</p>

<cite>Título da obra</cite>

<blockquote> para citações longas em bloco. <q> para citações curtas inline (adiciona aspas automáticas). <cite> referencia o título da obra. O atributo cite guarda a URL da fonte.

Texto Modificado
<del>Texto removido</del>
<ins>Texto inserido</ins>
<mark>Texto destacado</mark>
<s>Texto incorreto</s>
<u>Sublinhado (cuidado com links!)</u>
<small>Texto pequeno</small>

<del> mostra texto riscado (removido). <ins> sublinha (inserido). <mark> realça com fundo amarelo. <small> reduz o tamanho. Evite <u> — confunde com links.

Abreviaturas e Definições
<abbr title="HyperText Markup Language">
  HTML
</abbr>

<dfn>HTML</dfn> é a linguagem de marcação
padrão para páginas web.

<address>
  Escrito por <a href="mailto:a@b.com">Ana</a>
</address>

<abbr> mostra o significado em tooltip. <dfn> marca a definição de um termo. <address> contém informação de contacto do autor. Todos melhoram a semântica.

Listas


6 cards
Lista Não Ordenada
<ul>
  <li>HTML</li>
  <li>CSS</li>
  <li>JavaScript</li>
</ul>

<ul> cria lista com marcadores (bullets). Cada item usa <li>. Ideal para itens sem ordem específica. O estilo do marcador muda com list-style-type em CSS.

Listas Aninhadas
<ul>
  <li>Frontend
    <ul>
      <li>HTML</li>
      <li>CSS
        <ul>
          <li>Flexbox</li>
          <li>Grid</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Backend</li>
</ul>

Sublistas vão dentro do <li> pai. Pode misturar <ul> e <ol>. A indentação visual vem do CSS (margin-left por nível).

Lista Ordenada
<ol>
  <li>Abrir o ficheiro</li>
  <li>Editar o conteúdo</li>
  <li>Guardar</li>
</ol>

<ol start="5" reversed>
  <li>Quinto</li>
  <li>Quarto</li>
</ol>

<ol> cria lista numerada. start="5" inicia no 5. reversed inverte a contagem. Use para passos sequenciais ou rankings.

Lista com CSS (Sem Marcadores)
<ul style="list-style: none; padding: 0;">
  <li>→ Item com seta</li>
  <li>✓ Item com check</li>
  <li>★ Item com estrela</li>
</ul>

<!-- Ou com CSS externo: -->
<!-- ul { list-style: none; } -->
<!-- li::before { content: "→ "; } -->

list-style: none remove os marcadores. Use ::before com content para marcadores personalizados. Padrão comum em menus de navegação.

Tipo de Numeração
<ol type="1">  <!-- 1, 2, 3 -->
<ol type="A">  <!-- A, B, C -->
<ol type="a">  <!-- a, b, c -->
<ol type="I">  <!-- I, II, III -->
<ol type="i">  <!-- i, ii, iii -->

<li value="10">Salta para 10</li>

O atributo type define o formato: 1 (números), A/a (letras), I/i (romanos). value num <li> redefine a numeração a partir dali.

Lista de Definição
<dl>
  <dt>HTML</dt>
  <dd>Linguagem de marcação</dd>

  <dt>CSS</dt>
  <dd>Folha de estilos</dd>

  <dt>JavaScript</dt>
  <dd>Linguagem de programação</dd>
</dl>

<dl> cria lista de definições. <dt> é o termo. <dd> é a descrição. Ideal para glossários, FAQs e pares chave-valor.

Links e Navegação


8 cards
Link Básico
<a href="https://exemplo.com">Visitar site</a>

<a href="/sobre">Página interna</a>

<a href="./ficheiro.pdf">Ficheiro local</a>

O <a> cria hiperligações. href define o destino. Use URLs absolutas (https://) para sites externos e relativas (/pagina) para internas.

Download de Ficheiros
<a href="relatorio.pdf" download>
  Baixar PDF
</a>

<a href="dados.csv" download="vendas-2024.csv">
  Baixar com nome personalizado
</a>

O atributo download força o download em vez de abrir o ficheiro. Pode especificar um nome alternativo. Só funciona para URLs do mesmo domínio (same-origin).

Abrir em Nova Aba
<a href="https://externo.com"
   target="_blank"
   rel="noopener noreferrer">
  Abrir em nova aba
</a>

target="_blank" abre em nova aba. Sempre adicione rel="noopener" por segurança (impede acesso ao window.opener). noreferrer também esconde o referer.

Link como Botão
<!-- Link com aparência de botão -->
<a href="/registo" class="btn btn-primary"
   role="button">
  Registar
</a>

<!-- Botão real (sem navegação) -->
<button type="button" class="btn">
  Clique aqui
</button>

Use <a> para navegação e <button> para ações (JS). role="button" indica a leitores de ecrã que o link age como botão. Não use <div onclick> — não é acessível.

Âncoras (Links Internos)
<a href="#contactos">Ir para contactos</a>

<!-- Mais abaixo na página: -->
<section id="contactos">
  <h2>Contactos</h2>
</section>

<!-- Link de outra página: -->
<a href="/pagina.html#seccao">Secção</a>

Links com #id saltam para o elemento com esse id. Funciona na mesma página ou em outra (pagina.html#id). Use scroll-behavior: smooth em CSS para animar.

Rel noopener e nofollow
<a href="https://externo.com"
   rel="noopener">Seguro</a>

<a href="https://spam.com"
   rel="nofollow">Sem endorsement SEO</a>

<a href="https://patrocinado.com"
   rel="sponsored">Patrocinado</a>

<a href="https://exemplo.com"
   rel="noopener nofollow">Ambos</a>

rel="noopener" protege contra ataques. nofollow diz ao Google para não seguir o link (SEO). sponsored marca links pagos. Combine valores separados por espaço.

Email e Telefone
<a href="mailto:ana@exemplo.com">
  Enviar email
</a>

<a href="mailto:a@b.com?subject=Olá&cc=x@y.com">
  Email com assunto
</a>

<a href="tel:+351912345678">
  Ligar agora
</a>

mailto: abre o cliente de email. Aceita ?subject=, &cc=, &body=. tel: abre o marcador no telemóvel. Use formato internacional com +.

Breadcrumb (Trilho)
<nav aria-label="Breadcrumb">
  <ol>
    <li><a href="/">Início</a></li>
    <li><a href="/produtos">Produtos</a></li>
    <li aria-current="page">Detalhe</li>
  </ol>
</nav>

Breadcrumbs mostram a localização na hierarquia. Use <nav> com aria-label. aria-current="page" marca a página atual. Melhora SEO e navegação.

Tabelas


8 cards
Tabela Básica
<table>
  <tr>
    <td>Célula 1</td>
    <td>Célula 2</td>
  </tr>
  <tr>
    <td>Célula 3</td>
    <td>Célula 4</td>
  </tr>
</table>

<table> cria a tabela. <tr> é uma linha. <td> é uma célula de dados. Tabelas são para dados tabulares — não para layout.

Rodapé de Tabela
<table>
  <thead>
    <tr><th>Produto</th><th>Preço</th></tr>
  </thead>
  <tbody>
    <tr><td>Item A</td><td>10€</td></tr>
    <tr><td>Item B</td><td>20€</td></tr>
  </tbody>
  <tfoot>
    <tr><td>Total</td><td>30€</td></tr>
  </tfoot>
</table>

<tfoot> contém linhas de resumo. O browser pode repeti-lo em tabelas longas impressas. A ordem no HTML pode ser theadtfoottbody (renderiza no fim).

Cabeçalho e Corpo
<table>
  <thead>
    <tr>
      <th>Nome</th>
      <th>Idade</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ana</td>
      <td>30</td>
    </tr>
  </tbody>
</table>

<thead> agrupa o cabeçalho. <th> é célula de cabeçalho (negrito e centrada). <tbody> contém os dados. Melhora acessibilidade e permite estilizar secções.

Agrupar Colunas (colgroup)
<table>
  <colgroup>
    <col style="background: #f0f0f0">
    <col span="2" style="background: #e0e0e0">
  </colgroup>
  <tr>
    <td>Col 1</td>
    <td>Col 2</td>
    <td>Col 3</td>
  </tr>
</table>

<colgroup> e <col> estilizam colunas inteiras. span="2" aplica a 2 colunas. Útil para zebra striping por coluna ou destacar colunas específicas.

Legenda (caption)
<table>
  <caption>Vendas por trimestre (2024)</caption>
  <thead>
    <tr>
      <th>Trimestre</th>
      <th>Valor</th>
    </tr>
  </thead>
  <tbody>
    <tr><td>Q1</td><td>10k</td></tr>
  </tbody>
</table>

<caption> dá um título descritivo à tabela. Deve ser o primeiro filho de <table>. Essencial para acessibilidade — leitores de ecrã anunciam o caption.

Tabela Responsiva
<div style="overflow-x: auto;">
  <table>
    <tr>
      <td>Dados largos...</td>
      <td>Que não cabem...</td>
      <td>No ecrã mobile</td>
    </tr>
  </table>
</div>

Envolva a tabela num <div> com overflow-x: auto. Em ecrãs pequenos, aparece scroll horizontal. Alternativa: transformar em cards com CSS Grid em mobile.

Colspan e Rowspan
<table>
  <tr>
    <td colspan="2">Ocupa 2 colunas</td>
  </tr>
  <tr>
    <td rowspan="2">Ocupa 2 linhas</td>
    <td>Normal</td>
  </tr>
  <tr>
    <td>Normal</td>
  </tr>
</table>

colspan="2" faz a célula ocupar 2 colunas. rowspan="2" ocupa 2 linhas. Útil para cabeçalhos agrupados e células de resumo.

Escopo de Cabeçalho
<table>
  <tr>
    <th scope="col">Nome</th>
    <th scope="col">Idade</th>
  </tr>
  <tr>
    <th scope="row">Ana</th>
    <td>30</td>
  </tr>
</table>

scope="col" indica que o <th> é cabeçalho da coluna. scope="row" para a linha. Essencial para leitores de ecrã associarem dados ao cabeçalho correto.

Formulários


10 cards
Formulário Básico
<form action="/enviar" method="POST">
  <label for="nome">Nome:</label>
  <input type="text" id="nome" name="nome">

  <button type="submit">Enviar</button>
</form>

action define o destino dos dados. method é GET (URL) ou POST (body). name é obrigatório para o campo ser enviado. <label> com for liga ao input.

Checkbox e Radio
<label>
  <input type="checkbox" name="aceito"
         value="sim" checked>
  Aceito os termos
</label>

<label>
  <input type="radio" name="cor"
         value="azul">
  Azul
</label>
<label>
  <input type="radio" name="cor"
         value="verde" checked>
  Verde
</label>

checkbox permite múltipla seleção. radio só permite uma escolha (mesmo name). checked pré-marca. Envolva com <label> para clicar no texto também.

Input File e Múltiplo
<form enctype="multipart/form-data">
  <input type="file" name="foto"
         accept="image/*">

  <input type="file" name="docs"
         multiple
         accept=".pdf,.doc,.docx">
</form>

type="file" permite upload. accept filtra tipos de ficheiro. multiple permite vários. O <form> precisa de enctype="multipart/form-data" para uploads.

Tipos de Input
<input type="text">      <!-- texto -->
<input type="email">     <!-- email -->
<input type="password">  <!-- senha -->
<input type="number">    <!-- número -->
<input type="date">      <!-- data -->
<input type="time">      <!-- hora -->
<input type="color">     <!-- cor -->
<input type="range">     <!-- slider -->
<input type="file">      <!-- ficheiro -->
<input type="url">       <!-- URL -->
<input type="tel">       <!-- telefone -->
<input type="search">    <!-- pesquisa -->

O type define o comportamento e o teclado no mobile. email valida formato, number mostra spinner, date abre calendário. Use o tipo correto para melhor UX.

Validação Nativa
<input type="email" required>

<input type="text" minlength="3"
       maxlength="50">

<input type="number" min="1" max="100"
       step="0.5">

<input type="text"
       pattern="[0-9]{9}"
       title="9 dígitos">

required torna obrigatório. minlength/maxlength limitam tamanho. min/max limitam valores. pattern valida com regex. title mostra dica no erro.

Autofocus, Placeholder e Readonly
<input type="text" autofocus
       placeholder="Pesquisar...">

<input type="text" readonly
       value="Não editável">

<input type="text" disabled
       value="Desativado">

<input type="hidden" name="token"
       value="abc123">

autofocus foca ao carregar (1 por página). placeholder mostra dica. readonly impede edição mas envia. disabled impede e não envia. hidden é invisível.

Textarea
<label for="msg">Mensagem:</label>
<textarea id="msg" name="mensagem"
          rows="5" cols="40"
          placeholder="Escreva aqui..."
          maxlength="500"></textarea>

<textarea> permite texto multi-linha. rows define a altura inicial. maxlength limita caracteres. O conteúdo inicial vai entre as tags (não use value).

Fieldset e Legend
<form>
  <fieldset>
    <legend>Dados Pessoais</legend>
    <label>Nome: <input name="nome"></label>
    <label>Email: <input type="email"
           name="email"></label>
  </fieldset>

  <fieldset disabled>
    <legend>Bloqueado</legend>
    <input type="text" value="Não editável">
  </fieldset>
</form>

<fieldset> agrupa campos relacionados. <legend> dá título ao grupo. disabled no fieldset desativa todos os campos dentro. Melhora organização e acessibilidade.

Select e Datalist
<select name="pais">
  <option value="">Escolha...</option>
  <option value="pt" selected>Portugal</option>
  <option value="br">Brasil</option>
  <optgroup label="Europa">
    <option value="es">Espanha</option>
  </optgroup>
</select>

<input list="linguagens">
<datalist id="linguagens">
  <option value="HTML">
  <option value="CSS">
</datalist>

<select> cria dropdown. <optgroup> agrupa opções. selected pré-seleciona. <datalist> dá sugestões num input de texto (autocomplete nativo).

Botões
<button type="submit">Enviar</button>
<button type="button" onclick="salvar()">
  Guardar
</button>
<button type="reset">Limpar</button>
<button disabled>Indisponível</button>

type="submit" envia o formulário. type="button" não envia (use com JS). type="reset" limpa campos. disabled desativa. Prefira <button> a <input type="submit">.

HTML Semântico


10 cards
Header e Footer
<header>
  <h1>Meu Site</h1>
  <nav>...</nav>
</header>

<main>Conteúdo</main>

<footer>
  <p>&copy; 2024 Meu Site</p>
</footer>

<header> é o topo (logo, nav, título). <footer> é o rodapé (copyright, links). Podem existir vários por página (em <article>, <section>). Substituem <div class="header">.

Aside — Conteúdo Lateral
<main>
  <article>Conteúdo principal</article>

  <aside>
    <h3>Relacionado</h3>
    <ul>
      <li><a href="/post1">Post 1</a></li>
      <li><a href="/post2">Post 2</a></li>
    </ul>
  </aside>
</main>

<aside> contém conteúdo complementar (sidebar, dicas, publicidade). Deve estar relacionado com o conteúdo principal. Não use para conteúdo não relacionado.

Dialog (Modal Nativo)
<dialog id="modal">
  <h2>Título do Modal</h2>
  <p>Conteúdo da caixa de diálogo.</p>
  <button onclick="this.closest('dialog')
    .close()">Fechar</button>
</dialog>

<button onclick="document
  .querySelector('#modal')
  .showModal()">Abrir</button>

<dialog> cria modais nativos sem JS. .showModal() abre com overlay. .close() fecha. Suporta ::backdrop em CSS para estilizar o fundo. Sem dependências externas.

Nav — Navegação
<nav aria-label="Principal">
  <ul>
    <li><a href="/">Início</a></li>
    <li><a href="/sobre">Sobre</a></li>
    <li><a href="/contacto">Contacto</a></li>
  </ul>
</nav>

<nav> marca áreas de navegação principal. Use aria-label se houver múltiplos <nav>. Nem todos os links precisam de estar num <nav> — só os principais.

Details e Summary
<details>
  <summary>Clique para expandir</summary>
  <p>Conteúdo oculto que aparece
  ao clicar no summary.</p>
</details>

<details open>
  <summary>Já aberto</summary>
  <p>Visível por defeito.</p>
</details>

<details> cria um acordeão nativo sem JavaScript. <summary> é o título clicável. open mostra expandido por defeito. Ideal para FAQs e conteúdo opcional.

Template e Slot
<template id="card-template">
  <div class="card">
    <h3 class="titulo"></h3>
    <p class="texto"></p>
  </div>
</template>

<script>
const tpl = document
  .querySelector('#card-template');
const clone = tpl.content.cloneNode(true);
clone.querySelector('.titulo')
  .textContent = 'Novo';
document.body.appendChild(clone);
</script>

<template> guarda HTML inerte (não renderiza). Clone com .content.cloneNode(true) em JS. Ideal para listas dinâmicas e Web Components. O conteúdo só existe quando clonado.

Main — Conteúdo Principal
<body>
  <header>...</header>
  <nav>...</nav>

  <main>
    <h1>Título da página</h1>
    <p>Conteúdo único desta página.</p>
  </main>

  <footer>...</footer>
</body>

<main> contém o conteúdo único da página. Só pode existir um por página. Não inclua header, nav ou footer dentro. Ajuda leitores de ecrã a saltar direto ao conteúdo.

Time e Data
<time datetime="2024-01-15">15 de Janeiro</time>

<time datetime="2024-01-15T14:30">
  15 Jan, 14:30
</time>

<time datetime="PT2H30M">2h 30min</time>

<time> marca datas/horas de forma legível por máquinas. O atributo datetime usa formato ISO. Melhora SEO e permite que browsers adicionem ao calendário.

Article e Section
<article>
  <h2>Post: Como usar HTML</h2>
  <time datetime="2024-01-15">15 Jan</time>
  <p>Conteúdo independente...</p>
</article>

<section>
  <h2>Comentários</h2>
  <p>Secção temática da página.</p>
</section>

<article> é conteúdo independente (post, notícia, comentário). <section> agrupa conteúdo temático. Regra: se faz sentido sozinho, use <article>.

Progress e Meter
<progress value="70" max="100">
  70%
</progress>

<meter value="0.7" min="0" max="1"
       low="0.3" high="0.8"
       optimum="1">
  70% completo
</meter>

<progress> mostra progresso de uma tarefa. <meter> mostra um valor dentro de um intervalo (como um gauge). low/high/optimum definem zonas de cor.

Metadados e SEO


9 cards
Title e Description
<head>
  <title>Meu Site - Serviços Web</title>
  <meta name="description"
    content="Criamos sites modernos e
    responsivos. Orçamento grátis.">
</head>

O <title> aparece na aba e nos resultados do Google (máx ~60 chars). A meta description é o resumo nos resultados (máx ~160 chars). Essenciais para SEO.

Favicon e Icons
<link rel="icon" href="/favicon.ico"
      sizes="32x32">
<link rel="icon" href="/icon.svg"
      type="image/svg+xml">
<link rel="apple-touch-icon"
      href="/apple-icon.png">
<link rel="manifest"
      href="/site.webmanifest">

rel="icon" define o favicon da aba. apple-touch-icon para iOS (180x180px). manifest liga ao PWA. Use SVG para favicon escalável.

JSON-LD (Schema.org)
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Minha Empresa",
  "url": "https://site.com",
  "logo": "https://site.com/logo.png"
}
</script>

JSON-LD é dados estruturados para o Google. Vai num <script type="application/ld+json">. Permite rich snippets (estrelas, preços, FAQs) nos resultados de pesquisa.

Open Graph (Redes Sociais)
<meta property="og:title"
      content="Título do Post">
<meta property="og:description"
      content="Resumo atractivo">
<meta property="og:image"
      content="https://site.com/img.jpg">
<meta property="og:url"
      content="https://site.com/post">
<meta property="og:type"
      content="article">

Open Graph controla a pré-visualização ao partilhar no Facebook, LinkedIn, WhatsApp. og:image deve ter 1200x630px. Sem isto, as redes tentam adivinhar o conteúdo.

Ligar CSS e JavaScript
<!-- CSS no head -->
<link rel="stylesheet" href="estilo.css">

<!-- JS com defer (recomendado) -->
<script src="app.js" defer></script>

<!-- JS com async -->
<script src="analytics.js" async></script>

<!-- Módulo ES6 -->
<script type="module"
        src="modulo.js"></script>

CSS vai no <head> com <link>. JS use defer (executa após parse, mantém ordem) ou async (executa ao carregar, sem ordem). type="module" ativa ES modules.

Twitter Card
<meta name="twitter:card"
      content="summary_large_image">
<meta name="twitter:title"
      content="Título do Post">
<meta name="twitter:description"
      content="Resumo do post">
<meta name="twitter:image"
      content="https://site.com/img.jpg">

Twitter Card controla a pré-visualização no X/Twitter. summary_large_image mostra imagem grande. summary mostra pequena. Complementa o Open Graph.

Preload e Prefetch
<!-- Preload: recurso crítico -->
<link rel="preload" href="fonte.woff2"
      as="font" crossorigin>

<!-- Preconnect: DNS antecipado -->
<link rel="preconnect"
      href="https://fonts.googleapis.com">

<!-- Prefetch: próxima página -->
<link rel="prefetch" href="/proxima">

<!-- DNS prefetch -->
<link rel="dns-prefetch"
      href="//cdn.exemplo.com">

preload carrega recursos críticos antecipadamente. preconnect antecipa DNS+TCP. prefetch carrega recursos da próxima página em idle. Melhoram Core Web Vitals.

Canonical e Robots
<link rel="canonical"
      href="https://site.com/pagina">

<meta name="robots"
      content="index, follow">

<meta name="robots"
      content="noindex, nofollow">

canonical indica a URL preferida (evita conteúdo duplicado). robots controla indexação: index/noindex (aparecer no Google), follow/nofollow (seguir links).

Meta Tags Essenciais
<meta charset="UTF-8">
<meta name="viewport"
  content="width=device-width,
  initial-scale=1.0">
<meta name="author" content="Ana">
<meta name="theme-color"
      content="#E34F26">
<meta http-equiv="X-UA-Compatible"
      content="IE=edge">

charset e viewport são obrigatórios. theme-color define a cor da barra no mobile. author identifica o autor. X-UA-Compatible para compatibilidade IE.

Acessibilidade


8 cards
Alt em Imagens
<img src="grafico.png"
     alt="Vendas subiram 20% em 2024">

<!-- Decorativa: alt vazio -->
<img src="linha.png" alt=""
     role="presentation">

alt descreve a imagem para leitores de ecrã. Seja específico e descritivo. Para imagens decorativas, use alt="" (vazio) — o leitor ignora. Nunca omita o atributo.

Labels em Formulários
<!-- Método 1: for/id -->
<label for="email">Email:</label>
<input id="email" type="email">

<!-- Método 2: envolver -->
<label>
  Nome:
  <input type="text" name="nome">
</label>

<!-- Sem label visível -->
<input type="search"
       aria-label="Pesquisar">

Todo input precisa de label. for/id liga explicitamente. Envolver o input no <label> também funciona. Sem label visível, use aria-label. Nunca use só placeholder.

ARIA Labels
<button aria-label="Fechar menu">
  ✕
</button>

<nav aria-label="Navegação principal">
  ...
</nav>

<input aria-label="Pesquisar no site"
       type="search">

aria-label dá um nome acessível a elementos sem texto visível. Use em botões de ícones, inputs sem label visível e navegações. Não use se já existe texto visível adequado.

Skip Links e Landmarks
<a href="#conteudo"
   class="skip-link">
  Saltar para o conteúdo
</a>

<header>...</header>
<nav>...</nav>

<main id="conteudo">
  <h1>Conteúdo principal</h1>
</main>

Skip links permitem saltar a navegação (teclado). Esconda com CSS mas mantenha acessível. <main>, <nav>, <header> são landmarks que leitores usam para navegar.

ARIA States e Properties
<button aria-expanded="false"
        aria-controls="menu">
  Menu
</button>

<div id="menu" hidden>
  ...
</div>

<div aria-live="polite">
  Atualização dinâmica
</div>

<span aria-hidden="true">★</span>

aria-expanded indica estado aberto/fechado. aria-controls liga ao elemento controlado. aria-live anuncia mudanças dinâmicas. aria-hidden esconde decorativos.

Contraste e Foco
<!-- Não remova o outline! -->
<style>
  a:focus-visible {
    outline: 3px solid #E34F26;
    outline-offset: 2px;
  }

  /* Ratio mínimo: 4.5:1 */
  .texto {
    color: #333; /* bom contraste */
  }
</style>

Nunca use outline: none sem alternativa. :focus-visible mostra foco só para teclado. Contraste mínimo: 4.5:1 para texto normal, 3:1 para texto grande. Teste com ferramentas de contraste.

Roles ARIA
<div role="alert">
  Erro: campo obrigatório!
</div>

<div role="tablist">
  <button role="tab"
          aria-selected="true">Tab 1</button>
  <button role="tab">Tab 2</button>
</div>
<div role="tabpanel">Conteúdo</div>

role define o papel do elemento. alert anuncia erros. tablist/tab/tabpanel criam tabs acessíveis. Prefira tags semânticas — use role só quando necessário.

Tabelas Acessíveis
<table>
  <caption>Vendas 2024</caption>
  <thead>
    <tr>
      <th scope="col">Mês</th>
      <th scope="col">Valor</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Janeiro</th>
      <td>10.000€</td>
    </tr>
  </tbody>
</table>

Use <caption> para título. <th> com scope associa cabeçalhos a células. Nunca use tabelas para layout. Leitores de ecrã navegam por <th> e scope.

Dicas e Moderno


8 cards
Carregar JavaScript (defer/async)
<!-- Recomendado: defer -->
<script src="app.js" defer></script>

<!-- Async: sem ordem garantida -->
<script src="analytics.js" async></script>

<!-- Inline no fim do body -->
<body>
  ...
  <script src="app.js"></script>
</body>

defer carrega em paralelo e executa após o parse (mantém ordem). async executa assim que carrega (sem ordem). Sem atributo, bloqueia o parse. Prefira defer para scripts próprios.

Meta Refresh e Redirect
<!-- Redirect após 0s -->
<meta http-equiv="refresh"
      content="0; url=https://novo.com">

<!-- Refresh a cada 30s -->
<meta http-equiv="refresh"
      content="30">

http-equiv="refresh" redireciona ou recarrega a página. content="0; url=..." redireciona imediatamente. Prefira redirects HTTP (301/302) no servidor para SEO.

Contenteditable
<div contenteditable="true">
  Clique para editar este texto!
</div>

<p contenteditable="plaintext-only">
  Só texto simples
</p>

<!-- JS: obter conteúdo -->
<script>
const el = document
  .querySelector('[contenteditable]');
el.addEventListener('input', () => {
  console.log(el.innerHTML);
});
</script>

contenteditable="true" torna qualquer elemento editável. plaintext-only impede formatação. O evento input deteta mudanças. Base de editores rich-text.

Web Components (Básico)
<template id="tpl">
  <style>
    .card { border: 1px solid #ccc; }
  </style>
  <div class="card">
    <slot></slot>
  </div>
</template>

<script>
class MeuCard
  extends HTMLElement {
  connectedCallback() {
    const tpl = document
      .querySelector('#tpl');
    this.attachShadow({ mode: 'open' })
      .append(
        tpl.content.cloneNode(true));
  }
}
customElements
  .define('meu-card', MeuCard);
</script>

<meu-card>Conteúdo</meu-card>

Web Components criam elementos personalizados. customElements.define() regista. Shadow DOM isola estilos. <slot> recebe conteúdo. <template> guarda o HTML.

Output e Resultado
<form oninput="resultado.value =
  parseInt(a.value) + parseInt(b.value)">
  <input type="number" id="a" value="5"> +
  <input type="number" id="b" value="3"> =
  <output name="resultado"
          for="a b">8</output>
</form>

<output> mostra o resultado de um cálculo. for liga aos inputs relacionados. oninput recalcula em tempo real. Semântico para resultados de formulários.

Atributos Globais Úteis
<div hidden>Escondido</div>

<div inert>
  <button>Não clicável</button>
</div>

<p spellcheck="true">Editável</p>

<div translate="no">
  Não traduzir: código
</div>

<input inputmode="numeric"
       pattern="[0-9]*">

hidden oculta (sem CSS). inert desativa interação e foco. spellcheck ativa verificação ortográfica. translate="no" impede tradução. inputmode define teclado mobile.

Details como FAQ
<h2>Perguntas Frequentes</h2>

<details>
  <summary>O que é HTML?</summary>
  <p>Linguagem de marcação para
  estruturar páginas web.</p>
</details>

<details>
  <summary>É uma linguagem de
  programação?</summary>
  <p>Não, é de marcação.</p>
</details>

<details>/<summary> criam FAQs sem JavaScript. Cada pergunta é um <summary>, a resposta fica dentro do <details>. Nativo, acessível e sem dependências.

Validar HTML (W3C)
<!-- Ferramentas de validação: -->
https://validator.w3.org

<!-- VS Code: -->
<!-- Extensão: HTMLHint -->

<!-- Erros comuns: -->
<!-- ✗ <div><p>Texto</div></p> -->
<!-- ✓ <div><p>Texto</p></div> -->

<!-- ✗ <img src="x.jpg"> -->
<!-- ✓ <img src="x.jpg" alt="..."> -->

Valide em validator.w3.org. Erros comuns: tags mal fechadas, <img> sem alt, <div> dentro de <p>, IDs duplicados. HTML válido melhora SEO e acessibilidade.

Imagens e Media


8 cards
Imagem Básica
<img src="foto.jpg"
     alt="Cão a correr no parque"
     width="400"
     height="300">

<img> é self-closing (sem fecho). alt é obrigatório para acessibilidade e SEO. Defina width/height para evitar layout shifts.

Lazy Loading
<img src="foto.jpg" alt="..." loading="lazy">

<img src="hero.jpg" alt="..." loading="eager">

<!-- iframe também suporta: -->
<iframe src="mapa.html"
        loading="lazy"></iframe>

loading="lazy" só carrega a imagem quando está prestes a aparecer no viewport. loading="eager" carrega imediatamente (default). Ideal para imagens abaixo do fold.

Imagem Responsiva (srcset)
<img src="foto-800.jpg"
     srcset="foto-400.jpg 400w,
             foto-800.jpg 800w,
             foto-1200.jpg 1200w"
     sizes="(max-width: 600px) 400px, 800px"
     alt="Paisagem">

srcset oferece múltiplas resoluções. sizes diz ao browser o tamanho de exibição. O browser escolhe a melhor imagem. Reduz dados em ecrãs pequenos.

Figure com Legenda
<figure>
  <img src="grafico.png"
       alt="Vendas 2024">
  <figcaption>
    Fig. 1 — Vendas por trimestre
  </figcaption>
</figure>

<figure> agrupa conteúdo visual com a sua legenda. <figcaption> é a descrição. Pode conter imagens, gráficos, código ou citações.

Picture — Arte Diretiva
<picture>
  <source media="(max-width: 600px)"
          srcset="mobile.jpg">
  <source media="(max-width: 1024px)"
          srcset="tablet.jpg">
  <img src="desktop.jpg" alt="Produto">
</picture>

<picture> serve imagens diferentes conforme o ecrã (art direction). O <source> define condições com media. O <img> é o fallback obrigatório.

SVG Inline
<svg width="100" height="100"
     viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40"
          fill="#E34F26"/>
  <text x="50" y="55"
        text-anchor="middle"
        fill="white">HTML</text>
</svg>

<svg> inline permite gráficos vetoriais escaláveis. viewBox define o sistema de coordenadas. Vantagem: estilável com CSS e animável com JS. Sem perda de qualidade.

Formatos Modernos (WebP/AVIF)
<picture>
  <source srcset="foto.avif" type="image/avif">
  <source srcset="foto.webp" type="image/webp">
  <img src="foto.jpg" alt="Foto">
</picture>

AVIF e WebP são mais leves que JPEG/PNG. Use <picture> com type para fallback. O browser usa o primeiro formato suportado. Reduz 30-50% do tamanho.

Mapa de Imagem
<img src="mapa.png" alt="Mapa"
     usemap="#menu">

<map name="menu">
  <area shape="rect"
        coords="0,0,100,50"
        href="/pagina1" alt="Pág 1">
  <area shape="circle"
        coords="200,75,50"
        href="/pagina2" alt="Pág 2">
</map>

<map> define áreas clicáveis numa imagem. usemap liga a imagem ao mapa. shape pode ser rect, circle ou poly. Pouco usado hoje — prefira SVG.

Multimédia e Embed


7 cards
Vídeo HTML5
<video controls width="640"
       poster="capa.jpg">
  <source src="video.mp4"
          type="video/mp4">
  <source src="video.webm"
          type="video/webm">
  <track src="legendas.vtt"
         kind="subtitles"
         srclang="pt" label="PT">
  O seu browser não suporta vídeo.
</video>

<video> reproduz vídeo nativo. controls mostra botões. poster é a imagem de capa. <source> oferece formatos. <track> adiciona legendas (.vtt).

Embed e Object
<!-- PDF -->
<embed src="doc.pdf"
       type="application/pdf"
       width="100%" height="500">

<!-- Fallback com object -->
<object data="doc.pdf"
        type="application/pdf"
        width="100%" height="500">
  <p>PDF não suportado.
    <a href="doc.pdf">Baixar</a>
  </p>
</object>

<embed> incorpora conteúdo externo (PDF, SVG). <object> permite fallback (conteúdo entre as tags). Prefira <iframe> para páginas e <img> para SVG.

Áudio HTML5
<audio controls>
  <source src="musica.mp3"
          type="audio/mpeg">
  <source src="musica.ogg"
          type="audio/ogg">
  O seu browser não suporta áudio.
</audio>

<!-- Autoplay com mute -->
<audio autoplay muted loop>
  <source src="fundo.mp3">
</audio>

<audio> reproduz áudio nativo. controls mostra player. autoplay só funciona com muted (política dos browsers). loop repete. Texto interno é fallback.

Picture-in-Picture
<video id="video" controls
       src="video.mp4"></video>

<button onclick="togglePiP()">
  Picture-in-Picture
</button>

<script>
async function togglePiP() {
  const v = document
    .querySelector('#video');
  if (document.pictureInPictureElement) {
    await document
      .exitPictureInPicture();
  } else {
    await v.requestPictureInPicture();
  }
}
</script>

requestPictureInPicture() ativa o modo PiP (vídeo flutuante). exitPictureInPicture() desativa. O utilizador pode continuar a ver o vídeo enquanto navega noutra página.

Iframe
<iframe src="https://maps.google.com/..."
        width="600" height="400"
        title="Mapa da localização"
        loading="lazy"
        sandbox="allow-scripts"
        allowfullscreen>
</iframe>

<iframe> embute outra página. title é obrigatório para acessibilidade. loading="lazy" adia o carregamento. sandbox restringe permissões. allowfullscreen permite ecrã inteiro.

Canvas (Básico)
<canvas id="tela"
        width="400" height="200">
  Canvas não suportado.
</canvas>

<script>
const ctx = document
  .querySelector('#tela')
  .getContext('2d');
ctx.fillStyle = '#E34F26';
ctx.fillRect(10, 10, 150, 100);
ctx.font = '20px Arial';
ctx.fillText('HTML5', 50, 70);
</script>

<canvas> cria uma área de desenho via JavaScript. getContext("2d") dá acesso à API de desenho. Use para gráficos, jogos e manipulação de imagens. Requer JS para renderizar.

YouTube e Vimeo Embed
<!-- YouTube -->
<iframe
  src="https://www.youtube.com/embed/ID"
  title="Título do vídeo"
  allow="accelerometer; autoplay;
    clipboard-write; encrypted-media;
    gyroscope; picture-in-picture"
  allowfullscreen
  loading="lazy">
</iframe>

Use a URL /embed/ID do YouTube. allow define permissões. title descreve o vídeo. loading="lazy" melhora performance. Adicione aspect-ratio: 16/9 em CSS para responsivo.