# Code Reference — HTML

_43 pages_

---
# HTML (/docs/html)



# HTML [#html]

Semantic markup, media, a11y.

Browse the sidebar for every cheat sheet in this section.

## Sections [#sections]

* [Examples](./examples)


---

# Accessibility (/docs/html/accessibility)



# Accessibility [#accessibility]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Accessible HTML works with keyboards, screen readers, zoom, and captions. Start with semantic elements, keyboard focus, sufficient contrast, and text alternatives. ARIA supplements — it doesn’t replace — native HTML. Aim for WCAG 2.2 AA as a practical baseline.

## 🔧 Core concepts [#-core-concepts]

* **Perceivable**: `alt`, captions, contrast, don’t rely on color alone.
* **Operable**: keyboard access, focus visible, no keyboard traps, enough time.
* **Understandable**: clear labels, consistent nav, error identification.
* **Robust**: valid markup, appropriate roles/names/states.
* **Name, Role, Value**: every control needs an accessible name.
* **Prefer native**: `button`, `a`, `label`, `dialog`, inputs over custom widgets.

```html
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" required />

<button type="button" aria-expanded="false" aria-controls="menu">Menu</button>
<ul id="menu" hidden>...</ul>
```

## 💡 Examples [#-examples]

```html
<!-- Skip link -->
<a class="skip-link" href="#main">Skip to content</a>

<!-- Form errors -->
<input id="user" aria-invalid="true" aria-describedby="user-err" />
<p id="user-err" role="alert">Username is taken</p>

<!-- Decorative image -->
<img src="/flourish.svg" alt="" />

<!-- Meaningful image -->
<img src="/chart.png" alt="Sales rose 20% from March to June" />

<!-- Dialog -->
<dialog aria-labelledby="d-title">
  <h2 id="d-title">Confirm delete</h2>
  <button type="button">Cancel</button>
</dialog>

<!-- Reduced motion respect is CSS; live regions: -->
<div aria-live="polite" aria-atomic="true" class="status"></div>
```

```html
<!-- Focus order follows DOM — don’t reorder only with CSS -->
```

## ⚠️ Pitfalls [#️-pitfalls]

* `outline: none` without `:focus-visible` styles excludes keyboard users.
* Icon-only controls without names are silent in AT.
* `aria-hidden="true"` on focusable elements creates traps — also disable/hide from focus.
* Fake placeholders as only labels disappear and hurt UX.
* Auto-playing media with sound violates operable guidelines.

## 🔗 Related [#-related]

* [aria.md](/docs/html/aria) — ARIA patterns
* [semantic.md](/docs/html/semantic) — semantics
* [button.md](/docs/html/button) — controls
* [dialog.md](/docs/html/dialog) — modals
* [../Javascript/DOM/focus\_blur.md](/docs/html/../javascript/dom/focus-blur) — focus


---

# ARIA (/docs/html/aria)



# ARIA [#aria]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

ARIA (Accessible Rich Internet Applications) adds roles, states, and properties when native HTML can’t express behavior. First rule: **don’t use ARIA if a native element works**. Bad ARIA is worse than none. Focus on accessible name, role, and value.

## 🔧 Core concepts [#-core-concepts]

| Category | Examples                                                                      |          |
| -------- | ----------------------------------------------------------------------------- | -------- |
| Roles    | `button` `dialog` `listbox` `tab` `switch` (prefer native when possible)      |          |
| Names    | `aria-label` `aria-labelledby` `aria-describedby`                             |          |
| Widgets  | `aria-expanded` `aria-selected` `aria-checked` `aria-pressed` `aria-controls` |          |
| Live     | `aria-live` `aria-atomic` `aria-relevant` \`role="status                      | alert"\` |
| Hidden   | `aria-hidden` (never on focusable content)                                    |          |

* **Naming precedence**: `aria-labelledby` > `aria-label` > content > `title` (roughly).
* **Relationships**: `aria-controls`, `aria-owns`, `aria-activedescendant`.
* **HTML parity**: prefer `<button>`, `<dialog>`, `<input>` over role clones.

```html
<button type="button" aria-expanded="false" aria-controls="panel">
  Filters
</button>
<div id="panel" hidden>...</div>
```

## 💡 Examples [#-examples]

```html
<!-- Labelledby -->
<div role="dialog" aria-modal="true" aria-labelledby="t" aria-describedby="d">
  <h2 id="t">Confirm</h2>
  <p id="d">This cannot be undone.</p>
</div>

<!-- Tabs (simplified) -->
<div role="tablist" aria-label="Sections">
  <button role="tab" aria-selected="true" aria-controls="p1" id="t1">One</button>
  <button role="tab" aria-selected="false" aria-controls="p2" id="t2">Two</button>
</div>
<div role="tabpanel" id="p1" aria-labelledby="t1">...</div>
<div role="tabpanel" id="p2" aria-labelledby="t2" hidden>...</div>

<!-- Live region -->
<div role="status" aria-live="polite" id="save-status"></div>

<!-- Switch (or use checkbox) -->
<button type="button" role="switch" aria-checked="false">Notifications</button>
```

```html
<!-- Anti-pattern -->
<div role="button" onclick="...">Save</div>
<!-- Use <button> -->
```

## ⚠️ Pitfalls [#️-pitfalls]

* Changing role without keyboard behavior (e.g. `role="button"` on div without Enter/Space) fails a11y.
* `aria-hidden="true"` on a parent hides all descendants from AT — dangerous with focusable kids.
* Redundant ARIA (`<button role="button">`) adds noise.
* `aria-label` overrides visible text for AT — keep them in sync.
* Don’t use ARIA to “fix” invalid HTML structure.

## 🔗 Related [#-related]

* [accessibility.md](/docs/html/accessibility) — a11y principles
* [semantic.md](/docs/html/semantic) — native first
* [button.md](/docs/html/button) — native controls
* [dialog.md](/docs/html/dialog) — native dialog
* [../Javascript/DOM/focus\_blur.md](/docs/html/../javascript/dom/focus-blur) — focus patterns


---

# Attributes Basics (/docs/html/attributes-basics)



# Attributes Basics [#attributes-basics]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

**Attributes** add information to elements: where a link goes, which image to load, an id for CSS/JS, accessibility labels, and more. They appear in the opening tag as `name="value"`.

## 🔧 Core concepts [#-core-concepts]

| Attribute     | Common on                         | Purpose                              |
| ------------- | --------------------------------- | ------------------------------------ |
| `id`          | Most                              | Unique identifier in the page        |
| `class`       | Most                              | Styling / scripting hooks (reusable) |
| `href`        | `a`, `link`                       | URL target                           |
| `src` / `alt` | `img`                             | Image URL and accessible description |
| `lang`        | `html`                            | Document language                    |
| `type`        | `script`, `input`                 | Variant / input kind                 |
| Boolean attrs | `disabled`, `checked`, `required` | Presence means true                  |

Prefer double quotes around values. One `id` per document; classes can repeat.

## 💡 Examples [#-examples]

**Links and images:**

```html
<a href="https://example.com" title="Example site">Visit example</a>
<img src="dog.png" alt="A dog in a park" width="400" height="300" />
```

**id and class:**

```html
<p id="intro" class="lead highlight">Welcome</p>
<button class="btn btn-primary" type="button">Save</button>
```

**Form-related attributes:**

```html
<label for="email">Email</label>
<input
  id="email"
  name="email"
  type="email"
  placeholder="you@example.com"
  required
/>
```

**Boolean attributes:**

```html
<input type="checkbox" checked disabled />
<!-- checked and disabled are true because they are present -->
```

## ⚠️ Pitfalls [#️-pitfalls]

* Duplicate `id` values break `getElementById` and fragment links.
* Missing `alt` on meaningful images fails accessibility.
* `class` is not `Class` / `CLASS` in XHTML-like tooling — use lowercase in HTML.
* Putting raw `&` in attribute URLs should be escaped as `&amp;` in HTML text.

## 🔗 Related [#-related]

* [elements\_basics.md](/docs/html/elements-basics)
* [hello\_world.md](/docs/html/hello-world)
* [links.md](/docs/html/links)
* [data\_attributes.md](/docs/html/data-attributes)


---

# Button (/docs/html/button)



# Button [#button]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<button>` element performs actions. Prefer it over clickable `<div>`s. Inside forms, `type` defaults to `submit` — set `type="button"` for non-submit actions. Links navigate; buttons act.

## 🔧 Core concepts [#-core-concepts]

| Attribute                       | Role                                               |
| ------------------------------- | -------------------------------------------------- |
| `type`                          | `submit` (default in forms) \| `button` \| `reset` |
| `name` / `value`                | submitted with form when type=submit               |
| `disabled`                      | non-interactive                                    |
| `autofocus`                     | focus on load (use sparingly)                      |
| `form`                          | associate with a form by id                        |
| `formaction` / `formmethod` / … | override form submit attrs                         |

* Content: phrasing content; can include icons + text.
* Keyboard: Enter/Space activate.
* Don’t nest interactive elements inside buttons.

```html
<button type="button" onclick="doThing()">Do thing</button>
<button type="submit">Save</button>
```

## 💡 Examples [#-examples]

```html
<form method="post" action="/save">
  <button type="submit">Save</button>
  <button type="submit" name="intent" value="draft">Save draft</button>
  <button type="reset">Reset</button>
  <button type="button" id="preview">Preview</button>
</form>

<!-- Icon + accessible name -->
<button type="button" aria-label="Close">
  <svg aria-hidden="true" focusable="false">...</svg>
</button>

<!-- Toggle -->
<button type="button" aria-pressed="false" aria-expanded="false">
  Menu
</button>

<!-- External form attribute -->
<input id="q" name="q" form="search" />
<button type="submit" form="search">Search</button>
<form id="search" action="/search"></form>

<!-- Disabled with explanation -->
<button type="submit" disabled aria-describedby="why">Pay</button>
<p id="why">Complete shipping first.</p>
```

```html
<!-- Anti-pattern -->
<div onclick="...">Click me</div>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting `type="button"` inside forms accidentally submits.
* Disabled buttons are not focusable and may skip errors — explain why.
* Styling `<a>` as a button is fine for navigation; don’t use `<button>` for in-app routes that should be shareable URLs without JS (prefer links).
* `button` with only an icon needs an accessible name (`aria-label` or visually present text).
* `reset` often harms UX — rare in modern apps.

## 🔗 Related [#-related]

* [links.md](/docs/html/links) — links vs buttons
* [form.md](/docs/html/form) — form submission
* [input.md](/docs/html/input) — inputs
* [accessibility.md](/docs/html/accessibility) — names/states
* [aria.md](/docs/html/aria) — aria-pressed/expanded
* [../CSS/button.md](/docs/html/../css/button) — button CSS


---

# Canvas (/docs/html/canvas)



# Canvas [#canvas]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<canvas>` element provides a blank bitmap drawing surface for 2D graphics, animations, charts, and games via the Canvas API (`CanvasRenderingContext2D`) or WebGL (`WebGLRenderingContext` / `WebGL2RenderingContext`). Markup alone draws nothing—JavaScript obtains a context and paints pixels.

Canvas is a **replaced element**: it has intrinsic width/height attributes (default 300×150 CSS pixels) that define the **bitmap resolution**, separate from CSS display size. Prefer canvas for dynamic, pixel-level drawing; prefer SVG for scalable, DOM-accessible vector graphics.

Accessibility: a canvas is opaque to assistive tech by default. Provide fallback content inside the element, expose meaning with `aria-*` / `role`, or mirror critical UI in the DOM.

## 🔧 Core concepts [#-core-concepts]

### Markup and sizing [#markup-and-sizing]

```html
<canvas id="chart" width="640" height="360" role="img" aria-label="Sales chart">
  Chart unavailable. Sales rose 12% this quarter.
</canvas>
```

* `width` / `height` attributes set the **backing store** in CSS pixels (not CSS `width`/`height`).
* Scaling with CSS without matching attributes blurs the bitmap—multiply by `devicePixelRatio` for sharp retina output.
* Fallback text or HTML between tags shows when canvas is unsupported or for AT.

### Getting a context [#getting-a-context]

```js
const canvas = document.getElementById("chart");
const ctx = canvas.getContext("2d"); // or "webgl", "webgl2", "bitmaprenderer"
if (!ctx) {
  // Fallback UI
}
```

Common 2D operations: `fillRect`, `stroke`, `fillText`, `drawImage`, paths (`beginPath`, `arc`, `lineTo`), transforms, and `requestAnimationFrame` loops.

### Hit testing and interaction [#hit-testing-and-interaction]

Canvas has no DOM nodes for shapes. Track geometry yourself (bounding boxes, path `isPointInPath`) or use libraries. Keyboard focus requires `tabindex="0"` and custom key handlers.

### Offscreen and workers [#offscreen-and-workers]

`OffscreenCanvas` and `createImageBitmap` move heavy drawing off the main thread. Transfer a canvas with `transferControlToOffscreen()` when supported.

### When not to use canvas [#when-not-to-use-canvas]

| Need                      | Prefer        |
| ------------------------- | ------------- |
| Semantic text / links     | HTML          |
| Scalable icons / diagrams | SVG           |
| Form controls             | Native inputs |
| SEO-critical content      | Real DOM text |

## 💡 Examples [#-examples]

### Basic 2D drawing [#basic-2d-drawing]

```html
<canvas id="box" width="200" height="100" aria-label="Blue rectangle"></canvas>
<script>
  const ctx = document.getElementById("box").getContext("2d");
  ctx.fillStyle = "#2563eb";
  ctx.fillRect(20, 20, 160, 60);
</script>
```

### High-DPI setup [#high-dpi-setup]

```html
<canvas id="hi" role="img" aria-label="Sharp circle"></canvas>
<script>
  const canvas = document.getElementById("hi");
  const dpr = window.devicePixelRatio || 1;
  const cssW = 300;
  const cssH = 150;
  canvas.width = Math.round(cssW * dpr);
  canvas.height = Math.round(cssH * dpr);
  canvas.style.width = cssW + "px";
  canvas.style.height = cssH + "px";
  const ctx = canvas.getContext("2d");
  ctx.scale(dpr, dpr);
  ctx.beginPath();
  ctx.arc(150, 75, 40, 0, Math.PI * 2);
  ctx.fillStyle = "#0f766e";
  ctx.fill();
</script>
```

### Accessible chart pattern [#accessible-chart-pattern]

```html
<figure>
  <canvas id="sales" width="480" height="240"
    role="img"
    aria-labelledby="sales-caption"
    aria-describedby="sales-desc"></canvas>
  <figcaption id="sales-caption">Q1–Q4 revenue</figcaption>
  <p id="sales-desc" class="visually-hidden">
    Q1 40k, Q2 55k, Q3 48k, Q4 70k. Peak in Q4.
  </p>
  <table class="visually-hidden">
    <caption>Same data as the chart</caption>
    <thead><tr><th>Quarter</th><th>Revenue</th></tr></thead>
    <tbody>
      <tr><td>Q1</td><td>40000</td></tr>
      <tr><td>Q2</td><td>55000</td></tr>
    </tbody>
  </table>
</figure>
```

### Animation loop sketch [#animation-loop-sketch]

```html
<canvas id="anim" width="320" height="180" aria-hidden="true"></canvas>
<script>
  const c = document.getElementById("anim");
  const ctx = c.getContext("2d");
  let x = 0;
  function frame(t) {
    ctx.clearRect(0, 0, c.width, c.height);
    ctx.fillRect(x % 320, 80, 40, 40);
    x += 2;
    requestAnimationFrame(frame);
  }
  requestAnimationFrame(frame);
</script>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **CSS size ≠ bitmap size** — Stretching a 300×150 canvas to full viewport without resetting `width`/`height` causes blurry drawing and wrong mouse coordinates.
* **Forgotten `clearRect`** — Animation trails accumulate unless you clear or redraw the full frame.
* **Security / tainted canvas** — Cross-origin images without CORS taint the canvas; `toDataURL` / `getImageData` then throw.
* **No built-in a11y** — Screen readers ignore drawn text; always provide a text alternative or live DOM summary.
* **Memory** — Large canvases (especially × DPR) are expensive; dispose contexts and avoid unbounded offscreen buffers.
* **`getContext` once** — Calling with a different type after the first successful call returns `null`.

## 🔗 Related [#-related]

* [Media](/docs/html/media) — `<img>`, `<video>`, `<audio>` as drawable sources
* [Script](/docs/html/script) — loading drawing code
* [Style](/docs/html/style) — CSS sizing vs canvas attributes
* [Div](/docs/html/div) — layout wrappers around canvas
* [Section](/docs/html/section) — structuring figure/chart regions
* [URL](/docs/html/url) — blob/object URLs for exports


---

# Data Attributes (/docs/html/data-attributes)



# Data Attributes [#data-attributes]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`data-*` attributes store custom private data on HTML elements. Access them via `getAttribute`/`setAttribute` or the `element.dataset` map (camelCase). Prefer data attributes for hooks and progressive enhancement state — not for CSS-critical styling when a class or ARIA state fits better.

## 🔧 Core concepts [#-core-concepts]

* **HTML**: `data-user-id="42"` → `el.dataset.userId`.
* **Naming**: only lowercase letters, digits, hyphens in the attribute; multi-word becomes camelCase in `dataset`.
* **Values**: always strings — parse numbers/JSON yourself.
* **Presence**: `data-open` without value → `dataset.open === ""` (truthy string).
* **CSS**: attribute selectors `[data-state="on"]` or `.x[data-active]`.
* **Not for**: accessible names/roles — use ARIA/semantics.

```html
<button type="button" data-action="add" data-product-id="123">Add</button>
<script>
  btn.addEventListener("click", () => {
    cart.add(Number(btn.dataset.productId));
  });
</script>
```

## 💡 Examples [#-examples]

```html
<div
  id="chart"
  data-endpoint="/api/stats"
  data-refresh-ms="30000"
  data-theme="dark"
></div>

<script>
  const el = document.getElementById("chart");
  const url = el.dataset.endpoint;
  const ms = Number(el.dataset.refreshMs);
  el.dataset.theme = "light"; // sets data-theme="light"
  delete el.dataset.theme; // removes attribute
</script>

<!-- CSS hooks -->
<style>
  .tab[data-active] {
    font-weight: 700;
  }
  .toast[data-variant="danger"] {
    border-color: crimson;
  }
</style>

<!-- JSON in data (keep small) -->
<div data-config='{"lang":"en","n":3}'></div>
<script>
  const cfg = JSON.parse(el.dataset.config);
</script>
```

```html
<!-- Validation: data-userId is invalid — use data-user-id -->
```

## ⚠️ Pitfalls [#️-pitfalls]

* `dataset` values are strings — `"false"` is truthy; compare explicitly or use presence toggles carefully.
* Large JSON in attributes bloats HTML and XSS surface — prefer `<script type="application/json">` or fetch.
* Don’t put secrets in `data-*` — visible in DOM.
* Mixing `data-id` with real `id` confuses mental models — name clearly.
* CSS-only state often better as classes; a11y state better as ARIA.

## 🔗 Related [#-related]

* [aria.md](/docs/html/aria) — accessibility state
* [../Javascript/DOM/attributes.md](/docs/html/../javascript/dom/attributes) — attribute APIs
* [button.md](/docs/html/button) — action hooks
* [semantic.md](/docs/html/semantic) — prefer semantics first
* [../CSS/selectors.md](/docs/html/../css/selectors) — attribute selectors


---

# Details & Summary (/docs/html/details-summary)



# Details & Summary [#details--summary]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`<details>` creates a disclosure widget; `<summary>` is the visible toggle label. Native, keyboard-accessible expand/collapse without JS. Use for FAQs, optional advanced settings, and progressive disclosure. The `open` attribute controls expanded state.

## 🔧 Core concepts [#-core-concepts]

* **Structure**: `<details>` wraps `<summary>` plus any content.
* **`open`**: present when expanded; toggle via UI or JS property `details.open`.
* **Events**: `toggle` fires after open state changes.
* **Name grouping**: `name` attribute on multiple details makes an exclusive accordion (modern browsers).
* **Styling**: limited marker styling via `::marker` / `summary::-webkit-details-marker`.
* Only one summary per details.

```html
<details>
  <summary>Shipping times</summary>
  <p>Orders ship in 2–3 business days.</p>
</details>
```

## 💡 Examples [#-examples]

```html
<!-- FAQ -->
<details>
  <summary>What is your refund policy?</summary>
  <p>Full refunds within 30 days.</p>
</details>

<!-- Open by default -->
<details open>
  <summary>Release notes</summary>
  <ul>
    <li>Bug fixes</li>
  </ul>
</details>

<!-- Accordion via name -->
<details name="faq">
  <summary>A</summary>
  <p>...</p>
</details>
<details name="faq">
  <summary>B</summary>
  <p>...</p>
</details>

<!-- Styled -->
<style>
  details {
    border: 1px solid #ddd;
    padding: 0.5rem 0.75rem;
  }
  summary {
    cursor: pointer;
    font-weight: 600;
  }
  details[open] summary {
    margin-bottom: 0.5rem;
  }
</style>

<script>
  document.querySelector("details").addEventListener("toggle", (e) => {
    console.log(e.target.open);
  });
</script>
```

```html
<!-- summary can contain heading -->
<details>
  <summary><h3>Advanced</h3></summary>
  ...
</details>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Don’t put interactive content that fights the summary click target poorly — keep summary clear.
* Search engines / AT support is good but content in closed details may be less discoverable visually — don’t hide critical legal text only there without care.
* Exclusive `name` accordion support is newer — test targets.
* Animating open height still needs CSS tricks; `open` is discrete.
* Missing `summary` yields UA default “Details” label — always provide one.

## 🔗 Related [#-related]

* [semantic.md](/docs/html/semantic) — structure
* [accessibility.md](/docs/html/accessibility) — disclosures
* [dialog.md](/docs/html/dialog) — modals vs disclosures
* [button.md](/docs/html/button) — custom toggles
* [../CSS/pseudo\_elements.md](/docs/html/../css/pseudo-elements) — markers


---

# Dialog (/docs/html/dialog)



# Dialog [#dialog]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<dialog>` element provides native modal and non-modal dialogs with built-in focus management, backdrop, and Esc handling (for modal). Prefer it over custom `div` modals. Use `showModal()` for modals and `show()` for non-modals; `close()` or form `method="dialog"` to dismiss.

## 🔧 Core concepts [#-core-concepts]

* **API**: `show()`, `showModal()`, `close(returnValue?)`, `open` property, `returnValue`.
* **Events**: `close`, `cancel` (Esc).
* **Backdrop**: `::backdrop` pseudo-element when modal.
* **Forms**: `<form method="dialog">` closes and sets `returnValue` from submitter.
* **Light dismiss**: click backdrop doesn’t close by default — listen if desired.
* **Top layer**: modal dialogs render in the top layer above `z-index` wars.

```html
<dialog id="confirm">
  <form method="dialog">
    <p>Delete item?</p>
    <button value="cancel">Cancel</button>
    <button value="ok">Delete</button>
  </form>
</dialog>
<script>
  const d = document.getElementById("confirm");
  openBtn.onclick = () => d.showModal();
  d.addEventListener("close", () => console.log(d.returnValue));
</script>
```

## 💡 Examples [#-examples]

```html
<dialog id="dlg" aria-labelledby="dlg-title">
  <header>
    <h2 id="dlg-title">Settings</h2>
    <button type="button" class="close" aria-label="Close">&times;</button>
  </header>
  <form id="settings">...</form>
  <menu>
    <button type="button" class="close">Close</button>
    <button type="submit" form="settings">Save</button>
  </menu>
</dialog>

<style>
  dialog::backdrop {
    background: rgb(0 0 0 / 0.45);
  }
  dialog[open] {
    border: 0;
    border-radius: 12px;
    padding: 1.25rem;
  }
</style>

<script>
  const dlg = document.getElementById("dlg");
  dlg.querySelectorAll(".close").forEach((b) =>
    b.addEventListener("click", () => dlg.close()),
  );
  // Optional: light dismiss
  dlg.addEventListener("click", (e) => {
    const rect = dlg.getBoundingClientRect();
    const inDialog =
      rect.top <= e.clientY &&
      e.clientY <= rect.top + rect.height &&
      rect.left <= e.clientX &&
      e.clientX <= rect.left + rect.width;
    if (!inDialog) dlg.close();
  });
</script>
```

## ⚠️ Pitfalls [#️-pitfalls]

* `open` attribute shows non-modal; prefer `showModal()` for true modals.
* Don’t forget an initial focusable control and a clear close action.
* Nested dialogs are tricky — avoid when possible.
* Polyfills still needed for very old browsers — know your baseline.
* Removing `open` via JS isn’t the same as `close()` for return values/events.

## 🔗 Related [#-related]

* [accessibility.md](/docs/html/accessibility) — modal a11y
* [button.md](/docs/html/button) — triggers
* [form.md](/docs/html/form) — method=dialog
* [../Javascript/DOM/focus\_blur.md](/docs/html/../javascript/dom/focus-blur) — focus restore
* [../CSS/pseudo\_elements.md](/docs/html/../css/pseudo-elements) — ::backdrop


---

# Div (/docs/html/div)



# Div [#div]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<div>` element is a generic **flow content** container with no semantic meaning. It groups elements for styling, scripting, or layout when no more specific HTML element fits. Overusing `<div>` (div soup) harms accessibility and maintainability—prefer landmarks and sectioning elements first.

Use `<div>` when you need a box without implying article, navigation, complementary, or other roles. Pair with classes, IDs, and ARIA only when semantics cannot be expressed natively.

## 🔧 Core concepts [#-core-concepts]

### Default behavior [#default-behavior]

* Display: `block` (full width of containing block).
* No default margins (unlike headings/paragraphs).
* Valid almost anywhere flow content is allowed; may contain flow content.
* Does **not** create a landmark or outline entry by itself.

### Prefer semantic alternatives [#prefer-semantic-alternatives]

| Instead of…                 | Prefer…     |
| --------------------------- | ----------- |
| Page header block           | `<header>`  |
| Main content wrapper        | `<main>`    |
| Sidebar                     | `<aside>`   |
| Site/footer chrome          | `<footer>`  |
| Primary nav                 | `<nav>`     |
| Standalone story            | `<article>` |
| Thematic group with heading | `<section>` |
| Inline grouping             | `<span>`    |

### Legitimate uses [#legitimate-uses]

* CSS Grid / Flexbox layout shells
* Script hooks (`id`, `data-*`) without implying meaning
* Presentational wrappers required by a design system
* Grouping for `display: contents` or sticky positioning contexts

### ARIA on divs [#aria-on-divs]

If a `<div>` must act as a widget, add the correct `role`, keyboard support, and labels (`aria-label` / `aria-labelledby`). Prefer native elements (`button`, `a`, `input`) over `role="button"` on a div.

```html
<!-- Avoid when a button works -->
<div role="button" tabindex="0">Save</div>

<!-- Prefer -->
<button type="button">Save</button>
```

## 💡 Examples [#-examples]

### Layout shell (after semantics) [#layout-shell-after-semantics]

```html
<body>
  <header>…</header>
  <div class="layout">
    <main id="content">…</main>
    <aside>…</aside>
  </div>
  <footer>…</footer>
</body>
```

### Flex / grid wrapper [#flex--grid-wrapper]

```html
<div class="card-grid">
  <article class="card">…</article>
  <article class="card">…</article>
  <article class="card">…</article>
</div>
```

```css
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 1rem;
}
```

### Script target without fake semantics [#script-target-without-fake-semantics]

```html
<div id="toast-root" aria-live="polite" aria-atomic="true"></div>
```

### Dialog pattern (prefer `<dialog>` when possible) [#dialog-pattern-prefer-dialog-when-possible]

```html
<div
  role="dialog"
  aria-modal="true"
  aria-labelledby="dlg-title"
  hidden>
  <h2 id="dlg-title">Confirm delete</h2>
  <p>This cannot be undone.</p>
  <button type="button">Cancel</button>
  <button type="button">Delete</button>
</div>
```

Native `<dialog>` with `.showModal()` is usually better for focus trapping and `Escape`.

## ⚠️ Pitfalls [#️-pitfalls]

* **Div soup** — Nested anonymous divs make outlines and CSS brittle; name regions with real tags.
* **Clickable divs** — Missing `tabindex`, Enter/Space handlers, and roles break keyboard and AT users.
* **`div` for text** — Use `<p>`, lists, or headings for prose; divs do not convey paragraph structure.
* **Landmark overload** — Do not put `role="main"` on every wrapper; one `<main>` per page.
* **`display: contents`** — Can remove the box from a11y trees in some browsers; test carefully.
* **Styling only** — If the only reason is “I need a class,” check whether a semantic parent already exists.

## 🔗 Related [#-related]

* [Section](/docs/html/section) — thematic grouping with headings
* [Nav](/docs/html/nav) — navigation landmark
* [Footer](/docs/html/footer) — footer / contentinfo
* [Form](/docs/html/form) — form layout containers
* [Style](/docs/html/style) — styling hooks
* [Canvas](/docs/html/canvas) — wrapping drawing surfaces
* [Language](/docs/html/language) — `lang` on containers


---

# Elements Basics (/docs/html/elements-basics)



# Elements Basics [#elements-basics]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

An **element** is a node in the page tree, usually written with an opening tag, content, and a closing tag. Some elements are **void** (no closing tag), like `img` and `br`.

## 🔧 Core concepts [#-core-concepts]

| Kind       | Examples                           | Notes                                          |
| ---------- | ---------------------------------- | ---------------------------------------------- |
| Block-ish  | `h1`–`h6`, `p`, `ul`, `section`    | Start on a new line by default (CSS dependent) |
| Inline-ish | `a`, `strong`, `em`, `span`        | Flow within text                               |
| Void       | `img`, `br`, `hr`, `input`, `meta` | No child content                               |
| Semantic   | `header`, `main`, `nav`, `footer`  | Meaning for humans & assistive tech            |

Elements nest to form a tree; the browser builds the DOM from that tree.

## 💡 Examples [#-examples]

**Headings and text:**

```html
<h1>Site title</h1>
<h2>Section</h2>
<p>A paragraph of text with <strong>bold</strong> and <em>emphasis</em>.</p>
```

**Lists:**

```html
<ul>
  <li>Apples</li>
  <li>Bananas</li>
</ul>
<ol>
  <li>Install editor</li>
  <li>Write HTML</li>
</ol>
```

**Void elements:**

```html
<p>Line one<br />Line two</p>
<hr />
<img src="cat.jpg" alt="A cat sitting on a laptop" />
```

**Document landmarks:**

```html
<body>
  <header><h1>Notes</h1></header>
  <main>
    <article>
      <h2>Elements</h2>
      <p>Content goes here.</p>
    </article>
  </main>
  <footer><p>© 2026</p></footer>
</body>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Overusing `<div>` when a semantic tag fits better.
* Putting block elements inside `<p>` incorrectly.
* Self-closing `/>` is optional in HTML5 for void tags but fine to use.
* Tag names are case-insensitive; lowercase is the convention.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/html/getting-started)
* [hello\_world.md](/docs/html/hello-world)
* [attributes\_basics.md](/docs/html/attributes-basics)
* [semantic.md](/docs/html/semantic)


---

# Embedding (/docs/html/embedding)



# Embedding [#embedding]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

HTML offers several ways to embed external or nested content: `<iframe>`, `<embed>`, `<object>`, and media elements. Prefer modern, specific elements (`iframe` for documents, `video`/`audio`/`img` for media). Treat embeds as a security and performance boundary — sandbox and size them deliberately.

## 🔧 Core concepts [#-core-concepts]

| Element           | Typical use                                          |
| ----------------- | ---------------------------------------------------- |
| `iframe`          | HTML documents, apps, maps, PDFs (browser-dependent) |
| `embed`           | Plugin-like resources (PDF/legacy); limited API      |
| `object`          | Fallback-capable embed with nested content           |
| `img` / `picture` | images                                               |
| `video` / `audio` | media                                                |
| `fencedframe`     | privacy-bounded ads (emerging)                       |

* **Fallback**: nested content inside `<object>` shows if embedding fails.
* **Security**: `sandbox`, CSP `frame-src`, Permissions Policy `allow`.
* **A11y**: provide `title` / text fallback links.

```html
<iframe title="Terms PDF" src="/terms.pdf" width="100%" height="600"></iframe>

<object data="/diagram.svg" type="image/svg+xml" role="img" aria-label="Architecture diagram">
  <p><a href="/diagram.svg">Download diagram</a></p>
</object>
```

## 💡 Examples [#-examples]

```html
<!-- object with fallback -->
<object data="/poster.pdf" type="application/pdf" width="800" height="600">
  <p>PDF unavailable. <a href="/poster.pdf">Download</a>.</p>
</object>

<!-- embed (simple) -->
<embed src="/clip.swf" />
<!-- prefer video nowadays -->

<!-- Responsive iframe -->
<div style="aspect-ratio: 16 / 9">
  <iframe
    title="Demo"
    src="/embed/demo"
    style="width: 100%; height: 100%; border: 0"
    loading="lazy"
    sandbox="allow-scripts allow-same-origin"
  ></iframe>
</div>

<!-- Inline SVG often better than object for icons -->
```

```html
<!-- Prefer -->
<video src="/a.mp4" controls></video>
<!-- Over generic embed for video -->
```

## ⚠️ Pitfalls [#️-pitfalls]

* `embed`/`object` for video/audio are outdated — use dedicated media elements.
* Combining `sandbox` tokens `allow-scripts` + `allow-same-origin` can allow sandbox escape.
* PDFs in iframes vary by browser/OS — always offer a download link.
* Each embed costs memory/threads — lazy-load offscreen content.
* Accessibility: unlabeled frames fail audits — set `title`.

## 🔗 Related [#-related]

* [iframe.md](/docs/html/iframe) — iframe deep dive
* [video\_audio.md](/docs/html/video-audio) — media elements
* [images.md](/docs/html/images) — images
* [svg\_inline.md](/docs/html/svg-inline) — inline SVG
* [accessibility.md](/docs/html/accessibility) — titles/fallbacks


---

# Examples (/docs/html/examples)



# Examples [#examples]

HTML notes in **Examples**.


---

# Accessible Form (/docs/html/examples/accessible-form)



# Accessible Form [#accessible-form]

*Html · Example / how-to*

***

## 📋 Overview [#-overview]

Build a contact form with proper labels, error association, required fields, and keyboard-friendly controls.

## 🔧 Core concepts [#-core-concepts]

| Piece              | Role                |
| ------------------ | ------------------- |
| `<label for>`      | Name the control    |
| `aria-describedby` | Link help / errors  |
| `aria-invalid`     | Mark failed fields  |
| Native types       | `email`, `required` |

## 💡 Examples [#-examples]

```html
<form action="/contact" method="post" novalidate>
  <fieldset>
    <legend>Contact us</legend>

    <div>
      <label for="email">Email</label>
      <input
        id="email"
        name="email"
        type="email"
        autocomplete="email"
        required
        aria-describedby="email-hint email-error"
        aria-invalid="true"
      />
      <p id="email-hint">We never share your email.</p>
      <p id="email-error" role="alert">Enter a valid email address.</p>
    </div>

    <div>
      <label for="message">Message</label>
      <textarea
        id="message"
        name="message"
        rows="5"
        required
        aria-describedby="message-hint"
      ></textarea>
      <p id="message-hint">Max 1000 characters.</p>
    </div>

    <div>
      <input id="consent" name="consent" type="checkbox" required />
      <label for="consent">I agree to the privacy policy</label>
    </div>
  </fieldset>

  <button type="submit">Send</button>
</form>
```

**Clear error state when valid (JS sketch):**

```javascript
input.setAttribute("aria-invalid", "false");
error.textContent = "";
```

## ⚠️ Pitfalls [#️-pitfalls]

* Placeholder is not a label — screen readers and recall suffer.
* Only using color for errors fails contrast / color-blind users.
* `novalidate` disables native checks — pair with your own accessible errors.

## 🔗 Related [#-related]

* [Semantic article](/docs/html/examples/semantic-article)


---

# Semantic Article (/docs/html/examples/semantic-article)



# Semantic Article [#semantic-article]

*Html · Example / how-to*

***

## 📋 Overview [#-overview]

Mark up a blog-style article with landmark regions, heading hierarchy, and meaningful time/author metadata.

## 🔧 Core concepts [#-core-concepts]

| Piece                  | Role                      |
| ---------------------- | ------------------------- |
| `<main>` / `<article>` | Primary content landmarks |
| Heading levels         | Outline without skipping  |
| `<time datetime>`      | Machine-readable dates    |
| `<nav>` / `<aside>`    | Related, not main story   |

## 💡 Examples [#-examples]

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Shipping notes for June</title>
  </head>
  <body>
    <header>
      <p><a href="/">Home</a></p>
    </header>

    <main>
      <article>
        <header>
          <h1>Shipping notes for June</h1>
          <p>
            By <span rel="author">Ada Lovelace</span> ·
            <time datetime="2026-06-10">June 10, 2026</time>
          </p>
        </header>

        <p>We tightened release checklists and cut rollback time.</p>

        <h2>What changed</h2>
        <ul>
          <li>Faster preview deploys</li>
          <li>Clearer error budgets</li>
        </ul>

        <h2>Next steps</h2>
        <p>Adopt the checklist on every service.</p>

        <footer>
          <p>Tags: <a href="/tags/ops">ops</a>, <a href="/tags/release">release</a></p>
        </footer>
      </article>

      <aside>
        <h2>Related</h2>
        <nav aria-label="Related articles">
          <ul>
            <li><a href="/posts/may">May notes</a></li>
          </ul>
        </nav>
      </aside>
    </main>
  </body>
</html>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Multiple `<h1>` per page is usually confusing — one primary title is clearer.
* Div soup loses landmarks for screen-reader users.
* Decorative images need `alt=""`; informative images need real alt text.

## 🔗 Related [#-related]

* [Accessible form](/docs/html/examples/accessible-form)


---

# Footer (/docs/html/footer)



# Footer [#footer]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<footer>` element represents a footer for its nearest ancestor **sectioning content** or **sectioning root** (`article`, `aside`, `nav`, `section`, `blockquote`, `body`, `fieldset`, `figure`, `td`). Typical content: authorship, copyright, related links, or document metadata.

A footer is **not** limited to the bottom of the page. Nested footers belong to nested sections (e.g. an article’s byline). When `<footer>` is a direct descendant of `<body>`, browsers expose it as a `contentinfo` landmark—use **one** page-level footer for site-wide info.

## 🔧 Core concepts [#-core-concepts]

### Sectioning relationship [#sectioning-relationship]

```html
<body>
  <main>
    <article>
      <h1>Title</h1>
      <p>…</p>
      <footer>Posted by Ada · 2026-07-10</footer>
    </article>
  </main>
  <footer>
    <p>© 2026 Example Co.</p>
    <nav aria-label="Legal">…</nav>
  </footer>
</body>
```

* Article footer → scoped to that article (not `contentinfo`).
* Body footer → site `contentinfo` landmark.

### Allowed content [#allowed-content]

Flow content, but **no** nested `<footer>` or `<header>` descendants that would confuse sectioning. Contact info often uses `<address>` inside the footer for the document or article contact.

### Accessibility [#accessibility]

* Page footer: landmark `contentinfo` (implicit).
* Do not duplicate with `role="contentinfo"` on another element.
* Label multiple navs inside the footer (`aria-label="Legal"`, `aria-label="Social"`).
* Keep landmark count low—avoid wrapping every widget in its own footer.

### Common patterns [#common-patterns]

| Pattern        | Contents                     |
| -------------- | ---------------------------- |
| Site chrome    | Logo, legal, sitemap, social |
| Article        | Author, dates, tags, share   |
| Card / section | Secondary actions, meta      |

## 💡 Examples [#-examples]

### Site-wide footer [#site-wide-footer]

```html
<footer>
  <p>
    <small>© <time datetime="2026">2026</time> Acme Inc.</small>
  </p>
  <nav aria-label="Legal">
    <ul>
      <li><a href="/privacy">Privacy</a></li>
      <li><a href="/terms">Terms</a></li>
    </ul>
  </nav>
  <address>
    Contact: <a href="mailto:hello@acme.example">hello@acme.example</a>
  </address>
</footer>
```

### Article footer [#article-footer]

```html
<article>
  <header>
    <h2>Semantic footers</h2>
    <p><time datetime="2026-07-10">July 10, 2026</time></p>
  </header>
  <p>Body copy…</p>
  <footer>
    <p>By <a rel="author" href="/authors/ada">Ada</a></p>
    <ul>
      <li><a href="/tags/html">HTML</a></li>
      <li><a href="/tags/a11y">a11y</a></li>
    </ul>
  </footer>
</article>
```

### Footer with secondary navigation [#footer-with-secondary-navigation]

```html
<footer class="site-footer">
  <nav aria-label="Footer">
    <a href="/docs">Docs</a>
    <a href="/status">Status</a>
    <a href="/support">Support</a>
  </nav>
  <p lang="en">Built with semantic HTML.</p>
</footer>
```

### Figure / media credit [#figure--media-credit]

```html
<figure>
  <img src="/photo.jpg" alt="Harbor at dawn">
  <figcaption>Morning light over the harbor.</figcaption>
  <footer><small>Photo © Jordan Lee</small></footer>
</figure>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Multiple `contentinfo` landmarks** — Extra body-level footers or redundant `role="contentinfo"` confuse navigation shortcuts.
* **Footer as layout only** — Do not use `<footer>` merely to stick content to the bottom; use CSS on a non-landmark wrapper if it is not footer content.
* **Nested header/footer rules** — Avoid putting `<header>` inside `<footer>` and vice versa in ways that break the outline.
* **Missing labels on inner nav** — Several unlabeled `<nav>` elements in a footer are hard to distinguish.
* **Copyright-only div** — A bare `<div class="footer">` loses the landmark; use the real element when appropriate.
* **Forms in footers** — Newsletter forms are fine; ensure labels, `autocomplete`, and error messaging still meet a11y standards.

## 🔗 Related [#-related]

* [Nav](/docs/html/nav) — footer link groups
* [Section](/docs/html/section) — sectioning ancestors
* [Div](/docs/html/div) — non-semantic layout
* [Form](/docs/html/form) — newsletter signup patterns
* [Meta](/docs/html/meta) — document-level metadata (not a substitute for visible footer)
* [Language](/docs/html/language) — `lang` on footer snippets


---

# Forms (/docs/html/form)



# Forms [#forms]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<form>` element represents a document section that collects user input and submits it to a server or handles it with script. Native forms give you validation, keyboard behavior, autofill, and accessibility for free—prefer them over custom div-based “forms.”

A form owns **associated controls**: descendants plus elements linked via the `form="id"` attribute. Submission builds a payload from **successful controls** (named, enabled, and meeting type rules).

## 🔧 Core concepts [#-core-concepts]

### Essential attributes [#essential-attributes]

| Attribute      | Role                                                                                       |
| -------------- | ------------------------------------------------------------------------------------------ |
| `action`       | URL that receives the submission (defaults to current URL)                                 |
| `method`       | `get` (query string) or `post` (body); `dialog` closes a `<dialog>`                        |
| `enctype`      | `application/x-www-form-urlencoded` (default), `multipart/form-data` (files), `text/plain` |
| `novalidate`   | Skip built-in constraint validation on submit                                              |
| `autocomplete` | `on` / `off` for the form; controls can override                                           |
| `name`         | Identifies the form in `document.forms`                                                    |
| `target`       | Browsing context for response (`_blank`, iframe name, …)                                   |
| `rel`          | Link types for the submission request                                                      |

### Association and structure [#association-and-structure]

```html
<form id="signup" action="/api/signup" method="post" autocomplete="on">
  <fieldset>
    <legend>Account</legend>
    <label for="email">Email</label>
    <input id="email" name="email" type="email" required autocomplete="email">
  </fieldset>
  <button type="submit">Create account</button>
</form>
```

* Every control needs an accessible **name** (`<label for>`, wrapping label, or `aria-label`).
* Use `<fieldset>` / `<legend>` for related groups (radios, address blocks).
* `button` without `type` inside a form defaults to `submit`—set `type="button"` for non-submit actions.

### Constraint validation [#constraint-validation]

Built-in checks: `required`, `min`/`max`, `minlength`/`maxlength`, `pattern`, `type` (email, url, …), `step`. APIs: `checkValidity()`, `reportValidity()`, `setCustomValidity()`.

Listen to `invalid` and `submit`; call `event.preventDefault()` when handling with `fetch`.

### GET vs POST [#get-vs-post]

* **GET** — bookmarkable, idempotent filters/search; do not send secrets.
* **POST** — mutations, passwords, large bodies, file uploads (`multipart/form-data`).

## 💡 Examples [#-examples]

### Accessible login form [#accessible-login-form]

```html
<form action="/login" method="post">
  <div>
    <label for="user">Username</label>
    <input id="user" name="username" required
      autocomplete="username" autocapitalize="none">
  </div>
  <div>
    <label for="pass">Password</label>
    <input id="pass" name="password" type="password" required
      autocomplete="current-password">
  </div>
  <button type="submit">Sign in</button>
</form>
```

### File upload [#file-upload]

```html
<form action="/upload" method="post" enctype="multipart/form-data">
  <label for="avatar">Profile photo</label>
  <input id="avatar" name="avatar" type="file" accept="image/*">
  <button type="submit">Upload</button>
</form>
```

### External control with `form` attribute [#external-control-with-form-attribute]

```html
<form id="filters" method="get" action="/search"></form>

<label for="q">Query</label>
<input form="filters" id="q" name="q" type="search">

<button form="filters" type="submit">Search</button>
```

### Client-side submit with validation [#client-side-submit-with-validation]

```html
<form id="contact" action="/contact" method="post" novalidate>
  <label for="msg">Message</label>
  <textarea id="msg" name="message" required minlength="10"></textarea>
  <button type="submit">Send</button>
</form>
<script>
  document.getElementById("contact").addEventListener("submit", async (e) => {
    e.preventDefault();
    const form = e.target;
    if (!form.reportValidity()) return;
    const body = new FormData(form);
    await fetch(form.action, { method: "POST", body });
  });
</script>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Missing labels** — Placeholder is not a label; AT and click-to-focus suffer.
* **Unnamed controls** — Without `name`, values are omitted from submission.
* **Disabling validation silently** — `novalidate` without custom checks ships bad data.
* **CSRF** — Browser POSTs need server tokens/SameSite cookies; HTML alone is not enough.
* **Nested forms** — Invalid HTML; browsers repair unpredictably.
* **`div` buttons** — Lose default submit-on-Enter behavior in text fields.
* **Autofill ignored** — Wrong `autocomplete` tokens break password managers.

## 🔗 Related [#-related]

* [Input](/docs/html/input) — control types and attributes
* [Label / lists](/docs/html/list) — structuring options (see also fieldset patterns here)
* [Script](/docs/html/script) — progressive enhancement of submit handlers
* [URL](/docs/html/url) — `action` URLs and query strings
* [Meta](/docs/html/meta) — CSRF tokens sometimes injected via meta + JS
* [Nav](/docs/html/nav) — do not confuse search forms with navigation landmarks
* [Footer](/docs/html/footer) — newsletter forms in footers


---

# Getting Started with HTML (/docs/html/getting-started)



# Getting Started with HTML [#getting-started-with-html]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

HTML (HyperText Markup Language) describes the **structure** of a web page: headings, paragraphs, links, images, forms. Browsers parse HTML into the DOM. CSS styles it; JavaScript makes it interactive.

## 🔧 Core concepts [#-core-concepts]

| Idea      | Meaning                                        |
| --------- | ---------------------------------------------- |
| Element   | A piece of structure: `<p>text&lt;/p>`         |
| Tag       | The `<p>` / `&lt;/p>` markers                  |
| Attribute | Extra info on a tag: `href`, `src`, `alt`      |
| Document  | A full page starting with `&lt;!DOCTYPE html>` |
| Nesting   | Elements inside elements form a tree           |

Files use the `.html` extension. Double-click or serve them locally to view in a browser.

## 💡 Examples [#-examples]

**Minimal page:**

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>My first page</title>
  </head>
  <body>
    <h1>Hello, HTML</h1>
    <p>This is a paragraph.</p>
  </body>
</html>
```

**Save as `index.html` and open in a browser.**

**Common early tags:**

```html
<h1>Title</h1>
<p>Paragraph with a <a href="https://example.com">link</a>.</p>
<img src="photo.jpg" alt="A descriptive alt text" width="300" />
<ul>
  <li>One</li>
  <li>Two</li>
</ul>
```

**Validate structure mentally:** open tags should close (except void elements like `<img>`).

## ⚠️ Pitfalls [#️-pitfalls]

* Skipping `alt` on images hurts accessibility.
* Invalid nesting (`<p><div>&lt;/div>&lt;/p>`) confuses browsers.
* Viewing via `file://` is fine for basics; some APIs need a local server.
* HTML is not a programming language — logic lives in JavaScript.

## 🔗 Related [#-related]

* [hello\_world.md](/docs/html/hello-world)
* [elements\_basics.md](/docs/html/elements-basics)
* [attributes\_basics.md](/docs/html/attributes-basics)
* [semantic.md](/docs/html/semantic)


---

# Glossary (/docs/html/glossary)



# Glossary [#glossary]

*Html · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Alphabetical glossary of core HTML terms for document structure, semantics, forms, media, and accessibility.

## 🔧 Core concepts [#-core-concepts]

| Term           | Definition                                                                   |
| -------------- | ---------------------------------------------------------------------------- |
| Accessibility  | Designing markup so assistive technologies can perceive and operate content. |
| Anchor         | An `<a>` element that creates a hyperlink to a URL or page fragment.         |
| ARIA           | Attributes that expose roles, states, and properties to assistive tech.      |
| Attribute      | A name/value pair on a start tag that configures an element.                 |
| Block element  | An element that typically starts on a new line and fills available width.    |
| Body           | The `<body>` element containing visible page content.                        |
| Canvas         | An `<canvas>` element providing a drawing surface via JavaScript.            |
| Doctype        | The `&lt;!DOCTYPE html>` declaration that puts browsers in standards mode.   |
| Document       | The full HTML tree rooted at `<html>` and represented as the DOM.            |
| DOM            | The in-memory tree of nodes browsers build from HTML.                        |
| Element        | A node created by a start tag, optional content, and an end tag.             |
| Form           | An `<form>` that collects controls and submits data to a server or script.   |
| Head           | The `<head>` section for metadata, links, scripts, and title.                |
| Heading        | Ranked titles `<h1>`–`<h6>` that outline document structure.                 |
| Iframe         | An `<iframe>` that embeds another browsing context/document.                 |
| Inline element | An element that flows within text without forcing a new line.                |
| Input          | A form control (`<input>`) whose behavior depends on its `type`.             |
| Landmark       | A region role such as `nav`, `main`, or `aside` for page navigation.         |
| Meta           | Metadata elements describing charset, viewport, SEO, and more.               |
| Semantic HTML  | Using elements whose meaning matches content, not just presentation.         |
| Slot           | A placeholder in a shadow tree filled by light-DOM children.                 |
| SVG            | Scalable vector graphics markup embeddable in HTML.                          |
| Table          | Markup (`<table>`, `<tr>`, `<th>`, `<td>`) for tabular data.                 |
| Template       | An inert `<template>` whose content can be cloned into the document.         |
| Void element   | An element that cannot have children, such as `<img>` or `<br>`.             |
| Web component  | Custom elements, shadow DOM, and templates used as reusable widgets.         |

## 💡 Examples [#-examples]

**Semantic landmarks:**

```html
<header>
  <nav aria-label="Primary">
    <a href="/">Home</a>
  </nav>
</header>
<main>
  <h1>Docs</h1>
  <article>...</article>
</main>
```

**Form controls:**

```html
<form action="/signup" method="post">
  <label>
    Email
    <input type="email" name="email" required />
  </label>
  <button type="submit">Join</button>
</form>
```

**Picture and responsive images:**

```html
<picture>
  <source srcset="hero.avif" type="image/avif" />
  <img src="hero.jpg" alt="Product hero" width="1200" height="600" />
</picture>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Confusing &#x2A;*`<div>`** (generic box) with **semantic** elements like `<section>` or `<article>`.
* Mixing **block** and **inline** mental models with modern CSS `display` — HTML defaults are only defaults.
* Using **ARIA** to “fix” bad markup instead of preferring native semantics.
* Treating &#x2A;*`<iframe>`** like a simple include — it is a separate document with security boundaries.
* Equating &#x2A;*`<template>`** content with live DOM — it stays inert until cloned.

## 🔗 Related [#-related]

* [semantic](/docs/html/semantic)
* [form](/docs/html/form)
* [accessibility](/docs/html/accessibility)
* [aria](/docs/html/aria)
* [meta](/docs/html/meta)
* [web\_components](/docs/html/web-components)


---

# Head (/docs/html/head)



# Head [#head]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<head>` element holds **document metadata**—information about the page that is mostly not rendered as page content. Typical children: `<title>`, `<meta>`, `<link>`, `<style>`, `<script>`, and `<base>`. Browsers, crawlers, and social platforms read the head to configure charset, viewport, SEO, icons, and resource loading.

There must be exactly one `<head>` per document, as a child of `<html>`, before `<body>`. Visible UI belongs in `<body>`; the head configures how that body is interpreted and presented.

## 🔧 Core concepts [#-core-concepts]

### Minimal document [#minimal-document]

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Page title</title>
  <link rel="stylesheet" href="/styles.css">
</head>
<body>…</body>
</html>
```

### Key children [#key-children]

| Element      | Purpose                                                             |
| ------------ | ------------------------------------------------------------------- |
| `<title>`    | Document title (tabs, bookmarks, SERP); **required** for valid HTML |
| `<meta>`     | Charset, viewport, description, Open Graph, robots, etc.            |
| `<link>`     | Stylesheets, icons, preconnect, canonical, alternate                |
| `<style>`    | Document-level CSS                                                  |
| `<script>`   | JS (prefer `defer` / module in head)                                |
| `<base>`     | Base URL for relative links (use sparingly—global side effects)     |
| `<noscript>` | Fallback when scripting is off (also allowed in body)               |

### Order matters [#order-matters]

1. **Charset** early (`<meta charset="utf-8">` within first 1024 bytes).
2. **Viewport** for responsive mobile layout.
3. **Title** and descriptive meta.
4. **Preconnect / preload** hints before heavy assets.
5. **CSS** (blocking by default—critical CSS strategies apply).
6. **Scripts** with `defer` or `type="module"` so parsing is not blocked unnecessarily.

### Title guidelines [#title-guidelines]

* Unique per page, human-readable, \~50–60 characters for SERPs.
* Put distinctive info first: `Pricing — Acme` not `Acme — Pricing` if tabs truncate.
* Do not stuff keywords; match the primary `<h1>` topic.

## 💡 Examples [#-examples]

### SEO and social basics [#seo-and-social-basics]

```html
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Canvas API — HTML Reference</title>
  <meta name="description" content="Cheat sheet for the HTML canvas element and drawing API.">
  <link rel="canonical" href="https://example.com/html/canvas">
  <meta property="og:title" content="Canvas API — HTML Reference">
  <meta property="og:type" content="article">
  <meta property="og:url" content="https://example.com/html/canvas">
  <meta property="og:image" content="https://example.com/og/canvas.png">
</head>
```

### Performance hints [#performance-hints]

```html
<head>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://cdn.example.com" crossorigin>
  <link rel="preload" href="/fonts/Inter.woff2" as="font" type="font/woff2" crossorigin>
  <link rel="stylesheet" href="/app.css">
  <script src="/app.js" defer></script>
</head>
```

### Icons and theme [#icons-and-theme]

```html
<head>
  <link rel="icon" href="/favicon.ico" sizes="any">
  <link rel="icon" href="/icon.svg" type="image/svg+xml">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">
  <meta name="theme-color" content="#0f766e">
  <link rel="manifest" href="/manifest.webmanifest">
</head>
```

### Alternate languages [#alternate-languages]

```html
<head>
  <link rel="alternate" hreflang="en" href="https://example.com/en/docs">
  <link rel="alternate" hreflang="es" href="https://example.com/es/docs">
  <link rel="alternate" hreflang="x-default" href="https://example.com/docs">
</head>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Late charset** — Can cause mojibake; keep UTF-8 meta first.
* **Missing viewport** — Mobile browsers may zoom out to a desktop width.
* **Blocking scripts in head** — Without `defer`/`async`/module, parsing stalls.
* **Multiple titles** — Invalid; only one `<title>` should exist.
* **Secrets in head** — Meta tags are public; never put API keys there.
* **`<base>` surprises** — Changes every relative URL, including anchors and forms.
* **Duplicate canonicals** — Conflicting signals hurt SEO.

## 🔗 Related [#-related]

* [Meta](/docs/html/meta) — meta element details
* [Script](/docs/html/script) — loading JS from head or body
* [Style](/docs/html/style) — `<style>` and linked CSS
* [URL](/docs/html/url) — canonical and alternate URLs
* [Language](/docs/html/language) — `lang` on `<html>`, hreflang
* [XML](/docs/html/xml) — XHTML / polyglot considerations


---

# Hello World (/docs/html/hello-world)



# Hello World [#hello-world]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

An HTML Hello World is a complete minimal document that shows a heading or paragraph in the browser. It confirms your file is saved correctly and the browser can render markup.

## 🔧 Core concepts [#-core-concepts]

| Piece                | Role                                    |
| -------------------- | --------------------------------------- |
| `&lt;!DOCTYPE html>` | Tells the browser to use standards mode |
| `<html>`             | Root element                            |
| `<head>`             | Metadata (title, charset, CSS links)    |
| `<body>`             | Visible content                         |
| `<h1>` / `<p>`       | Heading and paragraph                   |

Always set `lang` on `<html>` and `charset` in `<head>`.

## 💡 Examples [#-examples]

**Classic hello page:**

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Hello</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>
```

**Hello with a paragraph and link:**

```html
<body>
  <h1>Hello, World!</h1>
  <p>Welcome to <strong>HTML</strong>.</p>
  <p><a href="https://developer.mozilla.org/">Learn more on MDN</a></p>
</body>
```

**Inline emphasis:**

```html
<p>Hello, <em>World</em>!</p>
```

**Comment in HTML:**

```html
<!-- This is not shown on the page -->
<p>Hello, World!</p>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Saving as `.txt` may open as plain text — use `.html`.
* Forgetting `&lt;/h1>` can make the rest of the page inherit heading styles.
* Using multiple `<h1>` without thought hurts document outline clarity.
* Fancy Word-processor HTML is messy — write markup in a code editor.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/html/getting-started)
* [elements\_basics.md](/docs/html/elements-basics)
* [attributes\_basics.md](/docs/html/attributes-basics)
* [links.md](/docs/html/links)


---

# iframe (/docs/html/iframe)



# iframe [#iframe]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`<iframe>` embeds another browsing context (page, PDF, map, video player). Powerful but costly for performance and security — sandbox aggressively, size explicitly, and prefer lighter embeds when possible. Use `title` for accessibility.

## 🔧 Core concepts [#-core-concepts]

| Attribute          | Role                                   |
| ------------------ | -------------------------------------- |
| `src`              | embedded URL                           |
| `srcdoc`           | inline HTML document                   |
| `title`            | accessible name (required in practice) |
| `width` / `height` | layout size                            |
| `allow`            | Permissions Policy features            |
| `sandbox`          | restrictions token list                |
| `loading`          | `lazy` / `eager`                       |
| `referrerpolicy`   | referrer sent to embed                 |
| `allowfullscreen`  | legacy; prefer `allow="fullscreen"`    |

* Cross-origin frames limit DOM access (same-origin policy).
* Communicate via `postMessage`.

```html
<iframe
  title="Map of office location"
  src="https://maps.example.com/embed?..."
  width="600"
  height="400"
  loading="lazy"
  referrerpolicy="no-referrer-when-downgrade"
  allow="geolocation 'none'"
></iframe>
```

## 💡 Examples [#-examples]

```html
<!-- Sandboxed untrusted HTML -->
<iframe
  title="User preview"
  sandbox="allow-scripts"
  srcdoc="<p>Hello</p>"
></iframe>

<!-- Strict sandbox (no scripts/forms) -->
<iframe title="Static preview" sandbox src="/preview.html"></iframe>

<!-- YouTube-style -->
<iframe
  title="Product demo video"
  src="https://www.youtube-nocookie.com/embed/VIDEO_ID"
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
  allowfullscreen
  loading="lazy"
></iframe>

<!-- postMessage -->
<script>
  frame.contentWindow.postMessage({ type: "ping" }, "https://trusted.example");
  window.addEventListener("message", (e) => {
    if (e.origin !== "https://trusted.example") return;
    console.log(e.data);
  });
</script>
```

```html
<!-- Aspect ratio wrapper -->
<div class="frame" style="aspect-ratio:16/9">
  <iframe title="Demo" src="..." style="width:100%;height:100%;border:0"></iframe>
</div>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Missing `sandbox` on untrusted content is dangerous (`allow-scripts` + `allow-same-origin` together can escape sandbox).
* Each iframe is expensive (memory/network) — lazy-load offscreen ones.
* Empty or missing `title` fails a11y checks.
* Assuming you can read `iframe.contentDocument` cross-origin throws.
* CSP `frame-src` / `child-src` may block embeds — coordinate headers.

## 🔗 Related [#-related]

* [embedding.md](/docs/html/embedding) — embed/object
* [video\_audio.md](/docs/html/video-audio) — native media
* [accessibility.md](/docs/html/accessibility) — titles
* [../Javascript/web\_workers.md](/docs/html/../javascript/web-workers) — other isolation
* [../CSS/aspect\_ratio.md](/docs/html/../css/aspect-ratio) — responsive frames


---

# Images (/docs/html/images)



# Images [#images]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<img>` element embeds images. Always provide meaningful `alt` (or empty `alt=""` for decorative). Use `width`/`height` or CSS aspect-ratio to reduce layout shift, and `srcset`/`sizes` for responsive resolution switching. For art direction, prefer `<picture>`.

## 🔧 Core concepts [#-core-concepts]

| Attribute          | Role                                          |
| ------------------ | --------------------------------------------- |
| `src`              | image URL                                     |
| `alt`              | text alternative                              |
| `width` / `height` | intrinsic layout hints                        |
| `srcset`           | candidate URLs with density/width descriptors |
| `sizes`            | layout width for `w` descriptors              |
| `loading`          | `lazy` / `eager`                              |
| `decoding`         | `async` / `sync` / `auto`                     |
| `fetchpriority`    | `high` / `low` / `auto`                       |
| `crossorigin`      | CORS for canvas use                           |

```html
<img
  src="/hero.jpg"
  alt="Team collaborating at a whiteboard"
  width="1200"
  height="800"
  loading="lazy"
  decoding="async"
/>
```

## 💡 Examples [#-examples]

```html
<!-- Decorative -->
<img src="/divider.svg" alt="" role="presentation" />

<!-- Responsive density -->
<img
  src="/logo.png"
  srcset="/logo.png 1x, /logo@2x.png 2x"
  alt="Acme"
  width="120"
  height="40"
/>

<!-- Width descriptors -->
<img
  src="/photo-800.jpg"
  srcset="/photo-400.jpg 400w, /photo-800.jpg 800w, /photo-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw, 600px"
  alt="Mountain lake at dawn"
  width="1200"
  height="800"
  loading="lazy"
/>

<!-- LCP hero: eager + high priority -->
<img
  src="/hero.avif"
  alt="Product screenshot"
  width="1600"
  height="900"
  fetchpriority="high"
/>

<!-- Map -->
<img src="/map.png" alt="Campus map" usemap="#campus" width="600" height="400" />
```

```html
<!-- Always pair with CSS max-width -->
<!-- img { max-width: 100%; height: auto; } -->
```

## ⚠️ Pitfalls [#️-pitfalls]

* Missing `alt` is worse than empty decorative `alt=""` — decide intentionally.
* Lazy-loading the LCP image hurts performance — keep heroes eager.
* Wrong `sizes` picks huge or tiny candidates — match real CSS layout.
* Hotlinking / missing CORS breaks canvas `getImageData`.
* Putting text only in images harms a11y and SEO — use real text.

## 🔗 Related [#-related]

* [picture\_source.md](/docs/html/picture-source) — art direction
* [svg\_inline.md](/docs/html/svg-inline) — SVG
* [media.md](/docs/html/media) — media overview
* [../CSS/object\_fit.md](/docs/html/../css/object-fit) — fitting
* [accessibility.md](/docs/html/accessibility) — alt text


---

# Input (/docs/html/input)



# Input [#input]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<input>` element creates interactive controls for forms. Behavior depends on the `type` attribute: text fields, checkboxes, radios, files, dates, range sliders, buttons, and more. Inputs participate in constraint validation, autofill, and keyboard accessibility when properly labeled.

Always associate a visible `<label>` (or accessible name). Choose the most specific `type` so mobile keyboards, validation, and password managers work correctly.

## 🔧 Core concepts [#-core-concepts]

### Common types [#common-types]

| `type`                                            | Use                                                        |
| ------------------------------------------------- | ---------------------------------------------------------- |
| `text`                                            | Single-line text (default)                                 |
| `email`, `url`, `tel`, `search`                   | Semantic text with validation / keyboards                  |
| `password`                                        | Obscured text; use `autocomplete`                          |
| `number`                                          | Numeric; `min`/`max`/`step`                                |
| `checkbox`                                        | Independent on/off                                         |
| `radio`                                           | One of a named group                                       |
| `file`                                            | File picker; needs `enctype="multipart/form-data"` on form |
| `hidden`                                          | Not shown; still submitted                                 |
| `date`, `time`, `datetime-local`, `month`, `week` | Temporal pickers (support varies)                          |
| `range`, `color`                                  | Visual pickers                                             |
| `submit`, `reset`, `button`, `image`              | Form actions                                               |

### Critical attributes [#critical-attributes]

* `name` — key in submitted data
* `value` — current / default value; for checkbox/radio, the value when selected
* `required`, `disabled`, `readonly`
* `placeholder` — hint only, **not** a label
* `autocomplete` — tokens like `email`, `new-password`, `street-address`
* `inputmode` — virtual keyboard hint (`decimal`, `numeric`, `email`, …)
* `pattern` — regex for text-like types
* `accept`, `multiple` — file inputs
* `checked` — initial state for checkbox/radio
* `min`, `max`, `step`, `minlength`, `maxlength`

### Labels and grouping [#labels-and-grouping]

```html
<label for="email">Email</label>
<input id="email" name="email" type="email" required autocomplete="email">

<fieldset>
  <legend>Shipping</legend>
  <label><input type="radio" name="ship" value="std" checked> Standard</label>
  <label><input type="radio" name="ship" value="exp"> Express</label>
</fieldset>
```

Radios sharing the same `name` form one tab stop group; arrows move between options.

### Events and values [#events-and-values]

* `input` — value changing; `change` — committed change
* Read via `element.value`, `checked`, or `FormData`
* Files: `input.files` (`FileList`); not available in plain Form URL encoding without multipart

## 💡 Examples [#-examples]

### Text with validation [#text-with-validation]

```html
<label for="username">Username</label>
<input
  id="username"
  name="username"
  type="text"
  required
  minlength="3"
  maxlength="32"
  pattern="[a-zA-Z0-9_]+"
  autocomplete="username"
  aria-describedby="username-hint">
<p id="username-hint">Letters, numbers, and underscore only.</p>
```

### Checkbox and switch-like pattern [#checkbox-and-switch-like-pattern]

```html
<label>
  <input type="checkbox" name="tos" value="yes" required>
  I agree to the terms
</label>
```

### Number and range [#number-and-range]

```html
<label for="qty">Quantity</label>
<input id="qty" name="qty" type="number" min="1" max="99" step="1" value="1">

<label for="vol">Volume</label>
<input id="vol" name="volume" type="range" min="0" max="100" value="50"
  aria-valuemin="0" aria-valuemax="100">
```

### File input [#file-input]

```html
<label for="docs">Attachments</label>
<input
  id="docs"
  name="docs"
  type="file"
  accept=".pdf,image/*"
  multiple
  aria-describedby="docs-help">
<p id="docs-help">PDF or images, up to 5 files.</p>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Placeholder as label** — Disappears on input; bad for a11y and memory.
* **`type="number"` for IDs** — Spinners and parsing issues; use `inputmode="numeric"` + `pattern` for digit strings.
* **Missing `name` on radios** — Grouping breaks; all can appear selected independently.
* **Styling away focus** — Never remove outlines without a visible `:focus-visible` replacement.
* **Hidden required fields** — Can block submit with no visible error.
* **Date formats** — Wire format is ISO-like; display is locale-dependent—do not parse as local free text.
* **Disabled vs readonly** — `disabled` controls are **not** submitted; `readonly` text still is.

## 🔗 Related [#-related]

* [Forms](/docs/html/form) — submission, `FormData`, validation API
* [List](/docs/html/list) — `<datalist>` options for inputs
* [Script](/docs/html/script) — enhancing input behavior
* [Table](/docs/html/table) — inputs in data grids (label carefully)
* [URL](/docs/html/url) — `type="url"` and query encoding
* [Meta](/docs/html/meta) — CSRF / tokens often paired with hidden inputs


---

# Language (/docs/html/language)



# Language [#language]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Language in HTML is declared primarily with the **`lang` attribute**. It tells browsers, search engines, and assistive technologies which natural language (and optionally dialect) the content uses. Correct language tags improve screen-reader pronunciation, hyphenation, spell-check, font selection, and SEO.

Set `lang` on the root `<html>` element for the document default, then override on elements that switch language. Pair with `hreflang` on links and `<link rel="alternate">` for translated URLs.

## 🔧 Core concepts [#-core-concepts]

### BCP 47 language tags [#bcp-47-language-tags]

Use standard tags, not free-form names:

| Tag          | Meaning                      |
| ------------ | ---------------------------- |
| `en`         | English                      |
| `en-US`      | English (United States)      |
| `en-GB`      | English (United Kingdom)     |
| `es`         | Spanish                      |
| `zh-Hans`    | Chinese, Simplified script   |
| `zh-Hant-TW` | Chinese, Traditional, Taiwan |
| `und`        | Undetermined (rare)          |

Primary language subtag is required; region and script are optional. Prefer the shortest tag that is still useful (`en` vs `en-US` when dialect matters for spelling/voice).

### Document and fragment language [#document-and-fragment-language]

```html
<html lang="en">
…
<blockquote lang="fr">
  <p>Liberté, égalité, fraternité.</p>
</blockquote>
```

* Inheritance: children inherit language unless overridden.
* Empty `lang=""` means unknown / no language (e.g. some proper nouns)—use sparingly.
* `xml:lang` appears in XHTML; in HTML5, `lang` is preferred (both may match in polyglot docs).

### Related attributes and elements [#related-attributes-and-elements]

* **`hreflang`** — language of the linked resource (`<a>`, `<link>`, `<area>`).
* **`translate`** — `yes` / `no` hint for translation tools.
* **`<title>` / meta description** — should match page language.
* **CSS `hyphens` / `:lang()`** — style per language.

```css
:lang(de) { quotes: "„" "“" "‚" "‘"; }
```

### Accessibility [#accessibility]

Screen readers switch voice models based on `lang`. Wrong or missing `lang` causes mispronunciation. Mark inline phrases in another language; do not mark decorative icons or code as a human language unless appropriate (`lang` on `<code>` is often omitted or set to empty).

## 💡 Examples [#-examples]

### Root declaration [#root-declaration]

```html
<!DOCTYPE html>
<html lang="en-GB">
<head>
  <meta charset="utf-8">
  <title>Colour systems</title>
</head>
<body>
  <h1>Colour systems</h1>
</body>
</html>
```

### Inline language switch [#inline-language-switch]

```html
<p>
  The French motto
  <span lang="fr">Liberté, égalité, fraternité</span>
  appears on many public buildings.
</p>
```

### Multilingual navigation with hreflang [#multilingual-navigation-with-hreflang]

```html
<nav aria-label="Languages">
  <ul>
    <li><a href="/en/guide" hreflang="en" lang="en">English</a></li>
    <li><a href="/es/guia" hreflang="es" lang="es">Español</a></li>
    <li><a href="/ja/guide" hreflang="ja" lang="ja">日本語</a></li>
  </ul>
</nav>
```

### Alternate links in head [#alternate-links-in-head]

```html
<head>
  <link rel="alternate" hreflang="en" href="https://example.com/en/docs">
  <link rel="alternate" hreflang="fr" href="https://example.com/fr/docs">
  <link rel="alternate" hreflang="x-default" href="https://example.com/docs">
</head>
```

### Opt out of translation [#opt-out-of-translation]

```html
<p>
  Product code
  <span translate="no">XR-2040-B</span>
  must stay unchanged.
</p>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Missing `lang` on `<html>`** — Validators flag it; AT guesses poorly.
* **Wrong tag** — `eng` or `english` is invalid; use `en`.
* **Over-tagging** — Do not set `lang` on every element when the root already applies.
* **Machine-translated pages** — Keep `lang` accurate to the visible text, not the source CMS locale.
* **`hreflang` mismatches** — Reciprocal alternates should form a consistent set; include `x-default` when appropriate.
* **Direction vs language** — `dir="rtl"` is separate from `lang`; set both for Arabic/Hebrew content (`lang="ar" dir="rtl"`).

## 🔗 Related [#-related]

* [Head](/docs/html/head) — document setup and alternate links
* [Meta](/docs/html/meta) — content-language meta (legacy; prefer `lang`)
* [XML](/docs/html/xml) — `xml:lang` in XML/XHTML
* [Nav](/docs/html/nav) — language switchers
* [Section](/docs/html/section) — scoping translated regions
* [URL](/docs/html/url) — locale prefixes in paths


---

# Links (/docs/html/links)



# Links [#links]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<a>` element creates hyperlinks to URLs, fragments, email/tel schemes, and downloadable files. Accessible links need clear text (not “click here”), meaningful `href`, and honest `target`/`rel` usage. Prefer real links for navigation so middle-click and progressive enhancement work.

## 🔧 Core concepts [#-core-concepts]

| Attribute  | Role                                                              |
| ---------- | ----------------------------------------------------------------- |
| `href`     | destination URL or `#fragment`                                    |
| `target`   | `_self` `_blank` `_parent` `_top` or frame name                   |
| `rel`      | link relationship (`noopener`, `noreferrer`, `nofollow`, `me`, …) |
| `download` | suggest download filename                                         |
| `hreflang` | language of target                                                |
| `type`     | MIME hint                                                         |
| `ping`     | tracking URLs (privacy-sensitive)                                 |

* Without `href`, `<a>` is a placeholder (not in tab order the same way).
* `target="_blank"` should include `rel="noopener noreferrer"` (modern browsers imply noopener for `_blank`, still good practice).

```html
<a href="/docs/intro">Introduction</a>
<a href="https://example.com" target="_blank" rel="noopener noreferrer">External</a>
<a href="#faq">Jump to FAQ</a>
```

## 💡 Examples [#-examples]

```html
<!-- Email / phone -->
<a href="mailto:hello@example.com">Email us</a>
<a href="tel:+15551234567">Call</a>

<!-- Download -->
<a href="/files/report.pdf" download="report.pdf">Download PDF</a>

<!-- Fragment + id -->
<a href="#shipping">Shipping</a>
<section id="shipping">...</section>

<!-- Skip link -->
<a class="skip" href="#main">Skip to content</a>
<main id="main">...</main>

<!-- Button-looking link vs button -->
<a class="btn" href="/signup">Sign up</a>
<button type="button">Open dialog</button>

<!-- Nav -->
<nav aria-label="Primary">
  <a href="/" aria-current="page">Home</a>
  <a href="/pricing">Pricing</a>
</nav>
```

```html
<!-- Empty href="#" is a smell — use button for actions -->
```

## ⚠️ Pitfalls [#️-pitfalls]

* Using `<a href="#">` or omitting `href` for JS actions breaks accessibility — use `<button>`.
* Vague link text fails screen reader users scanning links lists.
* `target="_blank"` without context surprises users — warn when needed.
* Nested interactive content (`a` inside `a`, or `a` wrapping `button`) is invalid.
* `javascript:` URLs are obsolete and unsafe.

## 🔗 Related [#-related]

* [nav.md](/docs/html/nav) — navigation landmarks
* [button.md](/docs/html/button) — buttons vs links
* [url.md](/docs/html/url) — URL concepts
* [accessibility.md](/docs/html/accessibility) — a11y
* [aria.md](/docs/html/aria) — aria-current


---

# Lists (/docs/html/list)



# Lists [#lists]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

HTML provides three primary list types: **ordered** (`<ol>`), **unordered** (`<ul>`), and **description** (`<dl>`). Lists convey structure to assistive technologies—use them for genuine sequences and name/value groups, not merely for indentation. Navigation menus are typically lists inside `<nav>`.

Related helpers: `<li>` for list items, `<dt>` / `<dd>` for terms and descriptions, and `<datalist>` for input suggestions (not a visible list widget by itself).

## 🔧 Core concepts [#-core-concepts]

### Unordered lists (`<ul>`) [#unordered-lists-ul]

Bulleted collections where order is not significant (features, tags, nav links).

```html
<ul>
  <li>Apples</li>
  <li>Oranges</li>
</ul>
```

### Ordered lists (`<ol>`) [#ordered-lists-ol]

Numbered sequences. Attributes:

| Attribute  | Effect                                                 |
| ---------- | ------------------------------------------------------ |
| `type`     | `1`, `a`, `A`, `i`, `I` (prefer CSS `list-style-type`) |
| `start`    | Starting number                                        |
| `reversed` | Count downward                                         |

```html
<ol start="3" reversed>
  <li>Third</li>
  <li>Second</li>
  <li>First</li>
</ol>
```

### Description lists (`<dl>`) [#description-lists-dl]

Groups of terms (`<dt>`) and descriptions (`<dd>`). One term may have multiple descriptions and vice versa.

```html
<dl>
  <dt>HTML</dt>
  <dd>HyperText Markup Language</dd>
  <dt>CSS</dt>
  <dd>Cascading Style Sheets</dd>
</dl>
```

### Nesting and content model [#nesting-and-content-model]

* Only `<li>` may be direct children of `<ul>` / `<ol>` (plus script-supporting elements).
* Nest lists **inside** `<li>`, not as siblings of `<li>`.
* Flow content is allowed inside `<li>`, `<dt>`, `<dd>`.

### Accessibility [#accessibility]

* Lists announce item counts in many screen readers.
* Do not fake lists with `<div>` + bullets; rebuild as real lists.
* For nav: `<nav><ul><li><a>…&lt;/a>&lt;/li>&lt;/ul>&lt;/nav>`.
* Flat vs nested: reflect real hierarchy; avoid deep nesting without need.
* Custom markers via CSS still keep list semantics if the elements remain.

## 💡 Examples [#-examples]

### Nested navigation list [#nested-navigation-list]

```html
<nav aria-label="Docs">
  <ul>
    <li><a href="/html">HTML</a>
      <ul>
        <li><a href="/html/forms">Forms</a></li>
        <li><a href="/html/tables">Tables</a></li>
      </ul>
    </li>
    <li><a href="/css">CSS</a></li>
  </ul>
</nav>
```

### Steps with ordered list [#steps-with-ordered-list]

```html
<ol>
  <li>Add the <code>lang</code> attribute to <code>&lt;html&gt;</code>.</li>
  <li>Provide a unique <code>&lt;title&gt;</code>.</li>
  <li>Include a viewport meta tag.</li>
</ol>
```

### Glossary with description list [#glossary-with-description-list]

```html
<dl>
  <dt id="term-landmark">Landmark</dt>
  <dd>
    A region role that assistive tech can jump to
    (e.g. <code>main</code>, <code>navigation</code>).
  </dd>
  <dt>Focus visible</dt>
  <dd>Clear indication of the keyboard-focused element.</dd>
</dl>
```

### Datalist for input suggestions [#datalist-for-input-suggestions]

```html
<label for="browser">Browser</label>
<input id="browser" name="browser" list="browsers" autocomplete="off">
<datalist id="browsers">
  <option value="Firefox">
  <option value="Chrome">
  <option value="Safari">
  <option value="Edge">
</datalist>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Div lists** — Breaking list semantics loses count announcements and list shortcuts.
* **Invalid children** — Putting `<p>` or `<div>` directly in `<ul>` is invalid; wrap with `<li>`.
* **Using tables for layout lists** — Prefer lists or CSS grid.
* **Empty bullets for spacing** — Use margin/gap, not empty `<li>` elements.
* **`type` on `<ul>`** — Deprecated presentational habit; use CSS.
* **Description list misuse** — Dialogues or random pairs may fit better as headings + paragraphs or cards.
* **ARIA `role="list"` on styled lists** — Some browsers drop list semantics when `list-style: none` is applied; restoring with explicit roles may be needed—test with AT.

## 🔗 Related [#-related]

* [Nav](/docs/html/nav) — menus built from lists
* [Input](/docs/html/input) — `list` + `<datalist>`
* [Section](/docs/html/section) — grouping list-heavy content
* [Table](/docs/html/table) — when tabular data beats lists
* [Div](/docs/html/div) — avoid replacing lists with divs
* [Form](/docs/html/form) — option groups vs lists


---

# Media (/docs/html/media)



# Media [#media]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

HTML media elements embed images, audio, video, and responsive picture sources. Core tags: `<img>`, `<picture>`, `<audio>`, `<video>`, `<source>`, `<track>`, and older embeds (`<iframe>`, `<object>`). Prefer native elements for playback controls, captions, and performance hints (`loading`, `decoding`, `preload`).

Accessible media needs **text alternatives** (alt text, transcripts, captions) and must not autoplay with sound. Decorative images use empty `alt=""`.

## 🔧 Core concepts [#-core-concepts]

### Images (`<img>`) [#images-img]

Required: `src` (or `srcset` with sizes) and `alt`.

| Attribute          | Role                                     |
| ------------------ | ---------------------------------------- |
| `alt`              | Short equivalent; `alt=""` if decorative |
| `width` / `height` | Reduce CLS; match aspect ratio           |
| `loading="lazy"`   | Defer offscreen images                   |
| `decoding="async"` | Decode without blocking                  |
| `srcset` / `sizes` | Responsive resolution candidates         |
| `fetchpriority`    | `high` for LCP image when appropriate    |

### Picture and art direction [#picture-and-art-direction]

```html
<picture>
  <source type="image/avif" srcset="hero.avif">
  <source type="image/webp" srcset="hero.webp">
  <img src="hero.jpg" alt="Mountain lake at sunrise" width="1200" height="600">
</picture>
```

Use media queries on `<source media="…">` when cropping changes by viewport—not only for format fallbacks.

### Video and audio [#video-and-audio]

```html
<video controls playsinline poster="poster.jpg" width="640" height="360">
  <source src="talk.webm" type="video/webm">
  <source src="talk.mp4" type="video/mp4">
  <track kind="captions" srclang="en" src="talk.vtt" label="English" default>
  Download the <a href="talk.mp4">MP4</a>.
</video>
```

* `controls` — native UI (prefer over custom-only players without a11y).
* `autoplay` — often blocked; if used, mute with `muted` and keep motion brief.
* `loop`, `preload` (`none` | `metadata` | `auto`).
* `<track>` — captions (`captions`), subtitles, descriptions, chapters.

### Iframes [#iframes]

Third-party embeds need `title`, restrictive `sandbox` when possible, and thoughtful `loading="lazy"`. Prefer privacy-enhanced embed URLs.

## 💡 Examples [#-examples]

### Responsive image with srcset [#responsive-image-with-srcset]

```html
<img
  src="photo-800.jpg"
  srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw, 600px"
  alt="Red ceramic mug on a wooden table"
  width="800"
  height="600"
  loading="lazy"
  decoding="async">
```

### Audio with transcript [#audio-with-transcript]

```html
<figure>
  <figcaption id="ep-title">Episode 12: Semantic HTML</figcaption>
  <audio controls preload="metadata" aria-labelledby="ep-title">
    <source src="ep12.mp3" type="audio/mpeg">
  </audio>
  <details>
    <summary>Transcript</summary>
    <p>Welcome to episode twelve…</p>
  </details>
</figure>
```

### Art-directed picture [#art-directed-picture]

```html
<picture>
  <source media="(max-width: 600px)" srcset="hero-mobile.jpg">
  <source media="(min-width: 601px)" srcset="hero-desktop.jpg">
  <img src="hero-desktop.jpg" alt="Team collaborating in a bright studio">
</picture>
```

### Accessible iframe embed [#accessible-iframe-embed]

```html
<iframe
  title="Map: office location"
  src="https://maps.example.com/embed?q=office"
  loading="lazy"
  referrerpolicy="no-referrer-when-downgrade"
  allowfullscreen></iframe>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Missing alt** — Critical a11y/SEO failure; decorative needs `alt=""`, not omitted.
* **Filename as alt** — `alt="IMG_4022.jpg"` helps no one.
* **Autoplay + sound** — Hostile UX; often blocked; violates preferences.
* **Captions missing** — Video without captions excludes Deaf/hard-of-hearing users.
* **Huge unoptimized assets** — Compress, modern formats, correct dimensions.
* **CSS background for content images** — Cannot carry alt text; use `<img>` for meaningful photos.
* **Aspect ratio CLS** — Always set width/height or CSS `aspect-ratio`.

## 🔗 Related [#-related]

* [Src](/docs/html/src) — `src`, `srcset`, and URL resolution
* [URL](/docs/html/url) — absolute vs relative media URLs
* [Canvas](/docs/html/canvas) — drawing frames from video/images
* [Figure patterns](/docs/html/section) — grouping media with captions
* [Script](/docs/html/script) — custom players and Media element API
* [Style](/docs/html/style) — object-fit and responsive CSS


---

# Meta (/docs/html/meta)



# Meta [#meta]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<meta>` element represents metadata that cannot be expressed with `<title>`, `<link>`, `<script>`, or `<style>`. It lives in `<head>` (except `itemprop` microdata cases). Meta tags configure character encoding, viewport behavior, SEO descriptions, social previews, robots directives, and HTTP-equivalent headers.

Meta content is always public in the HTML source—never store secrets there.

## 🔧 Core concepts [#-core-concepts]

### Forms of meta [#forms-of-meta]

1. **Charset** — `<meta charset="utf-8">`
2. **Name/content** — `<meta name="description" content="…">`
3. **Http-equiv** — `<meta http-equiv="…" content="…">` (prefer real HTTP headers when possible)
4. **Property** (Open Graph, etc.) — `<meta property="og:title" content="…">`

### Essential tags [#essential-tags]

```html
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Concise summary of the page for search and shares.">
```

Viewport notes:

* `width=device-width` — match CSS pixels to device.
* Avoid locking zoom (`user-scalable=no`, extreme `maximum-scale`)—hurts accessibility.
* `viewport-fit=cover` — notched devices with `env(safe-area-inset-*)`.

### SEO and robots [#seo-and-robots]

| Name                 | Purpose                                      |
| -------------------- | -------------------------------------------- |
| `description`        | Snippet candidate (\~150–160 chars)          |
| `robots`             | `index`/`noindex`, `follow`/`nofollow`, etc. |
| `googlebot`          | Crawler-specific overrides                   |
| `author`, `keywords` | Low impact today; keywords largely ignored   |

```html
<meta name="robots" content="index, follow">
<meta name="googlebot" content="max-image-preview:large">
```

### Social and app meta [#social-and-app-meta]

Open Graph and Twitter cards drive link previews:

```html
<meta property="og:title" content="Forms — HTML Reference">
<meta property="og:description" content="Cheat sheet for the form element.">
<meta property="og:image" content="https://example.com/og/forms.png">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
```

Also common: `theme-color`, `color-scheme`, `application-name`, Apple mobile web app tags.

### Http-equiv (use carefully) [#http-equiv-use-carefully]

| http-equiv                | Notes                                               |
| ------------------------- | --------------------------------------------------- |
| `refresh`                 | Redirect/refresh—prefer HTTP 301/302; a11y concerns |
| `content-security-policy` | Prefer CSP HTTP header                              |
| `X-UA-Compatible`         | Legacy IE; obsolete for modern sites                |

## 💡 Examples [#-examples]

### Solid default head metas [#solid-default-head-metas]

```html
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Tables — HTML Reference</title>
  <meta name="description" content="Accessible HTML table patterns, scope, and captions.">
  <meta name="color-scheme" content="light dark">
  <meta name="theme-color" content="#0f766e">
</head>
```

### Noindex draft page [#noindex-draft-page]

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

### Open Graph article [#open-graph-article]

```html
<meta property="og:type" content="article">
<meta property="og:title" content="Prefer semantic lists">
<meta property="og:url" content="https://example.com/blog/lists">
<meta property="og:image" content="https://example.com/og/lists.png">
<meta property="article:published_time" content="2026-07-10T08:00:00Z">
```

### CSP via meta (header preferred) [#csp-via-meta-header-preferred]

```html
<meta
  http-equiv="Content-Security-Policy"
  content="default-src 'self'; img-src 'self' https: data:; script-src 'self'">
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Charset not first** — Place within the first 1024 bytes.
* **Duplicate descriptions** — Keep one clear `name="description"`.
* **Refresh redirects** — Confuse users and AT; break the back button.
* **Keyword stuffing** — Ineffective and spammy.
* **Disabling zoom** — Accessibility violation for low-vision users.
* **Relative OG images** — Many crawlers need absolute HTTPS URLs.
* **Conflicting robots** — Meta vs `X-Robots-Tag` vs `robots.txt`—align them.

## 🔗 Related [#-related]

* [Head](/docs/html/head) — where meta belongs
* [URL](/docs/html/url) — canonical URLs alongside meta
* [Language](/docs/html/language) — prefer `lang` over `content-language`
* [Media](/docs/html/media) — OG image assets
* [Script](/docs/html/script) — CSP interaction with inline scripts
* [XML](/docs/html/xml) — metadata in XML documents


---

# Nav (/docs/html/nav)



# Nav [#nav]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<nav>` element marks a section of **major navigation links**—site menus, tables of contents, breadcrumbs, or in-page indexes. Browsers expose it as a `navigation` landmark so assistive technology users can jump directly to it.

Not every group of links needs `<nav>`: footers often wrap legal links in one labeled nav, while incidental “related posts” links may stay in a plain list inside `<aside>` or `<footer>`. Prefer quality over quantity of landmarks.

## 🔧 Core concepts [#-core-concepts]

### Landmark behavior [#landmark-behavior]

* Implicit role: `navigation`.
* Multiple navs are allowed; distinguish them with `aria-label` or `aria-labelledby`.
* Skip redundant roles: do not write `<nav role="navigation">`.

```html
<nav aria-label="Primary">…</nav>
<nav aria-label="Breadcrumb">…</nav>
```

### Typical structure [#typical-structure]

Lists are the conventional pattern:

```html
<nav aria-label="Primary">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/docs" aria-current="page">Docs</a></li>
    <li><a href="/blog">Blog</a></li>
  </ul>
</nav>
```

* `aria-current="page"` (or `true`) marks the current page link.
* One primary `<h2 class="visually-hidden">` can label the region instead of `aria-label`.

### What belongs in nav [#what-belongs-in-nav]

| Include                    | Usually exclude                         |
| -------------------------- | --------------------------------------- |
| Main site menu             | Social icon rows without site structure |
| Docs TOC                   | Pagination alone (optional)             |
| Breadcrumbs                | Random related links                    |
| In-page section jump lists | Language pickers can be nav if major    |

### Keyboard and mobile [#keyboard-and-mobile]

* Ensure links are real `<a href>`—not clickable divs.
* Disclose mobile menus with `<button>` + `aria-expanded`, focus management, and Esc to close.
* Visible focus styles on all interactive items.

## 💡 Examples [#-examples]

### Primary and utility navs [#primary-and-utility-navs]

```html
<header>
  <a href="/">Acme</a>
  <nav aria-label="Primary">
    <ul>
      <li><a href="/product">Product</a></li>
      <li><a href="/pricing">Pricing</a></li>
    </ul>
  </nav>
  <nav aria-label="Account">
    <ul>
      <li><a href="/login">Log in</a></li>
    </ul>
  </nav>
</header>
```

### Breadcrumbs [#breadcrumbs]

```html
<nav aria-label="Breadcrumb">
  <ol>
    <li><a href="/">Home</a></li>
    <li><a href="/docs">Docs</a></li>
    <li aria-current="page">Forms</li>
  </ol>
</nav>
```

### Table of contents [#table-of-contents]

```html
<article>
  <h1>Accessible tables</h1>
  <nav aria-labelledby="toc-heading">
    <h2 id="toc-heading">On this page</h2>
    <ol>
      <li><a href="#caption">Captions</a></li>
      <li><a href="#scope">Scope</a></li>
    </ol>
  </nav>
  <section id="caption">…</section>
</article>
```

### Disclosure menu sketch [#disclosure-menu-sketch]

```html
<nav aria-label="Primary">
  <button type="button" aria-expanded="false" aria-controls="menu">
    Menu
  </button>
  <ul id="menu" hidden>
    <li><a href="/docs">Docs</a></li>
    <li><a href="/api">API</a></li>
  </ul>
</nav>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Too many nav landmarks** — Every link list as `<nav>` overwhelms rotor menus.
* **Unlabeled duplicates** — Two “navigation” entries with no name are indistinguishable.
* **Nav without links** — Empty or button-only regions confuse expectations.
* **`aria-current` on the wrong node** — Put it on the link or the current crumb, consistently.
* **Skip link missing** — Pages with large navs should offer “Skip to content” to `<main>`.
* **Focus trap bugs** — Mobile overlays must return focus and allow Escape.

## 🔗 Related [#-related]

* [List](/docs/html/list) — `ul`/`ol` patterns for menus
* [Footer](/docs/html/footer) — secondary nav in footers
* [Section](/docs/html/section) — TOC within articles
* [Div](/docs/html/div) — layout wrappers around nav
* [Language](/docs/html/language) — language switchers
* [URL](/docs/html/url) — link targets and fragments


---

# Picture & Source (/docs/html/picture-source)



# Picture & Source [#picture--source]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`<picture>` wraps `<source>` elements and an `<img>` fallback for **art direction** (different crops/files per condition) and format negotiation (AVIF/WebP). The browser picks the first matching `<source>`, then loads via the `<img>` for intrinsic size, `alt`, and decoding behavior.

## 🔧 Core concepts [#-core-concepts]

* **Structure**: `<picture>` → zero+ `<source>` → required `<img>`.
* **`media`**: art direction queries on `<source>`.
* **`type`**: MIME type for format selection.
* **`srcset` / `sizes`**: on `<source>` or `<img>` for resolution switching.
* **Final `<img>`**: provides `alt`, `width`/`height`, `loading`, and fallback `src`.
* Not a replacement for CSS `display` — it selects which resource loads.

```html
<picture>
  <source type="image/avif" srcset="/hero.avif" />
  <source type="image/webp" srcset="/hero.webp" />
  <img src="/hero.jpg" alt="Product on a desk" width="1600" height="900" />
</picture>
```

## 💡 Examples [#-examples]

```html
<!-- Art direction -->
<picture>
  <source
    media="(max-width: 600px)"
    srcset="/hero-mobile.jpg"
    width="800"
    height="1200"
  />
  <source media="(min-width: 601px)" srcset="/hero-desktop.jpg" />
  <img
    src="/hero-desktop.jpg"
    alt="Wide shot of the storefront"
    width="1600"
    height="900"
    fetchpriority="high"
  />
</picture>

<!-- Format + responsive widths -->
<picture>
  <source
    type="image/avif"
    srcset="/p-400.avif 400w, /p-800.avif 800w"
    sizes="(max-width: 700px) 100vw, 700px"
  />
  <source
    type="image/webp"
    srcset="/p-400.webp 400w, /p-800.webp 800w"
    sizes="(max-width: 700px) 100vw, 700px"
  />
  <img
    src="/p-800.jpg"
    srcset="/p-400.jpg 400w, /p-800.jpg 800w"
    sizes="(max-width: 700px) 100vw, 700px"
    alt="Red sneakers"
    width="800"
    height="800"
    loading="lazy"
  />
</picture>

<!-- Dark mode asset -->
<picture>
  <source srcset="/logo-dark.svg" media="(prefers-color-scheme: dark)" />
  <img src="/logo-light.svg" alt="Acme" width="120" height="32" />
</picture>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Omitting `<img>` is invalid — always include it with `alt`.
* `media` on sources is for art direction; don’t confuse with CSS-only hiding of a single image.
* First matching source wins — order matters (narrow media / preferred types first as designed).
* Width/height on sources help but layout stability still depends on the chosen image’s dimensions.
* Overusing many huge variants wastes storage — keep a sensible set.

## 🔗 Related [#-related]

* [images.md](/docs/html/images) — img basics
* [video\_audio.md](/docs/html/video-audio) — media sources
* [media.md](/docs/html/media) — media overview
* [../CSS/object\_fit.md](/docs/html/../css/object-fit) — cropping via CSS
* [../CSS/dark\_mode.md](/docs/html/../css/dark-mode) — theme assets


---

# Script (/docs/html/script)



# Script [#script]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<script>` element embeds or loads JavaScript (and other script types). Scripts can be classic or module (`type="module"`), blocking or deferred, inline or external. Modern best practice: load modules or classic scripts with `defer` from `<head>`, keep progressive enhancement in mind, and respect Content Security Policy.

Scripts run with the page’s origin privileges—treat URLs, integrity, and user-generated inline script with care.

## 🔧 Core concepts [#-core-concepts]

### Loading modes [#loading-modes]

| Pattern                            | Behavior                                                              |
| ---------------------------------- | --------------------------------------------------------------------- |
| `<script src>` (classic, no attrs) | Fetch + execute immediately; blocks parsing                           |
| `async`                            | Download in parallel; execute as soon as ready (order not guaranteed) |
| `defer`                            | Download in parallel; execute after document parse, in order          |
| `type="module"`                    | Deferred by default; strict mode; unique imports                      |
| Inline script                      | Executes when parsed (modules still deferred)                         |

```html
<script src="/app.js" defer></script>
<script type="module" src="/main.js"></script>
```

### Important attributes [#important-attributes]

* `src` — external URL
* `type` — `module`, `importmap`, MIME for data blocks, or default JS
* `nomodule` — fallback for non-module browsers
* `crossorigin` — CORS for error reporting / modules
* `integrity` — Subresource Integrity (SRI) hash
* `referrerpolicy` — referrer for the request
* `blocking="render"` — rare; opt into render-blocking (use carefully)
* `fetchpriority` — hint for the script request

### Modules vs classic [#modules-vs-classic]

ES modules support `import`/`export`, run once per URL, and default to CORS for cross-origin. Classic scripts share a global scope and duplicate if included twice.

```html
<script type="importmap">
{
  "imports": {
    "lodash/": "https://cdn.example.com/lodash/"
  }
}
</script>
```

### Placement [#placement]

* **Head + defer/module** — preferred for apps.
* **End of body** — legacy pattern for classic scripts without defer.
* **Inline critical** — tiny bootstraps only; prefer external for cacheability.

### Accessibility and UX [#accessibility-and-ux]

Scripts should not be the only way to submit forms or follow links. Provide noscript fallbacks when core content depends on JS:

```html
<noscript>
  <p>This app needs JavaScript. View the <a href="/static">static docs</a>.</p>
</noscript>
```

## 💡 Examples [#-examples]

### Deferred classic + module [#deferred-classic--module]

```html
<head>
  <script src="/legacy-analytics.js" defer></script>
  <script type="module" src="/app.js"></script>
  <script nomodule src="/fallback.js"></script>
</head>
```

### SRI for CDN script [#sri-for-cdn-script]

```html
<script
  src="https://cdn.example.com/lib@1.2.3/lib.min.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
  crossorigin="anonymous"
  defer></script>
```

### Inline module [#inline-module]

```html
<script type="module">
  import { init } from "/js/init.js";
  init(document.getElementById("app"));
</script>
```

### JSON data island (non-JS type) [#json-data-island-non-js-type]

```html
<script id="config" type="application/json">
  { "apiBase": "/api", "featureFlags": { "newNav": true } }
</script>
<script type="module">
  const config = JSON.parse(document.getElementById("config").textContent);
</script>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Parser-blocking scripts** — Large classic scripts in head without `defer` delay First Paint.
* **`async` order** — Dependent files may run out of order; use `defer` or modules.
* **Duplicate globals** — Including the same classic library twice causes bugs.
* **Inline without CSP nonces** — Strict CSP blocks inline scripts; use nonces/hashes or external files.
* **`document.write`** — Destroys performance; avoid.
* **Assuming DOM ready** — Module/defer run after parse; classic without defer may need `DOMContentLoaded`.
* **Untrusted `innerHTML` + script** — XSS risk; sanitize and avoid injecting markup with handlers.

## 🔗 Related [#-related]

* [Head](/docs/html/head) — where to place scripts
* [Src](/docs/html/src) — resolving script URLs
* [URL](/docs/html/url) — CDN and absolute paths
* [Meta](/docs/html/meta) — CSP meta vs headers
* [Form](/docs/html/form) — progressive enhancement of forms
* [Canvas](/docs/html/canvas) — scripts that draw
* [Style](/docs/html/style) — FOUC and load ordering with CSS


---

# Section (/docs/html/section)



# Section [#section]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<section>` element represents a **thematic grouping** of content, typically with a heading. It is sectioning content: it appears in the document outline and can own its own `<header>` / `<footer>`. Use it when the block is a meaningful chunk of the page—not as a generic styling wrapper (that is `<div>`).

HTML5 also provides `<article>`, `<aside>`, `<nav>`, and `<main>` for more specific roles. Choose the most precise element; fall back to `<section>` for titled thematic groups, and `<div>` when there is no semantics to express.

## 🔧 Core concepts [#-core-concepts]

### Section vs related elements [#section-vs-related-elements]

| Element     | Use when                                                                 |
| ----------- | ------------------------------------------------------------------------ |
| `<section>` | Thematic group that belongs in the outline, usually with heading         |
| `<article>` | Self-contained composition (post, card, widget) distributable on its own |
| `<aside>`   | Tangentially related (pull quote, ads, secondary nav)                    |
| `<main>`    | Dominant unique content of the document (one per page)                   |
| `<div>`     | Purely presentational / script hook                                      |

### Headings and outline [#headings-and-outline]

Every section should ideally have a heading (`h1`–`h6` or `hgroup` patterns). Nesting sections raises the logical rank in outline algorithms; in practice, authors still assign explicit heading levels carefully for accessibility.

```html
<main>
  <h1>HTML landmarks</h1>
  <section aria-labelledby="nav-sec">
    <h2 id="nav-sec">Navigation</h2>
    <p>…</p>
  </section>
  <section aria-labelledby="form-sec">
    <h2 id="form-sec">Forms</h2>
    <p>…</p>
  </section>
</main>
```

### Accessibility [#accessibility]

* `<section>` without an accessible name is **not** a landmark in most browsers.
* With `aria-label` / `aria-labelledby` (often pointing at the heading), it becomes a `region` landmark.
* Do not create dozens of named regions—reserve for major chunks.
* Prefer one `<main>`; put sections inside it.

### Headers and footers inside [#headers-and-footers-inside]

```html
<section>
  <header>
    <h2>Release notes</h2>
    <p>Version 2.4</p>
  </header>
  <p>…</p>
  <footer>
    <p>Last updated <time datetime="2026-07-10">July 10</time></p>
  </footer>
</section>
```

## 💡 Examples [#-examples]

### Article composed of sections [#article-composed-of-sections]

```html
<article>
  <h1>Using section wisely</h1>
  <section>
    <h2>When to use it</h2>
    <p>Group related content under a shared theme.</p>
  </section>
  <section>
    <h2>When to avoid it</h2>
    <p>Do not wrap every heading for CSS convenience.</p>
  </section>
</article>
```

### Named region landmark [#named-region-landmark]

```html
<section aria-labelledby="newsletter-heading">
  <h2 id="newsletter-heading">Newsletter</h2>
  <form action="/subscribe" method="post">…</form>
</section>
```

### FAQ pattern [#faq-pattern]

```html
<section aria-labelledby="faq">
  <h2 id="faq">FAQ</h2>
  <div>
    <h3>Is section a landmark?</h3>
    <p>Only when it has an accessible name.</p>
  </div>
  <div>
    <h3>Can I nest sections?</h3>
    <p>Yes—reflect real hierarchy.</p>
  </div>
</section>
```

### Avoid: section as layout shell [#avoid-section-as-layout-shell]

```html
<!-- Prefer div for grid shells without meaning -->
<div class="layout-grid">
  <main>…</main>
  <aside>…</aside>
</div>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Section soup** — Replacing all divs with sections adds noise and false outline entries.
* **Headingless sections** — Weak semantics; add a heading or use a div.
* **Multiple mains** — Invalid pattern; sections do not replace `main`.
* **Skipping heading levels** — Jumping `h2` → `h4` confuses AT users.
* **Over-labeling regions** — Too many landmarks slow navigation.
* **Confusing article vs section** — If it could stand alone in a feed, prefer `article`.

## 🔗 Related [#-related]

* [Div](/docs/html/div) — non-semantic containers
* [Nav](/docs/html/nav) — navigation sections
* [Footer](/docs/html/footer) — section and page footers
* [Form](/docs/html/form) — forms inside sections
* [List](/docs/html/list) — TOC lists for long sections
* [Language](/docs/html/language) — `lang` on a section
* [Style](/docs/html/style) — styling section layouts


---

# Semantic HTML (/docs/html/semantic)



# Semantic HTML [#semantic-html]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Semantic elements describe meaning: headings, landmarks, lists, figures, and text-level semantics. They improve accessibility, SEO, and readability without CSS. Prefer native elements over generic `<div>`/`<span>` when a matching semantic tag exists.

## 🔧 Core concepts [#-core-concepts]

| Element                                                    | Meaning                  |
| ---------------------------------------------------------- | ------------------------ |
| `header` `footer` `main` `nav` `aside` `section` `article` | landmarks / sections     |
| `h1`–`h6`                                                  | heading outline          |
| `p` `ul` `ol` `dl`                                         | text structure           |
| `figure` `figcaption`                                      | media with caption       |
| `blockquote` `cite` `q`                                    | quotations               |
| `time` `address` `mark` `strong` `em`                      | inline semantics         |
| `search`                                                   | search landmark (modern) |

* One primary `<main>` per document.
* `section` needs a heading; `article` is independently distributable content.
* Don’t skip heading levels arbitrarily.

```html
<body>
  <header>...</header>
  <nav aria-label="Primary">...</nav>
  <main>
    <article>
      <h1>Title</h1>
      <p>...</p>
    </article>
  </main>
  <footer>...</footer>
</body>
```

## 💡 Examples [#-examples]

```html
<article>
  <header>
    <h1>Release notes</h1>
    <p><time datetime="2026-07-10">July 10, 2026</time></p>
  </header>
  <section aria-labelledby="feat">
    <h2 id="feat">Features</h2>
    <ul>
      <li>Faster builds</li>
    </ul>
  </section>
  <figure>
    <img src="/chart.svg" alt="Build time chart falling from 12s to 4s" />
    <figcaption>Median build time by week</figcaption>
  </figure>
</article>

<aside aria-labelledby="tips">
  <h2 id="tips">Tips</h2>
  <p>...</p>
</aside>

<!-- Text emphasis -->
<p><strong>Warning:</strong> <em>destructive</em> action.</p>
```

```html
<!-- Prefer -->
<nav>...</nav>
<!-- Over -->
<div class="nav">...</div>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Using only `<div>` soup forces ARIA to reinvent semantics poorly.
* Multiple `<h1>` can be OK in some outlines but keep a clear hierarchy.
* `section` without headings is usually a glorified div.
* `strong` ≠ bold CSS; `em` ≠ italic CSS — meaning first, style second.
* Landmark overuse (`nav` everywhere) adds noise — label distinct navs.

## 🔗 Related [#-related]

* [section.md](/docs/html/section) — sections
* [nav.md](/docs/html/nav) — navigation
* [footer.md](/docs/html/footer) — footer
* [accessibility.md](/docs/html/accessibility) — a11y
* [aria.md](/docs/html/aria) — when HTML isn’t enough


---

# Src (/docs/html/src)



# Src [#src]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The **`src` attribute** (and relatives `srcset`, `data`, `href` for some resources) tells the browser where to fetch an embedded resource: scripts, images, frames, tracks, and media sources. Understanding URL resolution, CORS, and responsive image candidates prevents broken assets and layout shift.

`src` always holds a single URL. For responsive images, combine `src` (fallback) with `srcset` and `sizes`. For `<video>` / `<audio>`, child `<source src>` elements provide format alternatives.

## 🔧 Core concepts [#-core-concepts]

### Elements that use `src` [#elements-that-use-src]

| Element                | Resource                  |
| ---------------------- | ------------------------- |
| `<img>`                | Image                     |
| `<script>`             | JavaScript                |
| `<iframe>`             | Nested browsing context   |
| `<audio>` / `<video>`  | Media (or use `<source>`) |
| `<source>`             | Media/picture candidate   |
| `<track>`              | Text track (WebVTT)       |
| `<embed>`              | External plug-in content  |
| `<input type="image">` | Submit button image       |

Related: `<link href>` for stylesheets/icons; `<a href>` for navigation—not `src`.

### URL resolution [#url-resolution]

Relative `src` values resolve against the document URL, or against `<base href>` if present.

```html
<!-- Document: https://example.com/docs/html/ -->
<img src="images/logo.png" alt="Logo">
<!-- → https://example.com/docs/html/images/logo.png -->

<img src="/images/logo.png" alt="Logo">
<!-- → https://example.com/images/logo.png -->
```

Protocols: `https:` preferred; `data:` for small embeds; `blob:` for generated objects; avoid mixed content (`http` on `https` pages).

### Srcset syntax [#srcset-syntax]

```html
<img
  src="hero-800.jpg"
  srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
  sizes="(max-width: 700px) 100vw, 700px"
  alt="Hero">
```

* **Width descriptors** (`400w`) — with `sizes`, browser picks density-appropriate file.
* **Pixel density** (`logo.png 1x, logo@2x.png 2x`) — for fixed-size images.
* `src` remains the fallback / default.

### CORS and credentials [#cors-and-credentials]

Cross-origin images can display without CORS but **taint canvas**. Scripts and fonts need proper CORS. Use `crossorigin` on `<img>` / `<script>` / `<link>` when you need access to pixel data or better error info.

```html
<img src="https://cdn.example.com/pic.jpg" alt="" crossorigin="anonymous">
```

### Integrity [#integrity]

Pair `src` with `integrity` (SRI) on scripts and stylesheets to ensure bytes match an expected hash.

## 💡 Examples [#-examples]

### Image with dimensions and lazy load [#image-with-dimensions-and-lazy-load]

```html
<img
  src="/media/team.jpg"
  alt="Engineering team at the whiteboard"
  width="640"
  height="480"
  loading="lazy"
  decoding="async">
```

### Video sources [#video-sources]

```html
<video controls poster="/media/poster.jpg">
  <source src="/media/talk.webm" type="video/webm">
  <source src="/media/talk.mp4" type="video/mp4">
</video>
```

### Script module URL [#script-module-url]

```html
<script type="module" src="/assets/js/main.js"></script>
```

### Picture format negotiation [#picture-format-negotiation]

```html
<picture>
  <source srcset="/img/hero.avif" type="image/avif">
  <source srcset="/img/hero.webp" type="image/webp">
  <img src="/img/hero.jpg" alt="Forest path in fog">
</picture>
```

### Blob URL from script [#blob-url-from-script]

```html
<script type="module">
  const blob = new Blob(["print('hi')"], { type: "text/python" });
  const url = URL.createObjectURL(blob);
  // revoke when done: URL.revokeObjectURL(url);
</script>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Broken relative paths** — Moving pages without fixing assets 404s; prefer root-absolute `/…` for app-wide assets.
* **`<base>` side effects** — Changes every relative `src` and `href`.
* **Missing `src` on img** — Invalid; empty images still need intentional handling.
* **Srcset without sizes** — Browser may assume `100vw` and over-download.
* **Hotlinking** — Unreliable and often blocked; host or contract CDNs.
* **Mixed content** — Active mixed content blocked; passive images may warn.
* **Forgetting revoke** — Blob URLs leak memory until `revokeObjectURL`.

## 🔗 Related [#-related]

* [Media](/docs/html/media) — images, audio, video elements
* [URL](/docs/html/url) — URL anatomy and encoding
* [Script](/docs/html/script) — script loading attributes
* [Canvas](/docs/html/canvas) — CORS-tainted images
* [Head](/docs/html/head) — `<base>` and resource hints
* [Style](/docs/html/style) — CSS `url()` vs HTML `src`


---

# Style (/docs/html/style)



# Style [#style]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Styling HTML happens through the **CSS cascade**: external stylesheets (`<link rel="stylesheet">`), document-level `<style>` elements, and inline `style` attributes. Prefer external or scoped document CSS for maintainability; use inline styles sparingly for dynamic values. The HTML `style` attribute applies declarations to one element with high specificity.

Separating structure (HTML) from presentation (CSS) improves accessibility, caching, and theming. Never use styling alone to convey meaning that belongs in semantics or text.

## 🔧 Core concepts [#-core-concepts]

### Three authoring layers [#three-authoring-layers]

```html
<head>
  <link rel="stylesheet" href="/styles.css">
  <style>
    :root { color-scheme: light dark; }
    .callout { border-inline-start: 4px solid #0f766e; }
  </style>
</head>
<body>
  <p style="margin-block: 0">Inline exception</p>
</body>
```

| Layer        | Pros                           | Cons                                           |
| ------------ | ------------------------------ | ---------------------------------------------- |
| External CSS | Cacheable, shareable           | Extra request (mitigate with HTTP/2, bundling) |
| `<style>`    | Critical CSS, no round trip    | Not shared across pages unless duplicated      |
| `style=""`   | Quick overrides, JS-set values | Hard to maintain; high specificity             |

### The `style` attribute [#the-style-attribute]

* Contains CSS declarations, not selectors.
* Specificity equals one inline declaration (beats classes unless `!important` wars).
* Cannot express pseudo-elements (`::before`) or media queries—use a stylesheet.
* Reflects in `element.style`; CSSOM `cssText` updates it.

### `<style>` element attributes [#style-element-attributes]

* `media` — conditional application (`media="(min-width: 48rem)"`).
* `blocking="render"` — opt into render-blocking (default for classic stylesheets in head).
* `nonce` / CSP hashes — allow inline under strict CSP.
* `title` — alternate stylesheets (with `<link rel="stylesheet" title>`).

### Cascade and importance (simplified) [#cascade-and-importance-simplified]

1. Origin & importance (user agent \< user \< author; `!important` reverses layers carefully)
2. Specificity (`inline` > IDs > classes/attributes > elements)
3. Order (later wins when equal)

### Accessibility of presentation [#accessibility-of-presentation]

* Do not rely on color alone.
* Preserve focus visibility.
* Respect `prefers-reduced-motion` and `prefers-color-scheme`.
* Maintain contrast (WCAG).
* Keep hit targets large enough.

## 💡 Examples [#-examples]

### Critical CSS in head [#critical-css-in-head]

```html
<head>
  <style>
    body { margin: 0; font-family: system-ui, sans-serif; }
    .hero { min-height: 60vh; }
  </style>
  <link rel="stylesheet" href="/full.css">
</head>
```

### Media-specific style block [#media-specific-style-block]

```html
<style media="print">
  nav, .no-print { display: none; }
  a[href]::after { content: " (" attr(href) ")"; }
</style>
```

### Theming with custom properties [#theming-with-custom-properties]

```html
<style>
  :root {
    --bg: #f8fafc;
    --fg: #0f172a;
    --accent: #0f766e;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --bg: #0f172a;
      --fg: #f8fafc;
    }
  }
  body {
    background: var(--bg);
    color: var(--fg);
  }
</style>
```

### Dynamic inline style from script [#dynamic-inline-style-from-script]

```html
<div id="bar" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100">
  <span class="fill"></span>
</div>
<script type="module">
  const fill = document.querySelector("#bar .fill");
  fill.style.width = "40%";
  fill.style.background = "var(--accent)";
</script>
```

## ⚠️ Pitfalls [#️-pitfalls]

* **Inline everything** — Unmaintainable; breaks theming and CSP ease.
* **`!important` sprawl** — Sign of specificity fights; refactor selectors.
* **Removing focus outlines** — Provide `:focus-visible` alternatives.
* **Using CSS for content** — Important text in `content:` may be missed by AT/translators.
* **FOUC** — Late stylesheets flash unstyled content; order and preload carefully.
* **Mixing presentational HTML** — `<font>`, `align`, `bgcolor` are obsolete; use CSS.
* **Huge style tags** — Defeat caching; extract to files for multi-page sites.

## 🔗 Related [#-related]

* [Head](/docs/html/head) — linking stylesheets
* [Div](/docs/html/div) — layout hooks for CSS
* [Script](/docs/html/script) — load order with JS
* [Meta](/docs/html/meta) — `color-scheme`, theme-color
* [Media](/docs/html/media) — styling images/video (`object-fit`)
* [Canvas](/docs/html/canvas) — CSS size vs bitmap size
* [Section](/docs/html/section) — styling landmarks


---

# Inline SVG (/docs/html/svg-inline)



# Inline SVG [#inline-svg]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Inline SVG embeds vector graphics directly in HTML for crisp icons, illustrations, and charts. You can style with CSS, animate, and expose titles for accessibility. Prefer `<img src="*.svg">` or `<use>` sprites when you don’t need per-path styling.

## 🔧 Core concepts [#-core-concepts]

* **Root**: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">`.
* **`viewBox`**: coordinate system; scales independently of `width`/`height`.
* **Shapes**: `path` `rect` `circle` `line` `polyline` `polygon` `text` `g`.
* **CSS**: `fill`, `stroke`, `currentColor` for themeable icons.
* **A11y**: decorative → `aria-hidden="true"`; meaningful → `<title>` + `role="img"` / `aria-label`.
* **Sprites**: `<use href="/icons.svg#check">` (external `use` has CORS limits).

```html
<svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
  <path fill="currentColor" d="M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" />
</svg>
```

## 💡 Examples [#-examples]

```html
<!-- Meaningful graphic -->
<svg role="img" aria-labelledby="salesTitle" viewBox="0 0 100 40" width="300">
  <title id="salesTitle">Sales rising from 10 to 40</title>
  <polyline
    fill="none"
    stroke="currentColor"
    stroke-width="3"
    points="0,30 30,22 60,18 100,5"
  />
</svg>

<!-- Icon button -->
<button type="button" aria-label="Settings">
  <svg aria-hidden="true" focusable="false" viewBox="0 0 24 24" width="20" height="20">
    <path fill="currentColor" d="..." />
  </svg>
</button>

<!-- Style -->
<style>
  .icon {
    width: 1.25rem;
    height: 1.25rem;
    display: block;
  }
  .icon-danger {
    color: crimson;
  }
</style>

<!-- Sprite use -->
<svg class="icon" aria-hidden="true" focusable="false">
  <use href="/sprite.svg#arrow" />
</svg>
```

```html
<!-- Prefer currentColor over hardcoded fills for theming -->
```

## ⚠️ Pitfalls [#️-pitfalls]

* Huge inline SVGs bloat HTML — externalize complex art.
* Missing `viewBox` breaks scaling.
* Interactive SVG needs keyboard support if it acts like a control — wrap in `button`/`a` instead.
* `focusable="false"` helps older IE/Edge; still set `aria-hidden` on decorative icons.
* XSS: never inline unsanitized SVG from users (`<script>`, event handlers).

## 🔗 Related [#-related]

* [images.md](/docs/html/images) — raster images
* [canvas.md](/docs/html/canvas) — canvas alternative
* [accessibility.md](/docs/html/accessibility) — graphics a11y
* [../CSS/icon.md](/docs/html/../css/icon) — icon CSS
* [embedding.md](/docs/html/embedding) — object/embed


---

# Table (/docs/html/table)



# Table [#table]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The `<table>` element represents **tabular data**—information arranged in rows and columns. Use tables for data relationships, not for page layout (CSS Grid/Flexbox replaced that anti-pattern). Accessible tables need captions, clear headers, and `scope` (or explicit `headers` IDs) so assistive technologies can announce cell context.

Core pieces: `<table>`, `<caption>`, `<thead>`, `<tbody>`, `<tfoot>`, `<tr>`, `<th>`, `<td>`, plus `<colgroup>` / `<col>` for column styling.

## 🔧 Core concepts [#-core-concepts]

### Basic structure [#basic-structure]

```html
<table>
  <caption>Quarterly revenue (USD thousands)</caption>
  <thead>
    <tr>
      <th scope="col">Quarter</th>
      <th scope="col">Revenue</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Q1</th>
      <td>40</td>
    </tr>
    <tr>
      <th scope="row">Q2</th>
      <td>55</td>
    </tr>
  </tbody>
</table>
```

### Header cells and scope [#header-cells-and-scope]

| `scope`    | Meaning                   |
| ---------- | ------------------------- |
| `col`      | Header for the column     |
| `row`      | Header for the row        |
| `colgroup` | Header for a column group |
| `rowgroup` | Header for a row group    |

Complex tables may use `headers="id1 id2"` on `<td>` pointing to `id`s on `<th>`.

### Sections [#sections]

* `<thead>` — column labels (can repeat when printing).
* `<tbody>` — main data (multiple allowed).
* `<tfoot>` — summaries; may appear before `tbody` in markup for streaming, still rendered at bottom in some cases—follow current HTML guidance and test.

### Spanning [#spanning]

* `colspan` — extend across columns
* `rowspan` — extend across rows\
  Keep spans minimal; they complicate a11y and responsive redesigns.

### When not to use tables [#when-not-to-use-tables]

Layout grids, email-only legacy layouts (sometimes unavoidable), and simple key/value pairs (consider `<dl>`) should not force data-table semantics.

## 💡 Examples [#-examples]

### Table with footer totals [#table-with-footer-totals]

```html
<table>
  <caption>Hardware inventory</caption>
  <thead>
    <tr>
      <th scope="col">Item</th>
      <th scope="col">Qty</th>
      <th scope="col">Unit price</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Keyboard</th>
      <td>12</td>
      <td>40</td>
    </tr>
    <tr>
      <th scope="row">Mouse</th>
      <td>20</td>
      <td>25</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th scope="row">Total units</th>
      <td colspan="2">32</td>
    </tr>
  </tfoot>
</table>
```

### Irregular headers with `headers` [#irregular-headers-with-headers]

```html
<table>
  <caption>Exam scores</caption>
  <tr>
    <td></td>
    <th id="mid" scope="col">Midterm</th>
    <th id="fin" scope="col">Final</th>
  </tr>
  <tr>
    <th id="ada" scope="row">Ada</th>
    <td headers="ada mid">92</td>
    <td headers="ada fin">88</td>
  </tr>
</table>
```

### Scrollable responsive wrapper [#scrollable-responsive-wrapper]

```html
<div class="table-scroll" tabindex="0" role="region" aria-label="Revenue table">
  <table>…</table>
</div>
```

```css
.table-scroll { overflow-x: auto; max-width: 100%; }
```

### Sortable header button (progressive) [#sortable-header-button-progressive]

```html
<th scope="col">
  <button type="button" aria-label="Sort by name ascending">
    Name
  </button>
</th>
```

Keep the `<th>` semantics; enhance with script without replacing the table with divs.

## ⚠️ Pitfalls [#️-pitfalls]

* **Layout tables** — Break reflow, reading order, and CSS flexibility.
* **Missing caption / headers** — Screen readers announce raw grids without context.
* **Only bold text as headers** — Use `<th>`, not styled `<td>`.
* **Empty header cells** — Provide meaningful labels or `abbr`.
* **Too many spans** — Hard to navigate linearly.
* **Clickable rows without keyboard support** — Prefer links/buttons inside cells.
* **CSS `display` changes** — Altering table `display` can destroy a11y mappings in some browsers—test.

## 🔗 Related [#-related]

* [List](/docs/html/list) — alternative for non-tabular sets
* [Section](/docs/html/section) — wrapping data sections
* [Div](/docs/html/div) — scroll wrappers
* [Form](/docs/html/form) — inputs inside table cells
* [Input](/docs/html/input) — editable grids
* [Canvas](/docs/html/canvas) — charts vs data tables (provide both)
* [Style](/docs/html/style) — table layout CSS


---

# Template & Slot (/docs/html/template-slot)



# Template & Slot [#template--slot]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`<template>` holds inert DOM that isn’t rendered until cloned with script. `<slot>` (inside Shadow DOM) projects light-DOM children into shadow trees. Together they power Web Components and client-side rendering patterns without displaying markup prematurely.

## 🔧 Core concepts [#-core-concepts]

* **`<template>`**: `template.content` is a `DocumentFragment`; clone with `cloneNode(true)`.
* **Inert**: scripts/styles/images inside don’t run until adopted into a live document.
* **`<slot>`**: placeholder in shadow root; default content inside slot shows if nothing assigned.
* **Named slots**: `<slot name="title">` ↔ `slot="title"` on light children.
* **Assignment**: automatic or `slotAssignment: "manual"` + `slot.assign()`.
* **`slotchange` event**: fires when assigned nodes change.

```html
<template id="row">
  <li class="row"><span class="name"></span></li>
</template>

<script>
  const tpl = document.getElementById("row");
  const node = tpl.content.cloneNode(true);
  node.querySelector(".name").textContent = "Ada";
  list.append(node);
</script>
```

## 💡 Examples [#-examples]

```html
<!-- Component with slots -->
<script>
  class UserCard extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: "open" }).innerHTML = `
        <style>::slotted(img){width:48px;border-radius:50%}</style>
        <slot name="avatar"></slot>
        <h2><slot name="name">Anonymous</slot></h2>
        <div><slot></slot></div>
      `;
    }
  }
  customElements.define("user-card", UserCard);
</script>

<user-card>
  <img slot="avatar" src="/a.jpg" alt="" />
  <span slot="name">Ada Lovelace</span>
  <p>Mathematician</p>
</user-card>

<!-- Manual assignment -->
<script>
  const shadow = host.attachShadow({ mode: "open", slotAssignment: "manual" });
  shadow.innerHTML = `<slot></slot>`;
  shadow.querySelector("slot").assign(...host.children);
</script>

<!-- slotchange -->
<script>
  shadow.querySelector("slot").addEventListener("slotchange", (e) => {
    console.log(e.target.assignedNodes());
  });
</script>
```

```html
<!-- Clone for each list item; never append template.content directly -->
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting `cloneNode(true)` and moving `template.content` empties the template after first use — always clone.
* Slots only work in Shadow DOM — not in light DOM alone.
* Fallback slot content is not light DOM — don’t expect to query it as children of the host.
* Scripts inside live-cloned templates will run — sanitize untrusted HTML.
* Named slot mismatch leaves content unprojected (still in light DOM).

## 🔗 Related [#-related]

* [web\_components.md](/docs/html/web-components) — full stack
* [../Javascript/DOM/shadow\_dom.md](/docs/html/../javascript/dom/shadow-dom) — shadow trees
* [../Javascript/DOM/custom\_elements.md](/docs/html/../javascript/dom/custom-elements) — custom elements
* [script.md](/docs/html/script) — script loading
* [semantic.md](/docs/html/semantic) — light DOM structure


---

# URL (/docs/html/url)



# URL [#url]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

URLs (Uniform Resource Locators) identify resources in HTML attributes such as `href`, `src`, `action`, and `cite`. Authors work with absolute URLs, root-relative paths, document-relative paths, and special schemes (`mailto:`, `tel:`, `data:`, `blob:`). Correct encoding, HTTPS, and stable canonical URLs matter for security, SEO, and broken-link prevention.

The browser resolves relative references against the active document base URL (affected by `<base>`).

## 🔧 Core concepts [#-core-concepts]

### Anatomy [#anatomy]

```
https://user:pass@example.com:443/path/to/page?query=1#fragment
\___/   \_______/ \_________/ \__/ \_________/ \_____/ \______/
scheme  userinfo   host       port  path        query   fragment
```

In modern web apps, prefer HTTPS, avoid embedding credentials in URLs, and keep fragments client-side only (not sent to servers).

### Forms used in HTML [#forms-used-in-html]

| Form              | Example                        | Resolves to                                       |
| ----------------- | ------------------------------ | ------------------------------------------------- |
| Absolute          | `https://cdn.example.com/a.js` | As written                                        |
| Root-relative     | `/images/logo.png`             | Origin + path                                     |
| Document-relative | `../assets/app.css`            | Relative to current URL path                      |
| Protocol-relative | `//cdn.example.com/x`          | Inherit current scheme (avoid; prefer `https://`) |
| Same-document     | `#section`                     | Fragment only                                     |
| Special           | `mailto:hi@ex.com`             | Handled by OS/UA                                  |

### Encoding [#encoding]

* Encode spaces and reserved characters in paths/queries (`encodeURIComponent` for components).
* Use `%20` or `+` in query strings per server expectations.
* Internationalized domains use Punycode; paths may be Unicode but encoding is safer for interoperability.

### HTML attributes that take URLs [#html-attributes-that-take-urls]

* Navigation: `a.href`, `area.href`, `base.href`, `link.href`
* Resources: `img.src`, `script.src`, `iframe.src`, `source.src`, `track.src`
* Forms: `form.action`
* Misc: `blockquote.cite`, `q.cite`, `html.manifest` (obsolete)

### Canonicalization and SEO [#canonicalization-and-seo]

```html
<link rel="canonical" href="https://example.com/docs/url">
```

Pick one preferred host (`www` vs apex), trailing-slash policy, and HTTPS redirect chain. Pair with `hreflang` alternates when localized.

## 💡 Examples [#-examples]

### Relative vs absolute in links [#relative-vs-absolute-in-links]

```html
<nav>
  <a href="/">Home</a>
  <a href="/docs/html/forms">Forms</a>
  <a href="https://developer.mozilla.org/">MDN</a>
  <a href="#pitfalls">On this page</a>
</nav>
```

### Form GET builds a query URL [#form-get-builds-a-query-url]

```html
<form action="/search" method="get">
  <label for="q">Search</label>
  <input id="q" name="q" type="search" value="semantic html">
  <button type="submit">Go</button>
</form>
<!-- Submits to /search?q=semantic+html -->
```

### Safe external link pattern [#safe-external-link-pattern]

```html
<a href="https://example.com/partner"
   rel="noopener noreferrer"
   target="_blank">
  Partner site
</a>
```

`noopener` protects `window.opener`; `noreferrer` also omits referrer (trade-offs for analytics).

### Data and blob URLs [#data-and-blob-urls]

```html
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3C/%3E" alt="">
```

Prefer files for large assets; data URLs bloat HTML and cache poorly.

## ⚠️ Pitfalls [#️-pitfalls]

* **Broken relative links** after moving pages—root-relative paths are stabler for apps.
* **`<base href>`** rewriting every relative URL unexpectedly.
* **Open redirects** — never bounce users to unchecked query params.
* **Credentials in URLs** — leak via history, logs, and Referer.
* **Mixed content** — HTTP resources on HTTPS pages fail or warn.
* **Unescaped `&` in query strings within HTML** — write `&amp;` in HTML attributes.
* **Assuming fragments reach the server** — they do not on normal navigations.

## 🔗 Related [#-related]

* [Src](/docs/html/src) — resource URL attributes
* [Head](/docs/html/head) — canonical and base
* [Form](/docs/html/form) — `action` and method
* [Media](/docs/html/media) — media resource URLs
* [Nav](/docs/html/nav) — in-site link patterns
* [Language](/docs/html/language) — locale in paths / hreflang
* [Meta](/docs/html/meta) — OG URLs
* [XML](/docs/html/xml) — XML Base / namespaces


---

# Video & Audio (/docs/html/video-audio)



# Video & Audio [#video--audio]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`<video>` and `<audio>` embed media with native controls, multiple `<source>` fallbacks, tracks for captions, and a rich DOM API. Prefer native elements for accessibility and performance; use `controls`, captions, and sensible preload defaults.

## 🔧 Core concepts [#-core-concepts]

| Attribute                    | Role                     |
| ---------------------------- | ------------------------ |
| `src` / `<source>`           | media URL(s)             |
| `controls`                   | show UA controls         |
| `autoplay`                   | may play muted only      |
| `muted` `loop` `playsinline` | playback flags           |
| `preload`                    | `none` `metadata` `auto` |
| `poster`                     | video placeholder image  |
| `width` `height`             | video layout             |
| `crossorigin`                | CORS for WebGL/canvas    |

* **Tracks**: `<track kind="captions" srclang="en" src="..." default>`.
* **API**: `play()`, `pause()`, `currentTime`, `volume`, events `play` `pause` `ended` `error`.
* **Formats**: provide multiple sources (e.g. MP4 + WebM) when needed.

```html
<video controls playsinline poster="/poster.jpg" width="1280" height="720">
  <source src="/demo.webm" type="video/webm" />
  <source src="/demo.mp4" type="video/mp4" />
  <track kind="captions" srclang="en" src="/demo.vtt" label="English" default />
  Download the <a href="/demo.mp4">video</a>.
</video>
```

## 💡 Examples [#-examples]

```html
<audio controls preload="metadata">
  <source src="/episode.mp3" type="audio/mpeg" />
  <source src="/episode.ogg" type="audio/ogg" />
</audio>

<video
  controls
  muted
  loop
  autoplay
  playsinline
  aria-label="Product animation"
>
  <source src="/loop.mp4" type="video/mp4" />
</video>

<script>
  const v = document.querySelector("video");
  btn.onclick = async () => {
    try {
      await v.play();
    } catch {
      /* autoplay blocked */
    }
  };
  v.addEventListener("error", () => console.error(v.error));
</script>
```

```html
<!-- Picture-in-picture / fullscreen via controls or JS APIs -->
```

## ⚠️ Pitfalls [#️-pitfalls]

* Autoplay with sound is blocked — mute or require a gesture.
* Missing captions fails accessibility for dialogue-heavy video.
* `preload="auto"` can waste bandwidth — prefer `metadata`/`none` on listing pages.
* Cross-origin media without CORS taints canvas draws.
* Don’t rely on Flash-era embeds — use native or modern players built on these elements.

## 🔗 Related [#-related]

* [media.md](/docs/html/media) — media overview
* [picture\_source.md](/docs/html/picture-source) — source selection
* [iframe.md](/docs/html/iframe) — third-party players
* [accessibility.md](/docs/html/accessibility) — captions
* [../CSS/object\_fit.md](/docs/html/../css/object-fit) — cover/contain


---

# Web Components (/docs/html/web-components)



# Web Components [#web-components]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Web Components combine Custom Elements, Shadow DOM, and HTML templates/slots into reusable, framework-agnostic widgets. Define a class, register a tag with a hyphenated name, encapsulate markup/styles in a shadow root, and project content with slots.

## 🔧 Core concepts [#-core-concepts]

| Piece                   | Role                                   |
| ----------------------- | -------------------------------------- |
| Custom Elements         | `customElements.define("x-el", Class)` |
| Shadow DOM              | style/DOM encapsulation                |
| `<template>` / `<slot>` | markup reuse & projection              |
| CSS `::part` / vars     | controlled theming                     |
| ES modules              | load component definitions             |

* Lifecycle: `constructor`, `connectedCallback`, `disconnectedCallback`, `attributeChangedCallback`.
* Form-associated custom elements can participate in forms (ElementInternals).
* Progressive enhancement: unknown elements render light DOM children until upgraded.

```html
<script type="module">
  class CoolBadge extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: "open" }).innerHTML = `
        <style>:host{display:inline-pad;padding:.2em .5em;background:var(--badge-bg, #eee)}</style>
        <slot></slot>
      `;
    }
  }
  customElements.define("cool-badge", CoolBadge);
</script>
<cool-badge>Beta</cool-badge>
```

## 💡 Examples [#-examples]

```html
<template id="tooltip-tpl">
  <style>
    :host {
      position: relative;
    }
    .tip {
      display: none;
      position: absolute;
      ...;
    }
    :host(:hover) .tip,
    :host(:focus-within) .tip {
      display: block;
    }
  </style>
  <slot></slot>
  <div class="tip" part="tip"><slot name="tip"></slot></div>
</template>

<script type="module">
  const tpl = document.getElementById("tooltip-tpl");
  class XTooltip extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: "open" }).append(tpl.content.cloneNode(true));
    }
  }
  customElements.define("x-tooltip", XTooltip);
</script>

<!-- Theming from outside -->
<style>
  x-tooltip {
    --badge-bg: #224;
  }
  x-tooltip::part(tip) {
    border-radius: 6px;
  }
</style>
```

```js
await customElements.whenDefined("cool-badge");
```

## ⚠️ Pitfalls [#️-pitfalls]

* Customized built-ins (`is="..."`) lack full cross-browser support — prefer autonomous elements.
* Closed shadow roots aren’t secure — don’t hide secrets there.
* Slotted content is styled with limited `::slotted` — complex styling may need parts/vars.
* SSR/hydration needs care — unknown elements flash unstyled without declarative shadow DOM strategies.
* Avoid huge shadow trees for simple static HTML — semantics first.

## 🔗 Related [#-related]

* [template\_slot.md](/docs/html/template-slot) — template & slot
* [../Javascript/DOM/custom\_elements.md](/docs/html/../javascript/dom/custom-elements) — element API
* [../Javascript/DOM/shadow\_dom.md](/docs/html/../javascript/dom/shadow-dom) — shadow API
* [accessibility.md](/docs/html/accessibility) — a11y in components
* [aria.md](/docs/html/aria) — ARIA when needed


---

# XML (/docs/html/xml)



# XML [#xml]

*HTML · Reference cheat sheet*

***

## 📋 Overview [#-overview]

**XML** (Extensible Markup Language) is a strict, generic markup language for structured data. **HTML5** is an SGML-inspired living standard with its own parsing rules—far more forgiving than XML. Authors sometimes meet XML via XHTML serialization, SVG/MathML embedded in HTML, sitemaps, RSS/Atom, or app config files.

This sheet contrasts XML rules with HTML practice and covers when polyglot markup, namespaces, and well-formedness matter in web documents.

## 🔧 Core concepts [#-core-concepts]

### Well-formedness (XML) [#well-formedness-xml]

XML documents must be well-formed:

* Single root element
* Properly nested tags
* Attribute values quoted
* Case-sensitive names
* Empty elements written as `<tag/>` or `<tag>&lt;/tag>`
* Special characters escaped: `&amp;` `&lt;` `&gt;` `&quot;` `&apos;`
* Optional XML declaration: `&lt;?xml version="1.0" encoding="UTF-8"?>`

HTML parsers auto-correct many errors; XML parsers **fail fatally** on malformed input.

### HTML vs XHTML [#html-vs-xhtml]

| Topic        | HTML5 (text/html)            | XHTML / XML               |
| ------------ | ---------------------------- | ------------------------- |
| MIME         | `text/html`                  | `application/xhtml+xml`   |
| Void tags    | `<br>` ok                    | `<br/>` or `<br>&lt;/br>` |
| Omitted tags | Often allowed                | Never                     |
| Namespaces   | Limited magic for SVG/MathML | Explicit `xmlns`          |
| Script/CSS   | Special CDATA-like rules     | Must respect XML escaping |

Serving XHTML as `text/html` makes browsers use the HTML parser—XML rules are not enforced.

### Namespaces [#namespaces]

```xml
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">
  <circle cx="12" cy="12" r="10" fill="currentColor"/>
</svg>
```

In HTML5, inline SVG and MathML are parsed with namespace awareness. Custom elements use different rules (no XML namespaces required).

### `xml:lang` and `lang` [#xmllang-and-lang]

In HTML, prefer `lang`. In XML vocabularies, `xml:lang` is standard. Polyglot documents may include both with identical values.

### Embedding XML-ish content in HTML [#embedding-xml-ish-content-in-html]

* **SVG / MathML** — first-class in HTML5.
* **Foreign data** — often JSON in `<script type="application/json">` instead of inline XML.
* **`XHTML` self-closing** — in `text/html`, trailing slashes on void elements are ignored noise; on non-void elements they can create surprising DOM trees—avoid casual `/>` on `<div/>`.

## 💡 Examples [#-examples]

### Minimal well-formed XML [#minimal-well-formed-xml]

```xml
<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Ada</to>
  <from>Grace</from>
  <message>Ship the spec.</message>
</note>
```

### Inline SVG in HTML [#inline-svg-in-html]

```html
<figure>
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" role="img" aria-label="Green circle">
    <circle cx="50" cy="50" r="40" fill="#0f766e"/>
  </svg>
  <figcaption>Decorative brand mark</figcaption>
</figure>
```

### Atom feed snippet [#atom-feed-snippet]

```xml
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Docs updates</title>
  <link href="https://example.com/feed.xml" rel="self"/>
  <updated>2026-07-10T12:00:00Z</updated>
  <entry>
    <title>Forms cheat sheet</title>
    <link href="https://example.com/html/form"/>
    <id>urn:uuid:1234</id>
    <updated>2026-07-10T12:00:00Z</updated>
  </entry>
</feed>
```

### Polyglot-minded void elements [#polyglot-minded-void-elements]

```html
<!-- Safe in both HTML and XHTML serializations -->
<meta charset="utf-8"/>
<link rel="stylesheet" href="/app.css"/>
<img src="/logo.svg" alt="Acme"/>
<br/>
```

Still serve HTML as `text/html` unless you intentionally need XML tooling.

## ⚠️ Pitfalls [#️-pitfalls]

* **Assuming HTML is XML** — Unclosed `<p>` or `<li>` may “work” in HTML and break XML pipelines.
* **`innerHTML` with XML strings** — HTML parser rules apply in the DOM, not XML rules.
* **Namespace typos** — Wrong SVG `xmlns` yields elements in the wrong namespace (no rendering).
* **Raw `&` in XML** — Must escape; HTML text content is also safer escaped.
* **XHTML MIME without error handling** — A single error blank-screens the page in XML mode.
* **`document.write` / copy-paste XHTML** — Self-closing non-void tags in HTML create empty elements and orphaned children.

## 🔗 Related [#-related]

* [Head](/docs/html/head) — document prologue vs XML declaration
* [Language](/docs/html/language) — `lang` / `xml:lang`
* [Meta](/docs/html/meta) — charset related to encoding declarations
* [URL](/docs/html/url) — XML Base concepts
* [Media](/docs/html/media) — SVG as image `src`
* [Script](/docs/html/script) — JSON data blocks vs XML
* [Style](/docs/html/style) — styling SVG embedded in HTML

