HTML Cheat Sheet
The markup language that gives every web page its structure: elements, attributes, forms, media and accessibility basics. Targets the current HTML Living Standard and browsers as of October 2026.
On this page
Page Skeleton #
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Page title – Site name</title>
</head>
<body>
<h1>Hello, world</h1>
</body>
</html>
| Code | What it does |
|---|---|
<!doctype html> | Standards mode; always the very first line |
<html lang="en"> | Language of the page (screen readers, translation, hyphenation) |
<meta charset="utf-8"> | Text encoding; put it first in <head> |
<meta name="viewport" content="width=device-width, initial-scale=1"> | Makes the page responsive on phones |
<title> | Text in the browser tab, bookmarks and search results |
Head Elements #
| Code | What it does |
|---|---|
<meta name="description" content="..."> | Summary shown in search results (about 150 characters) |
<link rel="icon" href="/favicon.svg" type="image/svg+xml"> | Favicon |
<link rel="stylesheet" href="styles.css"> | Load a CSS file |
<link rel="canonical" href="https://example.com/page"> | The preferred URL for this page (avoids duplicate content in search) |
<script src="app.js" defer></script> | Run after the HTML is parsed, in document order (best default) |
<script type="module" src="main.js"></script> | ES module: deferred by default, can use import |
<script src="analytics.js" async></script> | Run as soon as it downloads, in any order (independent scripts) |
<meta property="og:image" content="https://example.com/share.png"> | Preview image when the link is shared (Open Graph) |
Text #
| Code | What it does |
|---|---|
<h1> … <h6> | Headings; one <h1> per page, don't skip levels |
<p> | Paragraph |
<strong> / <em> | Strong importance (bold) / stress emphasis (italic) |
<b> / <i> | Bold / italic without extra meaning |
<code> / <pre> | Inline code / preformatted block (keeps spaces and line breaks) |
<kbd>Ctrl</kbd> | Keyboard input |
<blockquote cite="url"> / <q> | Block quotation / short inline quote (adds quote marks) |
<abbr title="HyperText Markup Language">HTML</abbr> | Abbreviation with its full form |
<time datetime="2026-10-11">11 Oct</time> | Machine-readable date or time |
<sub> / <sup> | Subscript (H₂O) / superscript (x²) |
<br> / <hr> | Line break inside text / thematic break between topics |
<span> / <div> | Generic inline / block container with no meaning (for styling) |
Semantic Layout #
| Code | What it does |
|---|---|
<header> | Intro of the page or a section (logo, title, nav) |
<nav> | Main navigation links |
<main> | The main content; one visible per page |
<article> | Self-contained content (blog post, product card, comment) |
<section> | Thematic group of content, normally with a heading |
<aside> | Related side content (sidebar, callout) |
<footer> | Footer of the page or a section (copyright, links) |
<figure> + <figcaption> | Image, chart or code with a caption |
<search> | Wraps a search form (widely supported) |
Links #
| Code | What it does |
|---|---|
<a href="/about">About</a> | Link to a page on the same site |
<a href="#pricing"> | Jump to the element with id="pricing" |
<a href="https://example.com" target="_blank" rel="noopener"> | Open in a new tab (modern browsers already imply noopener) |
rel="nofollow" / rel="sponsored" | Tell search engines not to endorse the link / it's paid |
<a href="mailto:hi@example.com?subject=Hello"> | Open an email to that address |
<a href="tel:+3231234567"> | Call the number (international format) |
<a href="/files/report.pdf" download> | Download the file instead of opening it (same-origin only) |
Images & Media #
| Code | What it does |
|---|---|
<img src="cat.jpg" alt="Cat asleep on a laptop" width="800" height="600"> | Image; width/height reserve space so the layout doesn't jump |
alt="" | Decorative image: screen readers skip it |
loading="lazy" | Load only when near the viewport (not for the main above-the-fold image) |
fetchpriority="high" | Download the main (hero) image first (Baseline 2024) |
srcset="cat-480.jpg 480w, cat-960.jpg 960w" sizes="(max-width: 600px) 100vw, 50vw" | Let the browser pick a file for the screen width |
<video src="clip.mp4" controls poster="still.jpg"></video> | Video with play controls and a preview image |
autoplay muted loop playsinline | Background video (autoplay only works when muted) |
<audio src="song.mp3" controls></audio> | Audio player |
<track src="subs.vtt" kind="subtitles" srclang="en" label="English"> | Subtitles inside <video> |
<iframe src="..." title="Map" loading="lazy"></iframe> | Embed another page; always give it a title |
<picture>
<source srcset="hero.avif" type="image/avif">
<source srcset="hero-wide.webp" media="(min-width: 800px)" type="image/webp">
<img src="hero.jpg" alt="Team at work" width="1200" height="600">
</picture>
Lists & Tables #
| Code | What it does |
|---|---|
<ul> + <li> | Bulleted list (order doesn't matter) |
<ol> + <li> | Numbered list; start="5", reversed, type="a" |
<dl> + <dt> + <dd> | Description list: term and definition pairs |
<table> + <caption> | Table with a visible title (helps screen readers) |
<thead> / <tbody> / <tfoot> | Header, body and footer row groups |
<th scope="col"> / <th scope="row"> | Header cell for a column / for a row |
colspan="2" / rowspan="3" | Make a cell span columns / rows |
Forms #
| Code | What it does |
|---|---|
<form action="/subscribe" method="post"> | Send the fields to a URL (get puts them in the URL, the default) |
<label for="email">Email</label> + <input id="email" name="email"> | Label linked to its field (click label to focus) |
<label><input type="checkbox" name="terms"> I agree</label> | Label wrapped around the field (no id needed) |
name="email" | Key the value is sent under; without it the field isn't submitted |
required | Field must be filled in |
minlength="8" / maxlength="64" | Minimum / maximum number of characters |
min="1" max="10" step="1" | Limits for number, range and date fields |
pattern="[0-9]{4}" | Regex the whole value must match |
placeholder="you@example.com" | Example hint inside the field (not a replacement for a label) |
autocomplete="email" | Autofill hint: name, email, tel, street-address, postal-code, current-password, new-password, one-time-code, off |
disabled / readonly | Greyed out and not submitted / can't edit but is submitted |
<select name="size"><option value="m">Medium</option></select> | Dropdown; selected preselects, multiple allows several |
<textarea name="msg" rows="4"></textarea> | Multi-line text |
<fieldset> + <legend> | Group related fields with a caption (radio groups, addresses) |
<button type="submit"> | Submits the form (the default type inside a form) |
<button type="button"> | Does nothing by itself; use it for JavaScript actions |
Input Types #
| Code | What it does |
|---|---|
type="text" | Single-line text (default) |
type="email" / type="url" | Validates the format, shows a matching mobile keyboard |
type="password" | Hidden characters |
type="tel" | Phone keypad on mobile (no format check, add pattern) |
type="number" | Numeric spinner; for codes and card numbers use inputmode="numeric" instead |
type="date" / type="time" / type="datetime-local" | Native date and time pickers |
type="checkbox" | On/off; add checked to pre-tick |
type="radio" | Pick one; radios with the same name form a group |
type="range" | Slider (use min, max, step) |
type="file" accept="image/*" multiple | File upload (form needs enctype="multipart/form-data") |
Interactive Elements #
| Code | What it does |
|---|---|
<details> + <summary> | Collapsible section; open starts it expanded, no JS needed |
<details name="faq"> | Same name on several = only one open at a time (Baseline 2024) |
<dialog id="dlg"> | Dialog box; dlg.showModal() opens it as a modal with a backdrop |
dlg.show() / dlg.close() | Open without modal behaviour / close it |
<form method="dialog"> | A submit button inside closes the dialog |
<button commandfor="dlg" command="show-modal"> | Open a dialog without JS; also close (Baseline since Dec 2025) |
<div id="menu" popover> | Popover: top layer, light dismiss (click outside or Esc) (Baseline 2025) |
<button popovertarget="menu"> | Toggles that popover; popovertargetaction="show" / "hide" |
inert | Make a part of the page unclickable and unfocusable |
<button commandfor="confirm" command="show-modal">Delete</button>
<dialog id="confirm">
<p>Delete this file?</p>
<form method="dialog">
<button value="cancel">Cancel</button>
<button value="ok">Delete</button>
</form>
</dialog>
Global Attributes #
| Code | What it does |
|---|---|
id="intro" | Unique name: link target, <label for>, JS getElementById |
class="card featured" | One or more space-separated classes for CSS and JS |
data-user-id="42" | Custom data; read in JS as el.dataset.userId |
tabindex="0" / tabindex="-1" | Add to the tab order / focusable only from JS (avoid positive values) |
title="More info" | Tooltip on hover (not shown on touch, don't put key info here) |
lang="nl" | Language of this part of the page |
Accessibility Basics #
| Code | What it does |
|---|---|
alt="Red running shoe, side view" | Describe what the image shows or does; alt="" if decorative |
<label for="..."> | Every form field needs a label, visible if possible |
<button> / <a href> | Button for actions, link for going somewhere; never a clickable <div> |
<main>, <nav>, <header>, <footer> | Landmarks: screen-reader users jump between them |
<button aria-label="Close">×</button> | Accessible name for an icon-only button |
aria-describedby="pw-hint" | Extra description, e.g. a hint or error message for a field |
aria-expanded="false" | Tell if a menu or accordion toggle is open |
aria-current="page" | Marks the current page link in a nav |
aria-live="polite" | Announce content that changes (toasts, form status) |
First rule of ARIA: use a native element (<button>, <dialog>, <details>) when one exists. Wrong ARIA is worse than no ARIA.
Entities #
| Code | What it does |
|---|---|
& | & ampersand |
< / > | < and > (to show a tag as text) |
" / ' | " and ' inside attribute values |
| Non-breaking space (keeps "10 kg" on one line) |
© / ® / ™ | © ® ™ |
— / – / … / € | — – … € |
€ / € | Any character by decimal / hex code point (here €) |
With charset="utf-8" you can type ©, € or emoji directly; you only must escape & and < in text.
Tips #
- Validate with validator.w3.org: it catches unclosed tags, duplicate
ids and invalid nesting. <p>can't contain block elements such as<div>or<ul>: the browser closes the<p>early and your CSS breaks.- Don't nest interactive elements (a
<button>inside an<a>, a link inside a link). - Boolean attributes are on when present:
required="false"still means required. Remove the attribute instead. - Pick elements for meaning, not looks (
<h2>for a heading, then style it with CSS). Never skip the<label>. <br>and<br />are both valid; void elements (<img>,<input>,<meta>) never get a closing tag.
Nothing on this sheet matches “”.