Cheatsheet HTML
Linguagem de marcação para páginas web
HTML
Estrutura Básica
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
< = < > = > & = & " = " = espaço © = © ® = ® → = → ♥ = ♥ 😀 = 😀
Entidades representam caracteres especiais. < e > para < e >. é um espaço que não quebra. Use códigos numéricos (😀) 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
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­bahn­haltestelle </p> <p style="hyphens: auto" lang="pt"> Paralelepípedo é uma palavra longa </p>
<wbr> sugere um ponto de quebra em URLs longas. ­ é 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
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
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
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 thead → tfoot → tbody (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
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
Header e Footer
<header> <h1>Meu Site</h1> <nav>...</nav> </header> <main>Conteúdo</main> <footer> <p>© 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
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
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
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
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
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.