HTML Cheatsheet - HTML Tags & Attributes Reference
When you hand-write a page, HTML decides who can understand the document: search engines weigh content by tag hierarchy, screen readers follow DOM order, and both signals get flattened by a pile of nameless divs. This table groups tags by document structure, text formatting, lists, links and images, tables, forms, and semantic elements, listing for each one its default behavior, its useful attributes, and the situations where it does not belong. Judge a choice with three questions: does the element still explain the structure without CSS, can search engines index it on its own, and can keyboard and screen reader users reach it. Reach for it when building a landing page without any framework, wiring native form validation and label associations, marking up table headers and scopes correctly, or producing an email template where you must control the markup by hand. The contrast with React or Vue is not syntax but responsibility: a framework renders one component, this table governs the skeleton of the whole document and its accessibility baseline.
Typical Use Case
For front-end developers hand-writing static pages, maintaining older projects, or wanting document structure done properly. The sheet follows three lines: document structure first, with DOCTYPE, meta charset and title as the non-negotiable baseline; then semantics, where the point is choosing the right tag instead of styling a div to look like one; then interaction, covering typed input validation, label association through for, and button type. Tables explain the division of labour between thead, tbody, th and td plus colspan and rowspan, and the closing section covers selecting among header, nav, main, article, section, aside and footer — the choice that accessibility and SEO both depend on.
Document Structure 8
<!DOCTYPE html><html lang="zh-CN"><head>...</head><meta charset="UTF-8"><title>Page Title</title><link rel="stylesheet" href="style.css"><script src="script.js"></script><body>...</body>Text Formatting 9
<h1>~<h6><p>Paragraph</p><strong>Bold</strong><em>Italic</em><br><hr><blockquote>Quote</blockquote><code>Inline code</code><pre>Preformatted</pre>Lists 3
<ul><li>List item</li></ul><ol><li>List item</li></ol><dl><dt>Term</dt><dd>Description</dd></dl>Links & Images 6
<a href="url">Link text</a><a href="url" target="_blank"><a href="#id">Anchor</a><img src="image.jpg" alt="Description"><img src="..." width="300" height="200"><figure><img><figcaption>Caption</figcaption></figure>Tables 7
<table>...</table><thead><tr><th>Header</th></tr></thead><tbody><tr><td>Data</td></tr></tbody><tr>Row</tr><th>Header cell</th><td>Data cell</td>colspan="2" / rowspan="2"Forms 10
<form action="/submit" method="POST"><input type="text" name="username"><input type="password" name="pwd"><input type="email" name="email"><input type="checkbox" name="agree"><input type="radio" name="gender"><textarea name="message"></textarea><select><option>Option</option></select><button type="submit">Submit</button><label for="id">Label</label>Semantic Tags 9
<header>Header</header><nav>Nav</nav><main>Main</main><article>Article</article><section>Section</section><aside>Aside</aside><footer>Footer</footer><div>Block container</div><span>Inline container</span>Parameter matrix
| Parameter | Effect | Example |
|---|---|---|
<!DOCTYPE html> | HTML5 document declaration; must be the first line. | <!DOCTYPE html> |
<html lang="zh-CN"> | Root element; lang determines screen-reader pronunciation and translation prompts. | <html lang="zh-CN"> |
<meta charset="UTF-8"> | Character encoding; leaving it out causes garbled text. | <meta charset="UTF-8"> |
<title> | Page title, shown in the browser tab and used by search engines. | <title>Page title</title> |
<link rel="stylesheet"> | Imports an external stylesheet. | <link rel="stylesheet" href="style.css"> |
<script src></script> | Imports an external script. | <script src="script.js"></script> |
<strong> / <em> | Semantic emphasis: importance and stress. | <strong>Required</strong> |
<pre> / <code> | Code display that preserves spaces and line breaks. | <pre>code block</pre> |
<ul> / <ol> / <dl> | Unordered, ordered, and definition lists. | <ol><li>Step one</li></ol> |
target="_blank" | Opens the link in a new window/tab. | <a href="url" target="_blank">link</a> |
href="#id" | In-page anchor jump. | <a href="#intro">Intro</a> |
alt attribute | Image alternative text; a missing value hurts accessibility and SEO. | <img src="a.jpg" alt="Architecture diagram"> |
width / height | Specifies image dimensions to reduce layout shift. | <img src="a.jpg" width="300" height="200"> |
colspan / rowspan | Table cell spanning columns / rows. | <td colspan="2">Total</td> |
input type | Provides automatic validation by type (text/password/email). | <input type="email" name="email"> |
label for | Associates a label with an input so clicking it focuses the field. | <label for="id">Label</label> |
button type | Distinguishes a submit button from a plain button. | <button type="submit">Submit</button> |
<main> / <nav> / <aside> | Main content / navigation / complementary content sectioning. | <main>Main content</main> |
Common pitfalls
SymptomAll non-Latin text on the page shows up as garbled boxes.
CauseA missing <meta charset="UTF-8">, or it was placed after other tags that already emit content.
FixPut the charset declaration at the very top of <head> so the parser knows the encoding before reading any content.
SymptomScreen readers cannot announce form field names, or clicking the label text does not focus the input.
CauseThe input is not associated with a label via for, so screen readers can only read a name with no semantics.
FixGive each input a <label> whose for points to its id, and put the hint text in the label rather than the placeholder.
SymptomWhen an image fails to load or the network is slow, the page leaves large blank areas and the layout jumps.
Cause<img> has no alt and no declared dimensions, so the browser cannot reserve space.
FixAdd a descriptive alt, and set width / height matching the real aspect ratio.
SymptomAn SEO check or accessibility audit reports "missing landmark regions".
CauseThe whole page is built from divs, without semantic tags such as header/nav/main/footer.
FixReplace the page skeleton with semantic tags, keep main unique per page, and fall back to div for blocks that fit nothing else.
SymptomThe table crams together on narrow screens and cell content overlaps.
CauseA structure that should use thead/th was written with plain tds, so screen readers cannot associate headers with data either.
FixUse thead + th for headers and tbody + td for data rows; declare spans explicitly with colspan / rowspan.
SymptomClicking any button in the form submits it, including the one meant to be an ordinary button.
Cause<button> defaults to type="submit", and the styling shows no difference.
FixWrite type="submit" or type="button" explicitly so semantics match appearance.
SymptomIndentation and line breaks in code samples get collapsed onto a single line.
CauseThe code was placed in an ordinary <p>, and HTML collapses consecutive whitespace into one space.
FixSwitch to <pre> to preserve original formatting; use <code> only for inline snippets.
Troubleshooting
1Confirm the document skeleton and key metadata are all present.
grep -nE '<!DOCTYPE html>|<meta charset|<title>|<html lang' index.htmlAll four declarations should appear near the top of the file; a missing charset is the direct cause of garbled text.
2Check for images missing the alt attribute.
grep -c '<img' index.html && grep -n '<img' index.htmlVerify each img has an alt one by one; purely decorative images may use an empty alt so screen readers skip them.
3Confirm the page has only one main region.
grep -c '<main' index.htmlOnly an output of 1 meets the spec; more than 1 means the page skeleton was copy-pasted incorrectly.
4Check that every input has a matching label.
grep -oE 'name="[^"]+"' index.htmlThe output name list should map one-to-one to the ids that label for points to; one missing means a missed association.
5Check for unclosed or mismatched tags.
python -c "from html.parser import HTMLParser; HTMLParser().feed(open('index.html', encoding='utf-8').read())"Feeding the file to the standard-library parser quickly reveals structural collapse from mismatched tags.
Command Examples
Semantic skeleton: exactly one main per page
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Page title</title>
</head>
<body>
<header>...</header>
<nav>...</nav>
<main>...</main>
<aside>...</aside>
<footer>...</footer>
</body>
</html>lang and meta charset belong at the very top of head: without lang a screen reader switches to an English voice, and a late or missing charset produces mojibake. These tags carry semantics, not layout — leave layout to CSS.
An accessible data table: headers, scope, and spans
<table>
<thead>
<tr><th scope="col">Name</th><th scope="col">Age</th></tr>
</thead>
<tbody>
<tr><td>Tom</td><td>25</td></tr>
<tr><td>Jerry</td><td colspan="2">Span two columns</td></tr>
</tbody>
</table>thead/th lets a screen reader announce the column name with each cell, and scope="col" is more reliable than relying on inference. colspan/rowspan shift the column correspondence of later rows, so plan the span before you merge.
Forms: bind labels to inputs with for
<form action="/submit" method="POST">
<label for="username">Username</label>
<input type="text" id="username" name="username">
<select name="gender"><option>Male</option></select>
<button type="submit">Submit</button>
</form>for must equal the input id: clicking the label focuses the field and screen readers use the pairing to announce the control name. The name attribute is what actually gets submitted — an input without one is silently discarded no matter what the user typed.
Always give images alt text and explicit dimensions
<img src="image.jpg" alt="Panorama of server-room racks">
<img src="chart.png" alt="Monthly conversion-rate line chart" width="300" height="200">
<figure>
<img src="diagram.png" alt="Diagram of the request path">
<figcaption>Figure 1: three cache layers a request passes through</figcaption>
</figure>Use alt="" for purely decorative images and a real description for informative ones — "image.jpg" tells a screen-reader user nothing. width/height reserve layout space and remove the content jump when the image finishes loading (CLS).
Common Pitfalls
- An img without alt makes screen readers read out the filename. Decorative images should say alt="" explicitly; a missing attribute counts as an accessibility defect.
- target="_blank" without rel="noopener" lets the new page reach back through window.opener and manipulate the original — always add rel="noopener noreferrer".
- Loose text inside a table without tr/td triggers browser error recovery that silently inserts tbody; the structure shifts, styles and screen-reader order both break, and the cause is very hard to find.
- A late-positioned meta charset, or charset="gb2312", means the browser has already parsed bytes under a default encoding — Chinese renders as mojibake. Put UTF-8 near the top of head.
- A form control with no name attribute never appears in the request body: the backend always gets nothing and nothing looks wrong on the page.
- Using h1-h6 font sizes as a styling tool (skipping levels, or using h3 for a small heading) breaks the outline screen readers navigate by, and users lose all sense of document structure.
Tips
- img needs alt for accessibility and SEO.
- Associate inputs with label for accessibility.
- Prefer semantic tags (header/nav/main) over plain div.
FAQ
When should I reach for a semantic tag, and when is a div fine?
Use a semantic element whenever one fits: header, nav, main (one per page), article, section, aside, footer. They carry accessibility and SEO meaning that assistive tech can pick up for free. Reach for div (block) and span (inline) only when nothing fits, or purely for layout and styling hooks. A page built entirely from divs reads as an unstructured blob to a screen reader.
What is the real difference between <code> and <pre>?
<code> is inline: it marks a short snippet such as a variable or a command and only switches the font, without disturbing the surrounding line wrapping. <pre> is block-level and preformatted, so spaces, indentation and newlines survive untouched. For multi-line snippets the two are normally combined as <pre><code>...</code></pre> — pre holds the formatting, code keeps the semantic monospace styling. For line numbers, wrap each line in a <span> inside the <code>.
Do form inputs really need a matching label?
Yes. Matching the label for attribute to the input id means clicking the label text focuses the field, and screen readers announce a proper accessible name — a baseline accessibility requirement. The pattern is <label for="username">Username</label> alongside <input type="text" id="username" name="username">. Pick the right control type too: type="email" for built-in validation, <textarea> for multi-line input, checkboxes sharing one name for a checkbox group, and <button type="submit"> to submit the form.
How do I make a table cell span multiple rows or columns?
Add colspan and rowspan to the th or td. colspan="2" stretches horizontally and is the usual choice for merged headers; rowspan="2" stretches vertically, which is handy for a category column on the left. Keep the markup tidy: headers inside <thead><tr><th> and data inside <tbody><tr><td> so styling and screen-reader output both work. When you span, plan which neighbouring cell you delete — leaving an extra cell shifts every column after it.
What actually breaks if I skip the alt attribute on an image?
Two real problems: screen readers either read out the filename or skip the image entirely, and search engines lose the image context. Write <img src="image.jpg" alt="description">; for purely decorative images use alt="" to mark them as intentionally empty rather than dropping the attribute. Reserve space with width="300" height="200" so the layout does not jump, and when a caption is needed wrap the img in <figure> with a <figcaption> — that is more meaningful than a bare img.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 21, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us