跳到主要内容

HTML 基础语法

本章将介绍 HTML 的基本语法,包括文档结构、标签使用和属性设置。理解这些基础概念是编写规范、高质量 HTML 代码的前提。

HTML 文档结构

基本结构

每个 HTML 文档都遵循相同的结构:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面标题</title>
</head>
<body>
<!-- 页面内容 -->
</body>
</html>

DOCTYPE 声明详解

<!DOCTYPE html>

DOCTYPE 声明位于文档最开头,它的作用是告诉浏览器使用哪种渲染模式。

为什么需要 DOCTYPE?

在 Web 发展早期,不同浏览器对 HTML 的解析方式存在差异。为了兼容旧网页,浏览器引入了两种渲染模式:

模式说明
标准模式(Standards Mode)浏览器按照 W3C 标准渲染页面
怪异模式(Quirks Mode)浏览器模拟旧版本行为,可能导致布局异常

<!DOCTYPE html> 的唯一目的就是阻止浏览器进入怪异模式,确保页面按照现代标准渲染。

DOCTYPE 的大小写

DOCTYPE 声明不区分大小写,以下写法都有效:

<!DOCTYPE html>
<!doctype html>
<!DoCtYpE html>

推荐使用小写 <!doctype html> 或标准写法 <!DOCTYPE html>,保持代码风格一致。

历史背景

在 HTML5 之前,DOCTYPE 声明非常复杂,需要引用 DTD(文档类型定义):

<!-- HTML 4.01 严格模式的 DOCTYPE -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<!-- XHTML 1.0 的 DOCTYPE -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

HTML5 简化了这一切,只需要简单的 <!DOCTYPE html>

文档结构逐行解释

<html lang="zh-CN">

<html> 是文档的根元素,所有其他元素都必须是它的后代。lang 属性声明页面语言,这对以下场景至关重要:

  • 搜索引擎优化:帮助搜索引擎识别页面语言
  • 屏幕阅读器:使用正确的发音引擎朗读内容
  • 浏览器翻译:提示浏览器是否需要翻译页面

常用语言代码:

语言代码
简体中文zh-CN
繁体中文zh-TW
英语enen-US
日语ja
韩语ko
<head>

<head> 元素包含文档的元数据,这些信息不会直接显示在页面上,但对浏览器和搜索引擎非常重要。head 中常见的元素包括:

  • <title>:页面标题
  • <meta>:元信息(字符编码、视口设置等)
  • <link>:外部资源链接(CSS、图标等)
  • <style>:内部样式
  • <script>:脚本
  • <base>:基础 URL
<meta charset="UTF-8">

字符编码声明告诉浏览器如何解析文档中的字符。UTF-8 是最推荐的编码方式,它能表示世界上几乎所有语言的字符。

重要提示

字符编码声明应该尽可能靠前,最好放在 <head> 标签后的第一个元素。如果浏览器在解析编码声明前遇到非 ASCII 字符,可能导致乱码。

<meta name="viewport" content="width=device-width, initial-scale=1.0">

视口设置是响应式网页的必备声明。它告诉移动浏览器如何控制页面的缩放和尺寸。

viewport 属性详解:

属性说明示例值
width视口宽度device-width(设备宽度)或具体数值
initial-scale初始缩放比例1.0(不缩放)
maximum-scale最大缩放比例5.0
minimum-scale最小缩放比例1.0
user-scalable是否允许用户缩放yes/no
<title>页面标题</title>

页面标题显示在浏览器标签页上,也是搜索引擎结果中的标题。一个好的标题应该:

  • 简洁明了地描述页面内容
  • 包含重要关键词
  • 控制在 50-60 个字符以内(避免被截断)
  • 采用「页面名 - 网站名」的格式
<body>

<body> 元素包含页面的所有可见内容——文字、图片、视频、表单等。一个页面只能有一个 <body> 元素。

标签语法

双标签

大多数 HTML 标签是双标签,需要成对使用:

<标签名>内容</标签名>

<p>这是一个段落</p>
<h1>这是一级标题</h1>
<div>这是一个容器</div>

开始标签和结束标签的区别在于结束标签多了一个斜杠 /

单标签(自闭合标签)

有些标签没有结束标签,称为自闭合标签或空元素:

<br>    <!-- 换行 -->
<hr> <!-- 水平分隔线 -->
<img> <!-- 图片 -->
<input> <!-- 输入框 -->
<meta> <!-- 元数据 -->
<link> <!-- 外部资源 -->
<area> <!-- 图片映射区域 -->
<base> <!-- 基础 URL -->
<col> <!-- 表格列 -->
<embed> <!-- 嵌入内容 -->
<source><!-- 媒体源 -->
<track> <!-- 媒体轨道 -->
<wbr> <!-- 建议换行点 -->
提示

在 XHTML 和一些严格模式下,自闭合标签需要使用斜杠:<br /><img />。在 HTML5 中两种写法都有效。

标签嵌套

标签可以嵌套,但必须正确闭合,遵循"后开先闭"原则:

<!-- 正确嵌套 -->
<div>
<p>段落内容<strong>加粗文字</strong></p>
</div>

<!-- 错误嵌套:标签交叉 -->
<div>
<p>段落内容<strong>加粗文字</div></strong>
</div>

嵌套层级应该保持清晰,过度嵌套会增加代码复杂度:

<!-- 不推荐:过度嵌套 -->
<div class="wrapper">
<div class="container">
<div class="content">
<div class="article">
<p>文字内容</p>
</div>
</div>
</div>
</div>

<!-- 推荐:扁平结构 -->
<article class="article">
<p>文字内容</p>
</article>

标签嵌套规则

并非所有标签都可以任意嵌套,HTML 有严格的嵌套规则:

块级元素可以包含块级元素和行内元素:

<div>
<p>段落</p>
<span>行内元素</span>
</div>

行内元素只能包含行内元素(部分行内元素有例外):

<span>
<strong>加粗</strong>
<em>斜体</em>
</span>

<!-- 错误:行内元素不能包含块级元素 -->
<span>
<div>这是不允许的</div>
</span>

特殊规则:

  • <p> 标签不能包含块级元素,也不能包含其他 <p> 标签
  • <a> 标签可以包含块级元素(HTML5 新规则),但不能包含其他 <a> 标签
  • 列表元素 <ul><ol> 的直接子元素必须是 <li>
  • <table> 的直接子元素必须是表格相关元素(<thead><tbody><tr> 等)

HTML 属性

基本语法

属性为元素提供额外信息,写在开始标签中:

<标签名 属性名="属性值">内容</标签名>

属性值应该用引号包裹,可以使用单引号或双引号:

<!-- 双引号(推荐) -->
<div class="container">

<!-- 单引号 -->
<div class='container'>

<!-- 属性值包含引号时,使用另一种引号 -->
<div title='他说"你好"'>
<div title="他说'你好'">

全局属性详解

全局属性是所有 HTML 元素都可以使用的属性。理解这些属性对于编写现代、可访问、可维护的 HTML 至关重要。

基础标识属性

id - 唯一标识符

<header id="main-header">
<h1 id="site-title">网站标题</h1>
</header>

<a href="#main-header">返回顶部</a>

id 属性的特点:

  • 在整个文档中必须唯一
  • 用于页面内锚点链接、JavaScript 选择元素、CSS 样式
  • 值不能包含空格
  • 区分大小写
最佳实践

尽量避免使用 id 选择器编写 CSS 样式,因为 id 选择器优先级过高,难以覆盖。推荐使用 id 进行页面内导航和 JavaScript 操作。

class - 类名

<article class="post featured">
<h2 class="post-title">文章标题</h2>
<p class="post-content">文章内容...</p>
</article>

class 属性的特点:

  • 一个元素可以有多个类名,用空格分隔
  • 同一个类名可以在多个元素上使用
  • 是 CSS 样式和 JavaScript 操作的主要方式

style - 内联样式

<p style="color: red; font-size: 18px;">红色文字</p>

style 属性用于直接在元素上添加 CSS 样式。但这种方式不推荐在生产环境使用,因为它:

  • 难以维护和复用
  • 优先级过高
  • 混合了结构和样式

title - 提示信息

<abbr title="超文本标记语言">HTML</abbr>
<a href="document.pdf" title="点击下载 PDF 文档">下载文档</a>

title 属性提供元素的附加信息,通常在鼠标悬停时显示为工具提示。

语言和方向属性

lang - 语言声明

<html lang="zh-CN">
<article lang="en">
<p>This is an English article.</p>
</article>
<p>这是中文内容。</p>

lang 属性声明元素内容的语言,影响:

  • 屏幕阅读器的发音
  • 浏览器的拼写检查
  • 搜索引擎的内容识别

dir - 文本方向

<p dir="ltr">从左到右的文字</p>
<p dir="rtl">从右到左的文字</p>
<p dir="auto">自动检测方向</p>
说明
ltr从左到右(Left to Right)
rtl从右到左(Right to Left),如阿拉伯语、希伯来语
auto由浏览器自动判断

交互和焦点属性

tabindex - Tab 键导航顺序

<button tabindex="1">第一个聚焦</button>
<a href="#" tabindex="2">第二个聚焦</a>
<div tabindex="0">可获得焦点的 div</div>
<span tabindex="-1">只能通过脚本聚焦</span>

tabindex 的值:

行为
负值元素可聚焦,但不能通过 Tab 键导航
0元素可聚焦,可通过 Tab 键导航,顺序由浏览器决定
正值元素可聚焦,按数值从小到大的顺序导航

accesskey - 快捷键

<button accesskey="s">保存 (Alt+S)</button>
<a href="/" accesskey="h">首页 (Alt+H)</a>

accesskey 为元素分配键盘快捷键。不同浏览器的触发方式:

浏览器WindowsMac
ChromeAlt + 键Alt + 键
FirefoxAlt + Shift + 键Alt + Shift + 键
SafariAlt + 键Control + Alt + 键

由于不同浏览器和操作系统的快捷键存在差异,实际应用中使用较少。

autofocus - 自动聚焦

<input type="text" autofocus>
<textarea autofocus></textarea>

页面加载时自动将焦点设置到该元素。一个页面只能有一个元素设置 autofocus

编辑和输入属性

contenteditable - 可编辑内容

<div contenteditable="true">
这段文字可以被用户编辑。
</div>

<div contenteditable="plaintext-only">
只能编辑纯文本,不能粘贴格式。
</div>

<div contenteditable="false">
这段文字不可编辑。
</div>
说明
true 或空字符串元素可编辑
false元素不可编辑
plaintext-only只能编辑纯文本

inputmode - 虚拟键盘提示

<input type="text" inputmode="numeric" placeholder="输入验证码">
<input type="text" inputmode="email" placeholder="输入邮箱">
<input type="text" inputmode="tel" placeholder="输入电话">
<div contenteditable inputmode="url">可编辑的 URL 输入</div>

inputmode 为移动设备提供虚拟键盘类型提示:

键盘类型
none不显示虚拟键盘
text标准文本键盘
numeric数字键盘
tel电话键盘
email邮箱键盘(带 @ 符号)
urlURL 键盘(带 / 和 .com)
decimal小数键盘
search搜索键盘

spellcheck - 拼写检查

<textarea spellcheck="true"></textarea>
<input type="text" spellcheck="false">
<div contenteditable spellcheck="true">可编辑内容</div>

autocapitalize - 自动大写

<input type="text" autocapitalize="words" placeholder="每个单词首字母大写">
<input type="text" autocapitalize="characters" placeholder="全部大写">
<input type="text" autocapitalize="none" placeholder="不自动大写">

autocorrect - 自动纠正

<input type="text" autocorrect="on">
<input type="text" autocorrect="off">

可见性和状态属性

hidden - 隐藏元素

<div hidden>这个元素被隐藏</div>
<section hidden>用户登录后才能看到的内容</section>

hidden 是布尔属性,设置后元素将从布局中完全移除(等同于 display: none)。与 CSS 隐藏的区别是,hidden 属性具有语义含义,表示内容当前不相关。

inert - 禁用交互

<div inert>
<button>这个按钮无法点击</button>
<a href="#">这个链接无法访问</a>
<input type="text" value="无法输入">
</div>

inert 属性使元素及其所有子元素变得"迟钝":

  • 无法点击、聚焦
  • 无法通过 Tab 键导航
  • 屏幕阅读器会跳过

常用于模态对话框的背景遮罩,防止用户与底层内容交互。

draggable - 可拖拽

<div draggable="true">可以拖拽</div>
<img src="photo.jpg" draggable="false">禁止拖拽</img>

结合 JavaScript 的 Drag and Drop API 使用:

<div id="dragItem" draggable="true">拖拽我</div>
<div id="dropZone">放置区域</div>

<script>
const dragItem = document.getElementById('dragItem');
const dropZone = document.getElementById('dropZone');

dragItem.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', 'dragItem');
});

dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
});

dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.appendChild(dragItem);
});
</script>

数据和自定义属性

data- - 自定义数据属性*

<article 
data-id="12345"
data-author="张三"
data-published-date="2024-01-15"
data-view-count="1024">
文章内容...
</article>

data-* 属性允许在 HTML 元素上存储自定义数据,供 JavaScript 使用:

const article = document.querySelector('article');

// 读取数据
console.log(article.dataset.id); // "12345"
console.log(article.dataset.author); // "张三"
console.log(article.dataset.publishedDate); // "2024-01-15"(自动转驼峰)
console.log(article.dataset.viewCount); // "1024"

// 设置数据
article.dataset.category = 'tech';
article.dataset.readTime = '5min';

命名规则:

  • 属性名必须以 data- 开头
  • 属性名只能包含小写字母、数字和连字符
  • JavaScript 中通过 dataset 属性访问,连字符自动转为驼峰命名

无障碍属性

role - 角色

<div role="button">可点击的元素</div>
<nav role="navigation">导航区域</nav>
<div role="dialog">对话框</div>

role 属性为元素定义语义角色,帮助辅助技术理解元素的目的。常用角色:

角色说明
button按钮
link链接
navigation导航区域
main主内容区
article独立文章
dialog对话框
alert警告信息
tablist标签列表
tabpanel标签面板

aria- - 无障碍属性族*

ARIA(Accessible Rich Internet Applications)属性为复杂组件提供额外的无障碍信息:

<!-- 标签和描述 -->
<button aria-label="关闭对话框">×</button>
<input aria-describedby="password-hint">
<span id="password-hint">密码至少8位</span>

<!-- 状态 -->
<button aria-pressed="true">已选中</button>
<div aria-expanded="false" aria-controls="menu">展开菜单</div>
<div id="menu" aria-hidden="true">...</div>

<!-- 值和范围 -->
<div role="slider" aria-valuemin="0" aria-valuemax="100" aria-valuenow="50">
音量: 50%
</div>

<!-- 实时区域 -->
<div role="alert" aria-live="assertive">
操作成功!
</div>

常用的 ARIA 属性:

属性说明
aria-label元素的标签文本
aria-labelledby引用作为标签的元素 ID
aria-describedby引用作为描述的元素 ID
aria-hidden是否对辅助技术隐藏
aria-disabled是否禁用
aria-expanded是否展开
aria-selected是否选中
aria-checked是否勾选
aria-live实时更新通知方式
最佳实践

优先使用原生 HTML 元素(如 <button><nav>),它们内置了无障碍支持。只有在原生元素无法满足需求时,才使用 rolearia-* 属性。

其他属性

translate - 翻译控制

<p translate="yes">这段文字可以被翻译</p>
<code translate="no">console.log('Hello')</code>
<footer translate="no">© 2024 Company Name</footer>

popover - 弹出框

<div popover id="menu">
弹出内容
</div>
<button popovertarget="menu">打开菜单</button>

slot - Web Component 插槽

<user-card>
<span slot="name">张三</span>
<span slot="email">[email protected]</span>
</user-card>

part - Shadow DOM 样式部件

<custom-element part="header"></custom-element>

<style>
custom-element::part(header) {
background: blue;
}
</style>

布尔属性

布尔属性只需要存在就表示"真",不需要值:

<!-- 禁用状态 -->
<input type="text" disabled>
<button disabled>无法点击</button>

<!-- 选中状态 -->
<input type="checkbox" checked>

<!-- 只读状态 -->
<input type="text" readonly value="只读内容">

<!-- 必填字段 -->
<input type="text" required>

<!-- 自动聚焦 -->
<input type="text" autofocus>

<!-- 多选 -->
<input type="file" multiple>

<!-- 音视频属性 -->
<audio controls autoplay loop muted></audio>

布尔属性的正确写法:

<!-- 推荐:只写属性名 -->
<input disabled>

<!-- 也有效:属性名等于属性名 -->
<input disabled="disabled">

<!-- 无效:布尔属性不使用 true/false -->
<!-- <input disabled="true"> -->

## HTML 注释

注释不会显示在页面上,也不会影响页面渲染,主要用于代码说明和调试。

### 注释语法

```html
<!-- 这是单行注释 -->

<!--
这是多行注释
可以写很多行
用于详细说明
-->

注释的用途

1. 代码说明

<!-- 导航栏开始 -->
<nav class="main-nav">
<ul>
<li><a href="/">首页</a></li>
<li><a href="/products">产品</a></li>
</ul>
</nav>
<!-- 导航栏结束 -->

2. 临时禁用代码

<!-- 暂时隐藏的广告位
<div class="advertisement">
<img src="ad.jpg" alt="广告">
</div>
-->

3. 开发调试标记

<!-- TODO: 需要添加响应式样式 -->
<div class="sidebar">...</div>

<!-- FIXME: 在 Safari 下有布局问题 -->
<div class="card">...</div>

<!-- NOTE: 这里依赖第三方 API -->
<div id="map">...</div>

注释注意事项

<!-- 错误:注释不能嵌套 -->
<!-- 外层注释 <!-- 内层注释 --> 外层注释继续 -->

<!-- 正确:避免嵌套,分开写 -->
<!-- 外层注释开始 -->
<!-- 内层注释 -->
<!-- 外层注释结束 -->

<!-- 注意:注释内容不能包含 -- -->
<!-- 错误:这里 -- 不能出现 -->

<!-- 正确:避免在注释中使用连续的横线 -->
<!-- 正确写法 -->

特殊字符(实体引用)

HTML 中有些字符有特殊含义,如果要在内容中使用这些字符,必须使用实体引用(Entity Reference)。

必须转义的字符

在 HTML 内容中,以下字符必须转义:

字符实体说明使用场景
<&lt;小于号在文本中显示 <
>&gt;大于号在文本中显示 >
&&amp;和号在文本中显示 &

常用实体字符

字符实体说明
"&quot;双引号
'&apos;单引号
&nbsp;不换行空格
©&copy;版权符号
®&reg;注册商标
&trade;商标符号
&ndash;短破折号(en dash)
&mdash;长破折号(em dash)
&hellip;省略号
×&times;乘号
÷&divide;除号
&euro;欧元符号
£&pound;英镑符号
¥&yen;人民币/日元符号
°&deg;度数符号
±&plusmn;正负号

数字实体引用

除了命名实体,还可以使用数字编码:

<!-- 十进制 -->
<p>字符 A: &#65;</p>
<p>版权符号: &#169;</p>

<!-- 十六进制 -->
<p>字符 A: &#x41;</p>
<p>欧元符号: &#x20AC;</p>

实际应用示例

<!-- 显示代码片段 -->
<p>使用 &lt;div&gt; 标签创建容器:</p>
<pre>&lt;div class="container"&gt;
内容
&lt;/div&gt;</pre>

<!-- 数学表达式 -->
<p>5 &lt; 10 为真,10 &gt; 5 也为真</p>
<p>价格:商品A &amp; 商品B 共 ¥199</p>

<!-- 版权信息 -->
<footer>
<p>&copy; 2024 公司名称. 保留所有权利.</p>
</footer>

<!-- 不换行空格(避免空白折叠) -->
<p>姓名:&nbsp;&nbsp;&nbsp;&nbsp;张三</p>
<p>版本&nbsp;2.0</p>

属性值中的引号

当属性值中需要包含引号时:

<!-- 属性值包含双引号 -->
<input type="text" value='他说"你好"'>

<!-- 属性值包含单引号 -->
<input type="text" value="他说'你好'">

<!-- 使用实体转义 -->
<input type="text" value="他说&quot;你好&quot;">
<p title='这是&apos;单引号&apos;'>悬停查看</p>

大小写规则

标签和属性名

HTML 标签和属性名不区分大小写:

<!-- 以下写法都有效 -->
<DIV>容器</DIV>
<div>容器</div>
<Div>容器</Div>

<INPUT TYPE="text">
<input type="text">
<Input Type="text">
推荐规范

虽然 HTML 不区分大小写,但强烈推荐使用小写

  • 符合现代 Web 开发规范
  • 提高代码可读性
  • 便于团队协作
  • XHTML 要求必须小写

属性值

属性值通常不区分大小写,但某些属性例外:

<!-- 类名和 ID 区分大小写 -->
<div class="Container"> <!-- 与 class="container" 不同 -->
<div id="MainHeader"> <!-- 与 id="mainheader" 不同 -->

<!-- 语言代码建议使用标准格式 -->
<html lang="zh-CN"> <!-- 推荐 -->
<html lang="ZH-CN"> <!-- 不推荐 -->

<!-- 路径和 URL 通常区分大小写(取决于服务器) -->
<img src="images/Logo.png"> <!-- 可能与 logo.png 不同 -->

空白处理

空白折叠

HTML 会将连续的空白字符(空格、换行、制表符)折叠为一个空格:

<p>这些      空格      会被折叠</p>
<!-- 渲染为:这些 空格 会被折叠 -->

<p>
换行和缩进
也会被折叠
</p>
<!-- 渲染为:换行和缩进 也会被折叠 -->

保留空白的方法

1. 使用 <pre> 标签

<pre>
function hello() {
console.log("Hello!");
}
</pre>

2. 使用 CSS white-space 属性

<p style="white-space: pre;">这里    的空格    会被保留</p>
<p style="white-space: pre-wrap;">自动换行但保留空格 和换行</p>

3. 使用 &nbsp; 实体

<p>多个&nbsp;&nbsp;&nbsp;&nbsp;空格</p>

编码最佳实践

1. 始终声明 DOCTYPE

<!-- 正确 -->
<!DOCTYPE html>
<html>
...

<!-- 错误:缺少 DOCTYPE 可能触发怪异模式 -->
<html>
...

2. 指定字符编码

<head>
<meta charset="UTF-8">
<title>页面标题</title>
</head>

3. 使用语义化标签

<!-- 不推荐:滥用 div -->
<div class="header">网站头部</div>
<div class="nav">导航</div>
<div class="main">主内容</div>

<!-- 推荐:使用语义化标签 -->
<header>网站头部</header>
<nav>导航</nav>
<main>主内容</main>

4. 正确闭合标签

<!-- 不推荐:省略可选的结束标签 -->
<p>第一段
<p>第二段
<ul>
<li>项目一
<li>项目二
</ul>

<!-- 推荐:始终闭合标签 -->
<p>第一段</p>
<p>第二段</p>
<ul>
<li>项目一</li>
<li>项目二</li>
</ul>

5. 属性值使用引号

<!-- 不推荐:省略引号 -->
<div class=container>
<input type=text>

<!-- 推荐:始终使用引号 -->
<div class="container">
<input type="text">

6. 图片必须添加 alt 属性

<!-- 不推荐:缺少 alt -->
<img src="photo.jpg">

<!-- 推荐:提供有意义的描述 -->
<img src="photo.jpg" alt="团队合影,2024年度会议">

<!-- 装饰性图片可以留空 -->
<img src="decoration.svg" alt="">

7. 保持代码可读性

<!-- 推荐:合理的缩进和换行 -->
<article>
<header>
<h2>文章标题</h2>
<time datetime="2024-01-15">2024年1月15日</time>
</header>

<p>文章内容...</p>

<footer>
<p>作者:张三</p>
</footer>
</article>

8. 使用有意义的命名

<!-- 不推荐:无意义的命名 -->
<div class="div1">
<span class="span2">内容</span>
</div>

<!-- 推荐:语义化命名 -->
<article class="post">
<span class="post-date">内容</span>
</article>

完整的 HTML 模板

以下是一个符合现代标准的 HTML 页面模板:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="页面描述,用于搜索引擎">
<title>页面标题 - 网站名称</title>

<!-- 网站图标 -->
<link rel="icon" href="favicon.ico">
<link rel="apple-touch-icon" href="apple-touch-icon.png">

<!-- 外部样式表 -->
<link rel="stylesheet" href="styles.css">
</head>
<body>
<!-- 页面头部 -->
<header>
<nav aria-label="主导航">
<ul>
<li><a href="/">首页</a></li>
<li><a href="/products">产品</a></li>
<li><a href="/about">关于我们</a></li>
</ul>
</nav>
</header>

<!-- 主内容区 -->
<main>
<article>
<header>
<h1>文章标题</h1>
<p>
作者:<span>张三</span> |
发布时间:<time datetime="2024-01-15">2024年1月15日</time>
</p>
</header>

<section>
<h2>章节标题</h2>
<p>段落内容...</p>
</section>
</article>

<aside>
<h2>相关推荐</h2>
<ul>
<li><a href="/article/1">相关文章一</a></li>
<li><a href="/article/2">相关文章二</a></li>
</ul>
</aside>
</main>

<!-- 页面底部 -->
<footer>
<p>&copy; 2024 网站名称. 保留所有权利.</p>
<nav aria-label="底部导航">
<a href="/privacy">隐私政策</a>
<a href="/terms">使用条款</a>
</nav>
</footer>

<!-- 外部脚本 -->
<script src="main.js"></script>
</body>
</html>

常见错误与解决

1. 标签未闭合

<!-- 错误 -->
<div>
<p>内容

<!-- 正确 -->
<div>
<p>内容</p>
</div>

2. 嵌套错误

<!-- 错误:行内元素包含块级元素 -->
<span>
<div>这是不允许的</div>
</span>

<!-- 正确 -->
<div>
<span>这是允许的</span>
</div>

3. 属性值未转义

<!-- 错误 -->
<a title="点击"查看"详情">链接</a>

<!-- 正确 -->
<a title="点击&quot;查看&quot;详情">链接</a>
<a title='点击"查看"详情'>链接</a>

4. 缺少必要的属性

<!-- 错误:图片缺少 alt -->
<img src="photo.jpg">

<!-- 正确 -->
<img src="photo.jpg" alt="风景照片">

小结

本章我们学习了:

  1. 文档结构:DOCTYPE 声明、html、head、body 元素的作用
  2. 标签语法:双标签和单标签、标签嵌套规则
  3. 全局属性:id、class、style、data-、aria- 等完整列表
  4. 布尔属性:disabled、checked、required 等特殊属性
  5. HTML 注释:语法和最佳实践
  6. 特殊字符:实体引用的使用方法
  7. 编码规范:大小写、引号、语义化等最佳实践

练习

  1. 创建一个基本的 HTML 页面,包含完整的文档结构
  2. 为元素添加 id、class 和 data-* 属性,并使用 JavaScript 读取这些属性
  3. 使用注释为代码添加说明,包括 TODO 标记
  4. 在页面中正确显示特殊字符(如 <>&、版权符号)
  5. 创建一个包含语义化结构的页面,使用 header、main、footer 等标签
  6. 为一个自定义组件添加 ARIA 属性,提升可访问性