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 |
| 英语 | en 或 en-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 为元素分配键盘快捷键。不同浏览器的触发方式:
| 浏览器 | Windows | Mac |
|---|---|---|
| Chrome | Alt + 键 | Alt + 键 |
| Firefox | Alt + Shift + 键 | Alt + Shift + 键 |
| Safari | Alt + 键 | 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 | 邮箱键盘(带 @ 符号) |
url | URL 键盘(带 / 和 .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>),它们内置了无障碍支持。只有在原生元素无法满足需求时,才使用 role 和 aria-* 属性。
其他属性
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 内容中,以下字符必须转义:
| 字符 | 实体 | 说明 | 使用场景 |
|---|---|---|---|
< | < | 小于号 | 在文本中显示 < |
> | > | 大于号 | 在文本中显示 > |
& | & | 和号 | 在文本中显示 & |
常用实体字符
| 字符 | 实体 | 说明 |
|---|---|---|
" | " | 双引号 |
' | ' | 单引号 |
| | 不换行空格 |
© | © | 版权符号 |
® | ® | 注册商标 |
™ | ™ | 商标符号 |
– | – | 短破折号(en dash) |
— | — | 长破折号(em dash) |
… | … | 省略号 |
× | × | 乘号 |
÷ | ÷ | 除号 |
€ | € | 欧元符号 |
£ | £ | 英镑符号 |
¥ | ¥ | 人民币/日元符号 |
° | ° | 度数符号 |
± | ± | 正负号 |
数字实体引用
除了命名实体,还可以使用数字编码:
<!-- 十进制 -->
<p>字符 A: A</p>
<p>版权符号: ©</p>
<!-- 十六进制 -->
<p>字符 A: A</p>
<p>欧元符号: €</p>
实际应用示例
<!-- 显示代码片段 -->
<p>使用 <div> 标签创建容器:</p>
<pre><div class="container">
内容
</div></pre>
<!-- 数学表达式 -->
<p>5 < 10 为真,10 > 5 也为真</p>
<p>价格:商品A & 商品B 共 ¥199</p>
<!-- 版权信息 -->
<footer>
<p>© 2024 公司名称. 保留所有权利.</p>
</footer>
<!-- 不换行空格(避免空白折叠) -->
<p>姓名: 张三</p>
<p>版本 2.0</p>
属性值中的引号
当属性值中需要包含引号时:
<!-- 属性值包含双引号 -->
<input type="text" value='他说"你好"'>
<!-- 属性值包含单引号 -->
<input type="text" value="他说'你好'">
<!-- 使用实体转义 -->
<input type="text" value="他说"你好"">
<p title='这是'单引号''>悬停查看</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. 使用 实体
<p>多个 空格</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>© 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="点击"查看"详情">链接</a>
<a title='点击"查看"详情'>链接</a>
4. 缺少必要的属性
<!-- 错误:图片缺少 alt -->
<img src="photo.jpg">
<!-- 正确 -->
<img src="photo.jpg" alt="风景照片">
小结
本章我们学习了:
- 文档结构:DOCTYPE 声明、html、head、body 元素的作用
- 标签语法:双标签和单标签、标签嵌套规则
- 全局属性:id、class、style、data-、aria- 等完整列表
- 布尔属性:disabled、checked、required 等特殊属性
- HTML 注释:语法和最佳实践
- 特殊字符:实体引用的使用方法
- 编码规范:大小写、引号、语义化等最佳实践
练习
- 创建一个基本的 HTML 页面,包含完整的文档结构
- 为元素添加 id、class 和 data-* 属性,并使用 JavaScript 读取这些属性
- 使用注释为代码添加说明,包括 TODO 标记
- 在页面中正确显示特殊字符(如
<、>、&、版权符号) - 创建一个包含语义化结构的页面,使用 header、main、footer 等标签
- 为一个自定义组件添加 ARIA 属性,提升可访问性