HTML#
HTML (HyperText Markup Language) is the document format of the web. The current revision (“HTML5”) is a living standard maintained by WHATWG; the version number is mostly ceremonial in 2026.
Document Skeleton#
The minimum well-formed document. <!doctype html>,
<meta charset>, <meta viewport>, and <html lang>
are non-negotiable; skipping any of them produces real
quirks in browser, accessibility, and search-engine behavior.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Page</title>
<link rel="stylesheet" href="/styles.css">
</head>
<body>
<header>...</header>
<main>...</main>
<footer>...</footer>
<script type="module" src="/main.js"></script>
</body>
</html>
Element Flow#
Elements are tags with optional content; some are void (no
closing tag). The categories below are a high-level taxonomy by
default flow; CSS display overrides any of them.
Block-level:
<div>,<p>,<section>,<article>, start a new line, flow vertically.Inline:
<span>,<a>,<strong>,<em>, flow within text.Replaced:
<img>,<video>,<iframe>, the browser fills in the content.Void:
<br>,<hr>,<input>,<meta>,<link>,<img>.
The sections below break elements down by their spec category.
Document Metadata#
Tags that live inside <head>. They tell the browser, search
engines, and operating systems how to render, identify, and link
the document.
Element |
Purpose |
|---|---|
|
Container for metadata. Not rendered. |
|
Browser-tab title and the default search-result heading. |
|
Default |
|
Resource relationships: stylesheets, icons, manifests, prefetch hints, alternate languages. |
|
Free-form key-value metadata: charset, viewport, description, OpenGraph, theme color, robots directives. |
|
Inline CSS. Useful for above-the-fold critical CSS; not for application styles. |
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Operator handbook">
<meta name="theme-color" content="#0b3d91">
<title>CYBINT Operator Handbook</title>
<base href="/handbook/">
<link rel="icon" href="/favicon.ico">
<link rel="stylesheet" href="/styles.css">
<link rel="manifest" href="/site.webmanifest">
</head>
Sectioning#
Landmark elements that carve a page into navigable regions. Screen readers announce them by name; search engines weight them; default styles know how to render them.
Element |
Purpose |
|---|---|
|
The document’s sectioning root. |
|
Introductory content for the page or a section: site title, primary nav. |
|
Major navigation block. Not every link list; reserve for primary navigation. |
|
The document’s primary content. One per page. |
|
Tangentially related content: sidebars, pull quotes, call-outs. |
|
Footer for the page or a section: copyright, links, author. |
|
A generic thematic grouping with a heading. |
|
A self-contained composition: blog post, news article, comment. |
|
A region containing a search interface. New in HTML Living Standard. |
|
Section headings. Use levels in order; do not skip. |
|
A heading plus subtitles. Limited use. |
|
Contact information for the nearest |
<body>
<header><h1>Site Title</h1><nav>...</nav></header>
<main>
<article>
<h2>Post title</h2>
<p>...</p>
<footer>Posted by ...</footer>
</article>
<aside>Related posts...</aside>
</main>
<footer><address>contact@example.com</address></footer>
</body>
Text Content#
Block-level elements for organizing prose, lists, and quoted material.
Element |
Purpose |
|---|---|
|
A paragraph. |
|
Generic block container with no semantics. Use only when no other element fits. |
|
Preformatted text; whitespace is preserved. Wrap |
|
A long quotation. |
|
Thematic break. Renders as a horizontal rule. |
|
Unordered list. |
|
Ordered list. |
|
List item, inside |
|
Toolbar-style action list. Treated like |
|
Description list. |
|
Term in a description list. |
|
Definition or description for a |
|
Self-contained content (image, code, diagram) with a caption. |
|
Caption inside a |
<figure>
<img src="/diagram.svg" alt="Cluster topology">
<figcaption>Production cluster, west region.</figcaption>
</figure>
<dl>
<dt>Operator</dt>
<dd>The person on the keyboard at the moment of the action.</dd>
<dt>Target</dt>
<dd>The system the operator is authorized to act against.</dd>
</dl>
Inline Text Semantics#
Inline elements that mark up phrases inside flowing text. Most have a default style, but their real value is semantic, accessible technology and search engines treat them as more than typography.
Element |
Purpose |
|---|---|
|
Hyperlink. |
|
Generic inline container with no semantics. |
|
Strong importance. Bold by default. |
|
Emphasis. Italic by default. |
|
Stylistic offset without elevated importance. |
|
Stylistic offset without elevated emphasis (alternate voice, technical term). |
|
Non-textual annotation (proper name in Chinese, misspelling). |
|
No longer accurate or relevant. Strike-through. |
|
Highlighted for reference in the current context. |
|
Side comments, fine print. |
|
Inline code fragment. |
|
Keyboard input. |
|
Sample output from a program. |
|
Variable in a mathematical expression or programming context. |
|
Abbreviation. |
|
Title of a cited work. |
|
Short inline quotation. |
|
The defining instance of a term. |
|
A date or time. |
|
A machine-readable value tied to text content. |
|
Subscript. |
|
Superscript. |
|
Line break. |
|
Optional word-break opportunity. |
|
Bidirectional text isolation. |
|
Bidirectional text override. |
|
East Asian typography ruby annotation container. |
|
Ruby text inside a |
|
Ruby parenthesis fallback for browsers that lack ruby support. |
<p>Published <time datetime="2026-05-12">12 May 2026</time>.
Press <kbd>Ctrl</kbd>+<kbd>C</kbd> to abort.
The <abbr title="CYBINT Operator Handbook">COH</abbr> covers
the standard tradecraft. See <cite>The C Programming Language</cite>
for the underlying idiom.</p>
Images and Multimedia#
Image, audio, and video markup. Responsive images (srcset /
sizes) and format negotiation (<picture>) cover most
modern image needs; <video> and <audio> are the native
players.
Element |
Purpose |
|---|---|
|
Embedded image. Always set |
|
Container for |
|
Alternative media resource inside |
|
Native audio player. |
|
Native video player. |
|
Captions, subtitles, descriptions for a media element. |
|
Client-side image map container. Rare in modern UIs. |
|
Clickable region inside a |
<img src="hero.avif" alt="Cluster topology" width="1600" height="900"
srcset="hero-800.avif 800w, hero-1600.avif 1600w"
sizes="(max-width: 800px) 100vw, 800px"
loading="lazy" decoding="async">
<picture>
<source type="image/avif" srcset="hero.avif">
<source type="image/webp" srcset="hero.webp">
<img src="hero.jpg" alt="Cluster topology">
</picture>
<video controls preload="metadata" poster="thumb.jpg">
<source src="clip.webm" type="video/webm">
<source src="clip.mp4" type="video/mp4">
<track kind="captions" src="clip.en.vtt" srclang="en" label="English" default>
</video>
Embedded Content#
Elements that pull external documents or interactive content into the page.
Element |
Purpose |
|---|---|
|
Embedded browsing context. Use |
|
Generic external content (plugins, PDFs). Largely legacy. |
|
External resource with a fallback inside the tag. |
|
Inline SVG. Treated as part of the DOM; CSS and JS reach inside. |
|
MathML expression. Native rendering in modern browsers. |
<iframe src="https://example.com/embed" loading="lazy"
sandbox="allow-scripts allow-same-origin"
referrerpolicy="no-referrer" title="External preview"></iframe>
Tables#
Tables for tabular data. Semantic structure (<thead>,
<tbody>, <tfoot>, <caption>, <th scope=>) is what
makes them accessible to screen readers and predictable for CSS.
Never use tables for layout.
Element |
Purpose |
|---|---|
|
Tabular data container. |
|
Table title; first child of |
|
Column group; carries shared styling for one or more columns. |
|
Single column within a |
|
Header rows. |
|
Body rows. Allowed multiple times to group sub-sections. |
|
Footer rows: totals, summaries. |
|
Row. |
|
Header cell. |
|
Data cell. |
<table>
<caption>Quarterly results</caption>
<thead>
<tr><th scope="col">Quarter</th><th scope="col">Revenue</th></tr>
</thead>
<tbody>
<tr><th scope="row">Q1</th><td>$1.2M</td></tr>
<tr><th scope="row">Q2</th><td>$1.6M</td></tr>
</tbody>
<tfoot>
<tr><th scope="row">Total</th><td>$2.8M</td></tr>
</tfoot>
</table>
Forms#
The platform’s input layer. Built-in validation, the right keyboard on mobile, accessible labeling, and submit semantics all come from using the form elements correctly. Modern HTML5 input types eliminate most of what JS form libraries were built to provide.
Element |
Purpose |
|---|---|
|
Form container. |
|
Single-line control. |
|
Multi-line text input. |
|
Drop-down or list box. |
|
Option group inside |
|
Single choice inside |
|
Suggestion list bound to an |
|
Push button. |
|
Caption bound to a control by |
|
Group of related controls. |
|
Caption for a |
|
Result of a calculation; can target a form’s controls. |
|
Progress indicator. |
|
Scalar measurement within a known range. |
<form method="post" action="/contact" novalidate>
<label>
Name
<input name="name" required autocomplete="name">
</label>
<label>
Email
<input type="email" name="email" required autocomplete="email">
</label>
<fieldset>
<legend>Contact preference</legend>
<label><input type="radio" name="prefer" value="email" checked> email</label>
<label><input type="radio" name="prefer" value="phone"> phone</label>
</fieldset>
<label>
Message
<textarea name="message" rows="4" required></textarea>
</label>
<button type="submit">Send</button>
</form>
Useful input types: email, url, number, tel,
date, time, datetime-local, month, week,
color, range, search, file. They give validation
and, on mobile, the right keyboard.
Interactive#
Built-in interactive widgets. Less code than JS reimplementations, keyboard-accessible by default, and styleable with CSS.
Element |
Purpose |
|---|---|
|
Disclosure widget; expands when |
|
The visible label for a |
|
Native modal or non-modal dialog. |
<details>
<summary>Show advanced options</summary>
<p>These options apply to the current session only.</p>
</details>
<dialog id="confirm">
<form method="dialog">
<p>Delete this campaign?</p>
<button value="cancel">Cancel</button>
<button value="ok">Delete</button>
</form>
</dialog>
<script>document.getElementById('confirm').showModal();</script>
Scripting#
How JavaScript and dynamic graphics load into a page.
Element |
Purpose |
|---|---|
|
Loads or runs JavaScript. |
|
Fallback content when JS is disabled. |
|
2D / WebGL drawing surface. Pixel data is exposed to scripts. |
|
Inert parsed HTML fragment. Cloned into the DOM at runtime. |
|
Insertion point inside a custom element’s shadow DOM. |
<script src="/app.js" defer></script>
<script type="module" src="/main.js"></script>
<script type="module">
import { mount } from "/lib.js";
mount(document.getElementById("app"));
</script>
<template id="card">
<article class="card">
<h3></h3>
<p></p>
</article>
</template>
defer, run after parsing, in document order. Use this by default.async, run as soon as ready, out of order. Analytics, isolated.type="module", ES modules, withimport/export; deferred by default.
Demarcating Edits#
For documents that show revisions, change history, or collaborative edits.
Element |
Purpose |
|---|---|
|
Inserted content. |
|
Deleted content. Same provenance attributes. |
<p>Status: <del datetime="2026-05-10">draft</del>
<ins datetime="2026-05-12">approved</ins>.</p>
Attributes#
Per-element configuration. Standard attributes are
type-checked by the spec; boolean attributes are present-or-
absent (disabled not disabled="true"); custom attributes
use the data- prefix and surface in JavaScript through
element.dataset:
<a href="/about" target="_blank" rel="noopener">about</a>
<input type="email" name="email" required minlength="5">
<img src="/logo.svg" alt="Acme Co." loading="lazy" decoding="async">
<button type="submit" disabled aria-busy="true">Send</button>
Boolean attributes are present-or-absent (disabled, not
disabled="true"). Custom attributes use the data- prefix
(data-user-id="42") and are accessible from JavaScript via
element.dataset.
Accessibility#
The accessibility checklist that catches the bulk of WCAG failures. Semantic HTML carries most of the weight; ARIA fills the gaps; keyboard reachability and visible focus are the boundaries below which the site stops working for users who can’t use a mouse.
Use semantic elements first; ARIA second.
Label every form control.
Use heading levels in order (
<h1>once, then<h2>,<h3>); don’t skip.Make focus visible (
:focus-visible).Ensure keyboard reachability for everything that takes a click.
aria-*attributes for state and context that semantics can’t express:aria-expanded,aria-controls,aria-live,aria-current.
Run real assistive-tech tests: VoiceOver, NVDA, Narrator, TalkBack. Linters and Lighthouse cover the basics; users find the rest.
Validation#
The tools that catch HTML and accessibility issues before real users do. Each one covers a different layer, from spec compliance (W3C validator), runtime issues (DevTools), performance and best practices (Lighthouse), accessibility (axe DevTools).
Browser DevTools’ Issues panel.
Lighthouse for accessibility / performance / best practices.
axe DevTools for accessibility.
What Belongs in HTML vs. CSS vs. JS#
A useful heuristic for “where should this go?” When something
can be done in HTML or CSS, do it there. Native
<details>, <dialog>, form validation, and CSS
animations are more accessible and more performant than JS
reimplementations.
HTML, structure, semantics, content, links, forms.
CSS, presentation, layout, animation, theming.
JavaScript, behavior the platform doesn’t already provide.
When something can be done in HTML or CSS, do it there. Native
<details>, <dialog>, form validation, and CSS animations are more
accessible and more performant than JS reimplementations.