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 文档声明,必须写在首行 | <!DOCTYPE html> |
<html lang="zh-CN"> | 根元素,lang 决定读屏发音与翻译提示 | <html lang="zh-CN"> |
<meta charset="UTF-8"> | 字符编码,缺失会导致中文乱码 | <meta charset="UTF-8"> |
<title> | 页面标题,显示在浏览器标签并被搜索引擎采用 | <title>页面标题</title> |
<link rel="stylesheet"> | 引入外部样式表 | <link rel="stylesheet" href="style.css"> |
<script src></script> | 引入外部脚本 | <script src="script.js"></script> |
<strong> / <em> | 语义化强调:重要性与侧重 | <strong>必填</strong> |
<pre> / <code> | 保留空格与换行的代码展示 | <pre>代码块</pre> |
<ul> / <ol> / <dl> | 无序、有序、定义列表 | <ol><li>第一步</li></ol> |
target="_blank" | 在新窗口/标签打开链接 | <a href="url" target="_blank">链接</a> |
href="#id" | 页内锚点跳转 | <a href="#intro">介绍</a> |
alt 属性 | 图片替代文本,缺失会影响可访问性与 SEO | <img src="a.jpg" alt="架构图"> |
width / height | 指定图片尺寸,减少布局抖动 | <img src="a.jpg" width="300" height="200"> |
colspan / rowspan | 表格单元格跨列 / 跨行 | <td colspan="2">合计</td> |
input type | 按类型提供自动校验(text/password/email) | <input type="email" name="email"> |
label for | 把标签与输入框关联,点击标签即可聚焦 | <label for="id">标签</label> |
button type | 区分提交与普通按钮 | <button type="submit">提交</button> |
<main> / <nav> / <aside> | 主内容 / 导航 / 辅助内容分区 | <main>主内容</main> |
Common pitfalls
Symptom页面中文全部显示成乱码方块
Cause缺少 `<meta charset="UTF-8">`,或它被放到了其它会输出内容的标签之后。
Fix把 charset 声明放在 `<head>` 的最前面,确保解析器在读到任何正文前就知道编码。
Symptom读屏软件念不出表单字段名,或点击文字光标不聚焦输入框
Cause输入框没有用 `label` 的 `for` 关联,屏幕阅读器只能读到没有语义的名字。
Fix为每个输入框配一个 `for` 指向其 `id` 的 `<label>`,并把提示文字写进 label 而不是占位符。
Symptom图片加载失败或网络慢时页面大块留白、布局跳动
Cause`<img>` 没有 `alt` 也未声明尺寸,浏览器无法预留空间。
Fix补上描述性的 `alt`,并按实际比例写 `width` / `height`。
SymptomSEO 检查或无障碍审计报「缺少 landmark 区域」
Cause整页都用 `div` 搭建,没有使用 `header`/`nav`/`main`/`footer` 这类语义化标签。
Fix把页面骨架替换成语义标签,`main` 在一个页面里保持唯一,其余无法归类的块再退回 `div`。
Symptom表格在窄屏上挤成一团,单元格内容互相覆盖
Cause该用 `thead`/`th` 表达的结构被写成了普通 `td`,屏幕阅读器也无法关联表头与数据。
Fix表头统一用 `thead` + `th`,数据行用 `tbody` + `td`,跨格场景用 `colspan` / `rowspan` 显式声明。
Symptom表单里点任何按钮都会提交,包括本来只想当普通按钮的那个
Cause`<button>` 缺省就是 `type="submit"`,样式上看不出区别。
Fix明确写 `type="submit"` 或 `type="button"`,让语义与外观一致。
Symptom代码示例里的缩进和换行全被吃掉,显示成一行
Cause代码放进了普通 `<p>`,HTML 会把连续空白折叠成一个空格。
Fix改用 `<pre>` 保留原始排版,行内片段才用 `<code>`。
Troubleshooting
1确认文档骨架与关键元信息是否齐备
grep -nE '<!DOCTYPE html>|<meta charset|<title>|<html lang' index.html四类声明都应出现在文件靠前位置;缺 charset 就是乱码的直接原因。
2检查是否漏写了图片的 alt 属性
grep -c '<img' index.html && grep -n '<img' index.html逐条核对每个 img 是否都有 alt,纯装饰图可写空 alt 以便读屏跳过。
3确认页面只有一个 main 区域
grep -c '<main' index.html输出为 1 才符合规范,多于 1 说明页面骨架被复制粘贴错了。
4核对输入框是否都有对应 label
grep -oE 'name="[^"]+"' index.html输出的 name 列表应与 label for 指向的 id 一一对应,缺一个就是漏关联。
5检查未闭合或错配的标签
python -c "from html.parser import HTMLParser; HTMLParser().feed(open('index.html', encoding='utf-8').read())"把文件喂给标准库解析器,能快速发现标签错配导致的结构塌陷。
Command Examples
Semantic skeleton: exactly one main per page
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<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">姓名</th><th scope="col">年龄</th></tr>
</thead>
<tbody>
<tr><td>Tom</td><td>25</td></tr>
<tr><td>Jerry</td><td colspan="2">合并两列</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">用户名</label>
<input type="text" id="username" name="username">
<select name="gender"><option>男</option></select>
<button type="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="服务器机房机柜全景">
<img src="chart.png" alt="月度转化率折线图" width="300" height="200">
<figure>
<img src="diagram.png" alt="请求链路示意图">
<figcaption>图 1:一次请求经过的三层缓存</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