Skip to content

定义

超文本标记语言(英语:HyperText Markup Language,简称:HTML)是一种用来结构化 Web 网页及其内容的标记语言。HTML 提供了网页的骨架和语义结构,与 CSS(样式)和 JavaScript(行为)共同构成了现代 Web 开发的基础技术栈。

1. 基本概念

1.1 什么是 HTML

HTML 不是一门编程语言,而是一种用于定义内容结构的标记语言(Markup Language)。HTML 由一系列的元素(elements)组成,这些元素可以用来包围不同部分的内容,使其以某种方式呈现或者工作。

核心特点:

  • 标记语言:使用标签(tags)来描述文档结构
  • 超文本:支持链接到其他文档或资源
  • 平台无关:可在任何设备和浏览器上运行
  • 开放标准:由 W3C 维护的开放标准
html
<p>My cat is very grumpy</p>

1.2 HTML 发展历程

  • HTML 1.0 (1991):最初的 HTML 规范,包含基本的标签
  • HTML 2.0 (1995):标准化版本,增加了表单元素
  • HTML 3.2 (1997):增加了表格、脚本和更多样式选项
  • HTML 4.01 (1999):严格的规范,引入了 CSS
  • XHTML 1.0 (2000):基于 XML 的更严格的 HTML 版本
  • HTML5 (2014):当前主要版本,支持多媒体和语义化标签
  • HTML5.1/5.2 (2016-2017):持续改进和新特性
  • HTML5.3 (2023):最新标准,包含更多 Web 组件特性

1.3 HTML 元素详解

1.3.1 元素组成结构

一个完整的 HTML 元素由以下几个部分组成:

html
<p class="editor-note">My cat is very grumpy</p>

主要组成部分:

  • 开始标签(Opening Tag)<p class="editor-note">
    • 元素名称:p
    • 属性:class="editor-note"
  • 内容(Content)My cat is very grumpy
  • 结束标签(Closing Tag)</p>

1.3.2 标签和元素的区别

  • 标签(Tag):只是 <p></p> 这样的标记
  • 元素(Element):开始标签 + 内容 + 结束标签的完整组合

1.3.3 属性(Attributes)

属性为元素提供额外信息,常见的属性类型:

html
<!-- 基础属性 -->
<div id="header" class="main-header">...</div>

<!-- 事件属性 -->
<button onclick="alert('Hello!')">点击我</button>

<!-- 数据属性 -->
<div data-user-id="123" data-role="admin">...</div>

<!-- ARIA 属性(无障碍) -->
<button aria-label="关闭对话框" aria-expanded="false">×</button>

<!-- 自定义属性(data-*) -->
<div data-component="user-card" data-variant="dark">...</div>

属性命名规范:

  • 使用小写字母
  • 多词属性使用连字符分隔:data-user-id
  • 布尔属性可以省略值:<input disabled> 等同于 <input disabled="disabled">

1.4 空元素(Void Elements)

不包含任何内容的元素称为空元素自闭合元素。这些元素只有一个开始标签,没有结束标签。

html
<!-- 常见空元素 -->
<img src="images/firefox-icon.png" alt="My test image">
<br>
<hr>
<input type="text" name="username">
<link rel="stylesheet" href="styles.css">
<meta charset="utf-8">

<!-- HTML5 空元素可以省略斜杠 -->
<img src="image.jpg" alt="description">
<img src="image.jpg" alt="description" />

常用空元素列表:

  • <img> - 图像
  • <br> - 换行
  • <hr> - 水平分割线
  • <input> - 输入框
  • <link> - 外部资源链接
  • <meta> - 元数据
  • <source> - 媒体源
  • <track> - 文本轨道
  • <area> - 图像映射区域
  • <base> - 基础 URL
  • <col> - 表格列
  • <embed> - 嵌入内容
  • <param> - 参数
  • <wbr> - 单词换行机会
  • <keygen> - 密钥对生成器(已废弃)

1.5 嵌套元素

HTML 元素可以嵌套在其他元素内部,形成层次结构:

html
<div class="article">
  <h1>文章标题</h1>
  <p>这是第一段文字,包含 <em>强调</em> 和 <strong>加粗</strong> 文本。</p>
  <div class="meta">
    <span class="author">作者:张三</span>
    <span class="date">2023-01-01</span>
  </div>
</div>

嵌套规则:

  • 块级元素可以包含块级和行内元素
  • 行内元素通常只能包含其他行内元素或文本
  • 某些元素有特定的嵌套限制(如 <p> 不能包含其他块级元素)
  • 必须正确闭合标签,避免交叉嵌套

2. HTML文档详解

2.1 完整 HTML 文档结构

一个完整的 HTML5 文档包含以下基本结构:

html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <!-- 基础元数据 -->
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  
  <!-- SEO 优化 -->
  <title>网页标题 - 网站名称</title>
  <meta name="description" content="网页描述,用于搜索引擎结果展示">
  <meta name="keywords" content="关键词1,关键词2,关键词3">
  <meta name="author" content="作者名称">
  
  <!-- 外部资源 -->
  <link rel="stylesheet" href="styles.css">
  <link rel="icon" href="favicon.ico" type="image/x-icon">
  
  <!-- Open Graph 标签 -->
  <meta property="og:title" content="网页标题">
  <meta property="og:description" content="网页描述">
  <meta property="og:image" content="https://example.com/image.jpg">
  <meta property="og:url" content="https://example.com/page">
  <meta property="og:type" content="website">
  
  <!-- 其他头部信息 -->
  <meta name="robots" content="index,follow">
</head>
<body>
  <!-- 页面可见内容 -->
  <header>
    <h1>网站标题</h1>
    <nav>
      <ul>
        <li><a href="#home">首页</a></li>
        <li><a href="#about">关于</a></li>
        <li><a href="#contact">联系</a></li>
      </ul>
    </nav>
  </header>
  
  <main>
    <article>
      <h2>文章标题</h2>
      <p>文章内容...</p>
    </article>
  </main>
  
  <footer>
    <p>&copy; 2023 版权信息</p>
  </footer>
  
  <!-- JavaScript 文件 -->
  <script src="script.js"></script>
</body>
</html>

2.1.1 文档声明

  • <!DOCTYPE html>:HTML5 的文档类型声明,告诉浏览器使用 HTML5 标准解析页面

2.1.2 根元素

  • <html lang="zh-CN">:根元素,包含整个页面内容
  • lang 属性指定页面语言,有助于无障碍访问和搜索引擎优化

2.1.3 头部元素(<head>

头部元素包含页面元数据,对用户不可见:

基础元数据:

html
<meta charset="UTF-8">                    <!-- 字符编码 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">  <!-- 响应式视口 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">  <!-- IE 兼容模式 -->

SEO 优化标签:

html
<title>页面标题 - 网站名称</title>
<meta name="description" content="页面描述(建议50-160字符)">
<meta name="keywords" content="关键词1,关键词2,关键词3">
<meta name="author" content="作者名称">
<meta name="robots" content="index,follow">

外部资源链接:

html
<link rel="stylesheet" href="styles.css">
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://cdn.example.com">

2.1.4 主体元素(<body>

主体元素包含用户可见的所有内容,建议使用语义化标签:

html
<body>
  <!-- 头部区域 -->
  <header>...</header>
  
  <!-- 导航区域 -->
  <nav>...</nav>
  
  <!-- 主要内容区域 -->
  <main>
    <article>...</article>
    <aside>...</aside>
  </main>
  
  <!-- 页脚区域 -->
  <footer>...</footer>
</body>

2.2 图像(Images)

图像是网页中重要的视觉元素,HTML 提供了多种图像相关的标签和属性。

2.2.1 基础图像标签

html
<img src="images/firefox-icon.png" alt="Firefox 浏览器图标" width="32" height="32">

主要属性:

  • src:图像路径(必需)
  • alt:替代文本(必需,用于无障碍访问)
  • widthheight:图像尺寸(建议设置,避免页面布局抖动)
  • title:鼠标悬停时显示的提示文本
  • loading="lazy":延迟加载,提升性能
  • decoding="async":异步解码,不影响其他内容渲染

2.2.2 响应式图像

html
<!-- 使用 srcset 属性 -->
<img src="image-small.jpg"
     srcset="image-small.jpg 480w,
             image-medium.jpg 768w,
             image-large.jpg 1024w"
     sizes="(max-width: 480px) 480px,
            (max-width: 768px) 768px,
            1024px"
     alt="响应式图像示例">

<!-- 使用 picture 元素 -->
<picture>
  <source media="(max-width: 600px)" srcset="image-mobile.webp" type="image/webp">
  <source media="(max-width: 600px)" srcset="image-mobile.jpg" type="image/jpeg">
  <source srcset="image-desktop.webp" type="image/webp">
  <img src="image-desktop.jpg" alt="图片描述">
</picture>

2.2.3 图像格式选择

html
<!-- WebP 格式(现代浏览器,体积小) -->
<img src="image.webp" alt="描述">

<!-- 传统格式(兼容性好) -->
<img src="image.jpg" alt="描述"> <!-- 照片类图片 -->
<img src="image.png" alt="描述"> <!-- 透明背景、图标类图片 -->

<!-- SVG 矢量图(可缩放) -->
<img src="icon.svg" alt="图标描述">

<!-- SVG 直接嵌入(无需额外请求) -->
<svg width="24" height="24" viewBox="0 0 24 24">
  <path d="M12 2L2 7v10c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V7l-10-5z"/>
</svg>

2.2.4 图像最佳实践

  • 始终提供 alt 属性,即使是空的 alt=""
  • 设置 width 和 height,避免布局抖动
  • 使用合适的图像格式,平衡质量和文件大小
  • 实施延迟加载,提升页面性能
  • 提供多种格式,确保兼容性
  • 优化图像大小,使用压缩工具

链接是 HTML 的核心特性,使网页能够相互连接形成网络。

2.3.1 基础链接

html
<!-- 外部链接 -->
<a href="https://www.mozilla.org/zh-CN/about/manifesto/">Mozilla Manifesto</a>

<!-- 内部链接(相对路径) -->
<a href="/about.html">关于我们</a>
<a href="#section1">跳转到第一部分</a>

<!-- 邮件链接 -->
<a href="mailto:someone@example.com?subject=Hello&body=消息内容">发送邮件</a>

<!-- 电话链接(移动端) -->
<a href="tel:+8613800138000">拨打电话</a>

2.3.2 链接属性

html
<!-- 在新标签页打开 -->
<a href="https://example.com" target="_blank" rel="noopener noreferrer">外部链接</a>

<!-- 下载链接 -->
<a href="/files/document.pdf" download="report.pdf">下载 PDF</a>

<!-- 带提示的链接 -->
<a href="https://example.com" title="访问示例网站">示例网站</a>

<!-- 安全属性 -->
<a href="https://external.com" rel="noopener noreferrer nofollow">外部链接</a>

2.3.3 链接状态和伪类

html
<style>
/* 不同链接状态 */
a:link { color: blue; }          /* 未访问 */
a:visited { color: purple; }     /* 已访问 */
a:hover { color: red; }         /* 鼠标悬停 */
a:focus { color: orange; }       /* 焦点状态 */
a:active { color: darkred; }    /* 点击时 */
</style>

2.3 标题(Heading)

标题元素可用于指定内容的标题和子标题。就像一本书的书名、每章的大标题、小标题,等。HTML 文档也是一样。HTML 包括六个级别的标题, <h1> (en-US)–<h6> (en-US) ,一般最多用到 3-4 级标题。

html
<h1>主标题</h1>
<h2>顶层标题</h2>
<h3>子标题</h3>
<h4>次子标题</h4>

2.4 段落(Paragraph)

<p>元素是用来指定段落的。通常用于指定常规的文本内容:

html
<p>这是一个段落</p>

2.5 列表(Lists)

列表是网页中常用的内容组织方式,HTML 提供了多种列表类型。

2.5.1 无序列表(Unordered List)

项目顺序不重要时的列表,使用 <ul> 元素:

html
<ul>
  <li>苹果</li>
  <li>香蕉</li>
  <li>橙子</li>
</ul>

<!-- 嵌套列表 -->
<ul>
  <li>水果
    <ul>
      <li>苹果</li>
      <li>香蕉</li>
    </ul>
  </li>
  <li>蔬菜
    <ul>
      <li>胡萝卜</li>
      <li>白菜</li>
    </ul>
  </li>
</ul>

2.5.2 有序列表(Ordered List)

项目顺序重要时的列表,使用 <ol> 元素:

html
<ol>
  <li>第一步:准备材料</li>
  <li>第二步:开始烹饪</li>
  <li>第三步:享用美食</li>
</ol>

<!-- 自定义起始数字 -->
<ol start="5">
  <li>第五个项目</li>
  <li>第六个项目</li>
</ol>

<!-- 反序列表 -->
<ol reversed>
  <li>最后一个项目</li>
  <li>倒数第二个项目</li>
  <li>倒数第三个项目</li>
</ol>

<!-- 不同类型 -->
<ol type="A">
  <li>第一个项目</li>
  <li>第二个项目</li>
</ol>

2.5.3 描述列表(Description List)

用于术语及其描述的列表,使用 <dl><dt><dd> 元素:

html
<dl>
  <dt>HTML</dt>
  <dd>超文本标记语言,用于创建网页的标准标记语言</dd>
  
  <dt>CSS</dt>
  <dd>层叠样式表,用于设置网页的样式和布局</dd>
  
  <dt>JavaScript</dt>
  <dd>一种编程语言,用于实现网页的交互功能</dd>
</dl>

<!-- 多个描述 -->
<dl>
  <dt>水果</dt>
  <dd>富含维生素和纤维的健康食品</dd>
  <dd>建议每天食用适量水果</dd>
  
  <dt>蔬菜</dt>
  <dd>提供矿物质和膳食纤维</dd>
</dl>

2.5.4 列表样式定制

html
<style>
/* 自定义列表标记 */
ul.custom {
  list-style-type: none; /* 移除默认标记 */
  padding-left: 0;
}

ul.custom li {
  position: relative;
  padding-left: 20px;
}

ul.custom li::before {
  content: "→"; /* 自定义标记 */
  position: absolute;
  left: 0;
  color: #ff6b6b;
}

/* 罗马数字列表 */
ol.roman {
  list-style-type: upper-roman;
}

/* 方形标记列表 */
ul.square {
  list-style-type: square;
}
</style>

2.6 表格(Tables)

表格用于展示结构化的数据,适合二维关系的信息展示。

2.6.1 基础表格结构

html
<table>
  <thead>
    <tr>
      <th>姓名</th>
      <th>年龄</th>
      <th>职业</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>张三</td>
      <td>28</td>
      <td>工程师</td>
    </tr>
    <tr>
      <td>李四</td>
      <td>32</td>
      <td>设计师</td>
    </tr>
  </tbody>
</table>

2.6.2 完整表格结构

html
<table>
  <caption>员工信息表</caption>
  
  <colgroup>
    <col class="name-column">
    <col class="age-column">
    <col class="job-column">
  </colgroup>
  
  <thead>
    <tr>
      <th scope="col">姓名</th>
      <th scope="col">年龄</th>
      <th scope="col">职业</th>
    </tr>
  </thead>
  
  <tbody>
    <tr>
      <th scope="row">张三</th>
      <td>28</td>
      <td>工程师</td>
    </tr>
    <tr>
      <th scope="row">李四</th>
      <td>32</td>
      <td>设计师</td>
    </tr>
  </tbody>
  
  <tfoot>
    <tr>
      <th scope="row">总计</th>
      <td colspan="2">2名员工</td>
    </tr>
  </tfoot>
</table>

2.6.3 表格高级功能

html
<table class="responsive-table">
  <caption>复杂表格示例</caption>
  
  <!-- 合并单元格 -->
  <tr>
    <td rowspan="2">部门</td>
    <td>前端组</td>
    <td>5人</td>
  </tr>
  <tr>
    <td>后端组</td>
    <td>3人</td>
  </tr>
  
  <!-- 合并列 -->
  <tr>
    <td>备注</td>
    <td colspan="2">共8名开发人员</td>
  </tr>
</table>

<style>
/* 响应式表格 */
.responsive-table {
  width: 100%;
  border-collapse: collapse;
}

.responsive-table th,
.responsive-table td {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}

.responsive-table th {
  background-color: #f2f2f2;
  font-weight: bold;
}
</style>

2.7 表单(Forms)

表单用于收集用户输入,是 Web 应用中最重要的交互元素之一。

2.7.1 基础表单结构

html
<form action="/submit" method="POST" enctype="multipart/form-data">
  <!-- 表单字段 -->
  <div class="form-group">
    <label for="username">用户名:</label>
    <input type="text" id="username" name="username" required>
  </div>
  
  <div class="form-group">
    <label for="password">密码:</label>
    <input type="password" id="password" name="password" required minlength="8">
  </div>
  
  <div class="form-group">
    <label for="email">邮箱:</label>
    <input type="email" id="email" name="email" required>
  </div>
  
  <div class="form-group">
    <button type="submit">提交</button>
    <button type="reset">重置</button>
  </div>
</form>

2.7.2 输入类型详解

html
<!-- 文本输入 -->
<input type="text" placeholder="请输入文本">
<input type="password" placeholder="密码">
<input type="email" placeholder="邮箱地址">
<input type="url" placeholder="网址">
<input type="tel" placeholder="电话号码">

<!-- 数值输入 -->
<input type="number" min="1" max="100" step="1" value="50">
<input type="range" min="0" max="100" step="5" value="50">

<!-- 日期时间 -->
<input type="date" min="2023-01-01" max="2023-12-31">
<input type="time" value="09:00">
<input type="datetime-local">
<input type="month">
<input type="week">

<!-- 选择输入 -->
<input type="checkbox" name="agree" id="agree">
<input type="radio" name="gender" value="male" id="male">
<input type="radio" name="gender" value="female" id="female">

<!-- 文件上传 -->
<input type="file" accept=".jpg,.png,.pdf" multiple>

<!-- 特殊输入 -->
<input type="color" value="#ff6b6b">
<input type="search" placeholder="搜索...">
<input type="hidden" name="csrf_token" value="abc123">

2.7.3 下拉选择

html
<!-- 基础选择框 -->
<select name="city" id="city">
  <option value="">请选择城市</option>
  <option value="beijing">北京</option>
  <option value="shanghai">上海</option>
  <option value="guangzhou">广州</option>
</select>

<!-- 分组选择框 -->
<select name="department">
  <optgroup label="技术部门">
    <option value="frontend">前端组</option>
    <option value="backend">后端组</option>
    <option value="qa">测试组</option>
  </optgroup>
  <optgroup label="业务部门">
    <option value="sales">销售组</option>
    <option value="marketing">市场组</option>
  </optgroup>
</select>

<!-- 多选下拉框 -->
<select name="skills" multiple size="4">
  <option value="html">HTML</option>
  <option value="css">CSS</option>
  <option value="javascript">JavaScript</option>
  <option value="react">React</option>
  <option value="vue">Vue</option>
</select>

2.7.4 文本区域

html
<textarea name="message" rows="4" cols="50" placeholder="请输入留言..." maxlength="500"></textarea>

<!-- 带字符计数的文本区域 -->
<div class="char-counter">
  <textarea name="bio" rows="3" maxlength="200" placeholder="个人简介..."></textarea>
  <span class="counter">0/200</span>
</div>

2.7.5 表单验证

html
<form novalidate>
  <!-- HTML5 验证属性 -->
  <input type="text" required minlength="2" maxlength="20" pattern="[A-Za-z]{2,20}" 
         title="请输入2-20个字母">
  
  <input type="email" required placeholder="example@domain.com">
  
  <input type="number" min="18" max="100" required>
  
  <!-- 自定义验证消息 -->
  <input type="text" id="custom-input" required>
  <div class="error-message" id="custom-error"></div>
</form>

<script>
const input = document.getElementById('custom-input');
const errorMessage = document.getElementById('custom-error');

input.addEventListener('invalid', (e) => {
  e.preventDefault();
  errorMessage.textContent = '请输入正确的信息';
});
</script>

3. HTML5 新特性

3.1 HTML5 概述

HTML5 是最新的 HTML 标准,带来了革命性的改进:

  • 丰富的内容支持:无需插件即可承载丰富的 Web 内容
  • 语义化改进:新的语义化元素提升文档结构
  • 多媒体支持:原生音视频支持
  • 图形能力:Canvas 2D、WebGL、SVG
  • 数据存储:本地存储、会话存储、IndexedDB
  • 跨平台性:在 PC、平板、手机、电视等多种设备上运行
  • 性能提升:更快的解析和渲染
  • API 丰富:地理定位、Web Sockets、Web Workers 等

3.2 新增语义化元素

3.2.1 文档结构元素

html
<!DOCTYPE html>
<html lang="zh-CN">
<body>
  <header>
    <h1>网站标题</h1>
    <nav>主导航</nav>
  </header>
  
  <main>
    <article>
      <header>
        <h2>文章标题</h2>
        <time datetime="2023-01-01">2023年1月1日</time>
      </header>
      
      <section>
        <h3>第一节</h3>
        <p>第一部分内容...</p>
      </section>
      
      <section>
        <h3>第二节</h3>
        <p>第二部分内容...</p>
      </section>
    </article>
    
    <aside>
      <h3>相关链接</h3>
      <ul>
        <li><a href="#">链接1</a></li>
        <li><a href="#">链接2</a></li>
      </ul>
    </aside>
  </main>
  
  <footer>
    <p>&copy; 2023 版权信息</p>
  </footer>
</body>
</html>

3.2.2 文本级语义元素

html
<p>
  这是一段包含<mark>高亮文本</mark>的段落。
  我们可以使用<time datetime="2023-12-25">圣诞节</time>来标记时间。
  <abbr title="World Wide Web">WWW</abbr>是万维网的缩写。
  <bdo dir="rtl">这段文字会从右向左显示</bdo>
</p>

<figure>
  <img src="chart.png" alt="销售图表">
  <figcaption>图1:2023年销售数据</figcaption>
</figure>

3.3 多媒体支持

3.3.1 音频(Audio)

html
<!-- 基础音频 -->
<audio controls>
  <source src="audio.mp3" type="audio/mpeg">
  <source src="audio.ogg" type="audio/ogg">
  <p>您的浏览器不支持音频播放。</p>
</audio>

<!-- 带字幕的音频 -->
<audio controls>
  <source src="audio.mp3" type="audio/mpeg">
  <track src="subtitles.vtt" kind="subtitles" srclang="zh-CN" label="中文字幕">
</audio>

<!-- 自动播放音频(注意用户体验) -->
<audio autoplay loop muted>
  <source src="background.mp3" type="audio/mpeg">
</audio>

3.3.2 视频(Video)

html
<!-- 基础视频 -->
<video controls width="640" height="360" poster="poster.jpg">
  <source src="video.mp4" type="video/mp4">
  <source src="video.webm" type="video/webm">
  <p>您的浏览器不支持视频播放。</p>
</video>

<!-- 响应式视频 -->
<div class="video-container">
  <video controls>
    <source src="video.mp4" type="video/mp4">
  </video>
</div>

<style>
.video-container {
  position: relative;
  padding-bottom: 56.25%; /* 16:9 比例 */
  height: 0;
  overflow: hidden;
}

.video-container video {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
</style>

3.4 Canvas 绘图

html
<canvas id="myCanvas" width="400" height="300">
  您的浏览器不支持 Canvas。
</canvas>

<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// 绘制矩形
ctx.fillStyle = '#ff6b6b';
ctx.fillRect(10, 10, 100, 50);

// 绘制圆形
ctx.beginPath();
ctx.arc(200, 100, 50, 0, 2 * Math.PI);
ctx.fillStyle = '#4ecdc4';
ctx.fill();

// 绘制文字
ctx.font = '20px Arial';
ctx.fillStyle = '#333';
ctx.fillText('Hello Canvas!', 100, 200);
</script>

3.5 SVG 矢量图形

html
<!-- 内联 SVG -->
<svg width="200" height="200" viewBox="0 0 200 200">
  <circle cx="100" cy="100" r="50" fill="#ff6b6b" />
  <rect x="50" y="50" width="100" height="100" fill="#4ecdc4" opacity="0.5" />
  <text x="100" y="150" text-anchor="middle" font-family="Arial" font-size="16" fill="#333">
    SVG 文本
  </text>
</svg>

3.6 数据存储 API

html
<script>
// LocalStorage 示例
localStorage.setItem('username', '张三');
localStorage.setItem('preferences', JSON.stringify({
  theme: 'dark',
  language: 'zh-CN'
}));

const username = localStorage.getItem('username');
const preferences = JSON.parse(localStorage.getItem('preferences'));

// SessionStorage 示例(页面关闭后清除)
sessionStorage.setItem('tempData', '临时数据');
const tempData = sessionStorage.getItem('tempData');
</script>

3.7 新的表单元素

html
<!-- 新的输入类型 -->
<input type="date" min="2023-01-01" max="2023-12-31">
<input type="time" step="60">
<input type="datetime-local">
<input type="month">
<input type="week">
<input type="color" value="#ff6b6b">
<input type="range" min="0" max="100" value="50">
<input type="number" step="0.1">

<!-- 新的表单元素 -->
<datalist id="browsers">
  <option value="Chrome">
  <option value="Firefox">
  <option value="Safari">
  <option value="Edge">
</datalist>
<input list="browsers" placeholder="选择浏览器">

<progress value="70" max="100">70%</progress>
<meter value="6" min="0" max="10" low="3" high="8">6/10</meter>

3.8 其他重要特性

  • 地理定位 API:获取用户地理位置
  • Web Workers:后台线程处理
  • Web Sockets:实时双向通信
  • 拖放 API:原生拖放功能
  • 历史 API:浏览器历史记录管理
  • 通知 API:系统通知
  • 全屏 API:全屏显示

4. HTML 语义化

4.1 语义化定义

HTML 语义化是指根据内容的结构化选择合适的标签,使得:

  1. 内容语义化:使用能够表达内容含义的标签
  2. 代码语义化:编写清晰、可读、可维护的代码
html
<!-- 不语义化的代码 -->
<div class="header">...</div>
<div class="content">
  <div class="article">
    <div class="title">文章标题</div>
    <div class="meta">发布时间:2023-01-01</div>
    <div class="text">文章内容...</div>
  </div>
</div>
<div class="footer">...</div>

<!-- 语义化的代码 -->
<header>...</header>
<main>
  <article>
    <h1>文章标题</h1>
    <time datetime="2023-01-01">发布时间:2023-01-01</time>
    <p>文章内容...</p>
  </article>
</main>
<footer>...</footer>

4.2 语义化原则

4.2.1 语义化标签选择指南

html
<!-- 文档结构语义化 -->
<header>     <!-- 页面或区域头部 -->
<nav>        <!-- 导航链接集合 -->
<main>       <!-- 主要内容区域 -->
<article>    <!-- 独立的内容单元 -->
<section>    <!-- 内容的章节或部分 -->
<aside>      <!-- 侧边栏或相关内容 -->
<footer>     <!-- 页面或区域底部 -->

<!-- 文本内容语义化 -->
<h1>-<h6>    <!-- 标题层级,重要性递减 -->
<p>          <!-- 段落文本 -->
<strong>     <!-- 重要内容,语气强调 -->
<em>         <!-- 强调内容,语气改变 -->
<mark>       <!-- 高亮标记的文本 -->
<blockquote> <!-- 长段引用 -->
<q>          <!-- 短句引用 -->
<code>       <!-- 代码片段 -->
<pre>        <!-- 预格式化文本 -->
<cite>       <!-- 作品标题引用 -->
<abbr>       <!-- 缩写词 -->
<dfn>        <!-- 术语定义 -->

<!-- 列表语义化 -->
<ul>         <!-- 无序列表 -->
<ol>         <!-- 有序列表 -->
<li>         <!-- 列表项 -->
<dl>         <!-- 定义列表 -->
<dt>         <!-- 定义术语 -->
<dd>         <!-- 定义描述 -->

<!-- 表格语义化 -->
<table>      <!-- 表格容器 -->
<caption>    <!-- 表格标题 -->
<thead>      <!-- 表格头部 -->
<tbody>      <!-- 表格主体 -->
<tfoot>      <!-- 表格底部 -->
<th>         <!-- 表头单元格 -->
<td>         <!-- 数据单元格 -->

<!-- 表单语义化 -->
<form>       <!-- 表单容器 -->
<fieldset>   <!-- 相关表单字段组 -->
<legend>     <!-- 字段组标题 -->
<label>      <!-- 表单控件标签 -->
<button>     <!-- 按钮 -->
<input>      <!-- 输入控件 -->
<select>      <!-- 下拉选择 -->
<textarea>   <!-- 多行文本输入 -->

4.2.2 语义化最佳实践

html
<!-- ✅ 正确的语义化实践 -->
<article class="blog-post">
  <header class="post-header">
    <h1 class="post-title">如何编写语义化 HTML</h1>
    <div class="post-meta">
      <time datetime="2023-01-01" class="post-date">2023年1月1日</time>
      <address class="post-author">作者:张三</address>
    </div>
  </header>
  
  <div class="post-content">
    <section>
      <h2>什么是语义化</h2>
      <p>语义化是指使用正确的 HTML 标签来表达内容的含义...</p>
      <blockquote cite="https://www.w3.org">
        <p>"Semantic HTML is the use of HTML markup to reinforce the semantics, or meaning, of the information in webpages."</p>
      </blockquote>
    </section>
    
    <section>
      <h2>语义化的好处</h2>
      <ul>
        <li><strong>可访问性提升</strong>:屏幕阅读器能够正确理解页面结构</li>
        <li><strong>SEO 优化</strong>:搜索引擎更好地理解页面内容</li>
        <li><strong>代码可维护性</strong>:代码结构清晰,易于理解和维护</li>
      </ul>
    </section>
  </div>
  
  <footer class="post-footer">
    <nav class="post-navigation">
      <a href="#previous" rel="prev">上一篇</a>
      <a href="#next" rel="next">下一篇</a>
    </nav>
  </footer>
</article>

4.3 语义化的好处

4.3.1 可访问性改善

html
<!-- 为屏幕阅读器提供更好的结构 -->
<form>
  <fieldset>
    <legend>用户信息</legend>
    
    <div class="form-group">
      <label for="username">用户名:</label>
      <input type="text" id="username" name="username" required 
             aria-required="true" aria-describedby="username-help">
      <small id="username-help">请输入3-20个字符的用户名</small>
    </div>
    
    <div class="form-group">
      <label for="password">密码:</label>
      <input type="password" id="password" name="password" required
             aria-required="true">
    </div>
    
    <button type="submit" aria-label="提交用户注册表单">注册</button>
  </fieldset>
</form>

4.3.2 SEO 优化

html
<!-- 搜索引擎友好的结构 -->
<article itemscope itemtype="https://schema.org/Article">
  <header>
    <h1 itemprop="headline">HTML5 语义化最佳实践</h1>
    <time itemprop="datePublished" datetime="2023-01-01">2023年1月1日</time>
    <address itemprop="author" itemscope itemtype="https://schema.org/Person">
      <span itemprop="name">张三</span>
    </address>
  </header>
  
  <div itemprop="articleBody">
    <p>文章内容...</p>
  </div>
  
  <footer>
    <nav>
      <a href="#comments" itemprop="discussionUrl">查看评论 (15)</a>
    </nav>
  </footer>
</article>

4.3.3 代码可维护性

html
<!-- 清晰的代码结构,易于理解和维护 -->
<body>
  <!-- 头部区域 -->
  <header role="banner">
    <h1>网站标题</h1>
    <nav role="navigation" aria-label="主导航">
      <ul>
        <li><a href="#home">首页</a></li>
        <li><a href="#about">关于</a></li>
        <li><a href="#contact">联系</a></li>
      </ul>
    </nav>
  </header>
  
  <!-- 主要内容 -->
  <main role="main">
    <article role="article">
      <h2>文章标题</h2>
      <p>文章内容...</p>
    </article>
  </main>
  
  <!-- 侧边栏 -->
  <aside role="complementary">
    <h3>相关链接</h3>
    <nav aria-label="相关导航">
      <ul>
        <li><a href="#">链接1</a></li>
        <li><a href="#">链接2</a></li>
      </ul>
    </nav>
  </aside>
  
  <!-- 页脚 -->
  <footer role="contentinfo">
    <p>&copy; 2023 版权信息</p>
  </footer>
</body>

4.4 语义化检查工具

4.4.1 浏览器开发者工具

  • Elements 面板:检查 HTML 结构
  • Accessibility 面板:检查可访问性
  • Lighthouse:综合性能和可访问性检查

4.4.2 在线验证工具

  • W3C Markup Validation Service:HTML 语法验证
  • HTML5 Outliner:文档大纲结构检查
  • axe DevTools:可访问性检查
  • WAVE Web Accessibility Evaluation Tool:可访问性评估

4.4.3 语义化常见误区

html
<!-- ❌ 误区1:过度使用 div -->
<div class="article">
  <div class="title">标题</div>
  <div class="content">内容</div>
  <div class="date">日期</div>
</div>

<!-- ✅ 正确做法:使用语义化标签 -->
<article>
  <h2>标题</h2>
  <p>内容</p>
  <time datetime="2023-01-01">2023年1月1日</time>
</article>

<!-- ❌ 误区2:错误使用标题层级 -->
<h3>主标题</h3>
<h5>子标题</h5>
<h2>另一个主标题</h2>

<!-- ✅ 正确做法:保持标题层级连续 -->
<h1>主标题</h1>
<h2>子标题</h2>
<h3>子子标题</h3>

<!-- ❌ 误区3:忽略 alt 属性 -->
<img src="photo.jpg">

<!-- ✅ 正确做法:提供有意义的 alt 文本 -->
<img src="photo.jpg" alt="一位程序员在电脑前工作的照片">

4.5 语义化发展趋势

HTML 的发展趋势是更加语义化和结构化

  1. HTML5 语义化标签<article>, <section>, <nav>, <header>, <footer>
  2. 微数据(Microdata):结构化数据标记
  3. JSON-LD:基于 JSON 的链接数据
  4. Web Components:自定义语义化组件
  5. ARIA 属性:增强可访问性的语义化

语义化是现代 Web 开发的核心原则之一,它不仅影响代码质量,还直接影响用户体验、搜索引擎优化和可访问性。

5. 响应式 HTML

5.1 视口配置

响应式设计的基础是正确的视口配置:

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

视口参数说明:

  • width=device-width:视口宽度等于设备宽度
  • initial-scale=1.0:初始缩放比例
  • minimum-scale=1.0:最小缩放比例
  • maximum-scale=1.0:最大缩放比例
  • user-scalable=no:禁止用户缩放(不推荐)

5.2 响应式图片

html
<!-- 使用 srcset 实现响应式图片 -->
<img src="image-small.jpg"
     srcset="image-small.jpg 480w,
             image-medium.jpg 768w,
             image-large.jpg 1024w,
             image-xlarge.jpg 1200w"
     sizes="(max-width: 480px) 480px,
            (max-width: 768px) 768px,
            (max-width: 1024px) 1024px,
            1200px"
     alt="响应式图片示例">

<!-- 使用 picture 元素 -->
<picture>
  <source media="(max-width: 600px)" srcset="image-mobile.webp" type="image/webp">
  <source media="(max-width: 600px)" srcset="image-mobile.jpg" type="image/jpeg">
  <source srcset="image-desktop.webp" type="image/webp">
  <img src="image-desktop.jpg" alt="图片描述">
</picture>

5.3 响应式表格

html
<style>
/* 基础响应式表格 */
.responsive-table {
  width: 100%;
  border-collapse: collapse;
}

.responsive-table th,
.responsive-table td {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}

/* 小屏幕设备 */
@media screen and (max-width: 600px) {
  .responsive-table {
    display: block;
    overflow-x: auto;
  }
  
  .responsive-table thead {
    display: none;
  }
  
  .responsive-table tbody,
  .responsive-table tr,
  .responsive-table td {
    display: block;
    width: 100%;
  }
  
  .responsive-table tr {
    margin-bottom: 15px;
    border: 1px solid #ddd;
  }
  
  .responsive-table td {
    border: none;
    border-bottom: 1px solid #eee;
    position: relative;
    padding-left: 50%;
  }
  
  .responsive-table td:before {
    position: absolute;
    top: 6px;
    left: 6px;
    width: 45%;
    padding-right: 10px;
    white-space: nowrap;
    font-weight: bold;
    content: attr(data-label);
  }
}
</style>

<table class="responsive-table">
  <thead>
    <tr>
      <th>姓名</th>
      <th>年龄</th>
      <th>职业</th>
      <th>城市</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td data-label="姓名">张三</td>
      <td data-label="年龄">28</td>
      <td data-label="职业">工程师</td>
      <td data-label="城市">北京</td>
    </tr>
  </tbody>
</table>

6. HTML 性能优化

6.1 资源加载优化

html
<!-- 预加载关键资源 -->
<link rel="preload" href="critical.css" as="style">
<link rel="preload" href="hero-image.jpg" as="image">
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

<!-- 预连接外部域名 -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="dns-prefetch" href="https://cdn.example.com">

<!-- 延迟加载图片 -->
<img src="placeholder.jpg" 
     data-src="real-image.jpg" 
     loading="lazy" 
     alt="延迟加载的图片"
     class="lazy-load">

<script>
// 延迟加载实现
document.addEventListener('DOMContentLoaded', function() {
  const lazyImages = document.querySelectorAll('img.lazy-load');
  
  if ('IntersectionObserver' in window) {
    const imageObserver = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const img = entry.target;
          img.src = img.dataset.src;
          img.classList.remove('lazy-load');
          imageObserver.unobserve(img);
        }
      });
    });
    
    lazyImages.forEach(img => imageObserver.observe(img));
  } else {
    // 兼容回退
    lazyImages.forEach(img => {
      img.src = img.dataset.src;
      img.classList.remove('lazy-load');
    });
  }
});
</script>

6.2 关键资源优化

html
<!-- 关键 CSS 内联 -->
<style>
/* 首屏关键样式 */
body { margin: 0; font-family: Arial, sans-serif; }
.hero { height: 100vh; background: linear-gradient(45deg, #4ecdc4, #44a08d); }
.hero-content { display: flex; align-items: center; justify-content: center; }
</style>

<!-- 非关键 CSS 异步加载 -->
<link rel="preload" href="non-critical.css" as="style" 
      onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="non-critical.css"></noscript>

<!-- JavaScript 延迟执行 -->
<script src="analytics.js" defer></script>
<script src="non-critical.js" async></script>

6.3 缓存策略

html
<!-- 静态资源缓存 -->
<link rel="stylesheet" href="styles.v123456.css">
<script src="script.v123456.js"></script>

<!-- Service Worker 缓存 -->
<script>
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js')
      .then(registration => {
        console.log('SW registered: ', registration);
      })
      .catch(registrationError => {
        console.log('SW registration failed: ', registrationError);
      });
  });
}
</script>

7. HTML 可访问性

7.1 基础可访问性

html
<!-- 语义化标签 -->
<header role="banner">
  <nav role="navigation" aria-label="主导航">
    <ul>
      <li><a href="#home" aria-current="page">首页</a></li>
      <li><a href="#about">关于</a></li>
    </ul>
  </nav>
</header>

<main role="main">
  <article aria-labelledby="article-title">
    <h2 id="article-title">文章标题</h2>
    <p>文章内容...</p>
  </article>
</main>

<!-- 跳转链接 -->
<a href="#main-content" class="skip-link">跳转到主要内容</a>
<a href="#navigation" class="skip-link">跳转到导航</a>

<!-- 键盘导航支持 -->
<button onclick="toggleMenu()" 
        onkeydown="handleMenuKeydown(event)"
        aria-expanded="false"
        aria-controls="menu"
        aria-haspopup="true">
  菜单
</button>

7.2 表单可访问性

html
<form role="form" aria-labelledby="form-title">
  <h2 id="form-title">用户注册</h2>
  
  <fieldset>
    <legend>个人信息</legend>
    
    <div class="form-group">
      <label for="username" id="username-label">
        用户名 <span aria-label="必填字段">*</span>
      </label>
      <input type="text" 
             id="username" 
             name="username"
             required
             aria-required="true"
             aria-describedby="username-help username-error"
             aria-invalid="false">
      <small id="username-help">请输入3-20个字符的用户名</small>
      <div id="username-error" class="error-message" role="alert" aria-live="polite"></div>
    </div>
    
    <div class="form-group">
      <label for="password">密码 <span aria-label="必填字段">*</span></label>
      <input type="password" 
             id="password" 
             name="password"
             required
             aria-required="true"
             aria-describedby="password-help">
      <small id="password-help">密码长度至少8位</small>
    </div>
  </fieldset>
  
  <button type="submit" aria-label="提交用户注册表单">注册</button>
</form>

7.3 媒体可访问性

html
<!-- 图片可访问性 -->
<img src="team-photo.jpg" 
     alt="团队成员在公司会议室的合影,5个人围坐在会议桌旁"
     longdesc="team-photo-description.html"
     width="600" 
     height="400">

<!-- 视频可访问性 -->
<video controls>
  <source src="video.mp4" type="video/mp4">
  <track src="subtitles-chinese.vtt" 
         kind="subtitles" 
         srclang="zh-CN" 
         label="中文字幕">
  <track src="captions-chinese.vtt" 
         kind="captions" 
         srclang="zh-CN" 
         label="中文字幕(音效描述)">
  <track src="descriptions-chinese.vtt" 
         kind="descriptions" 
         srclang="zh-CN" 
         label="音频描述">
</video>

<!-- 音频可访问性 -->
<audio controls>
  <source src="podcast.mp3" type="audio/mpeg">
  <track src="podcast-transcript.vtt" 
         kind="captions" 
         srclang="zh-CN" 
         label="文字稿">
</audio>

8. HTML 最佳实践总结

8.1 代码质量

  1. 使用语义化标签:选择合适的 HTML5 语义化元素
  2. 保持代码整洁:适当的缩进、注释和空格
  3. 验证 HTML 代码:使用 W3C 验证器检查语法
  4. 遵循标准规范:遵循 W3C HTML 标准
  5. 编写可维护代码:结构清晰,易于理解和修改

8.2 性能考虑

  1. 优化资源加载:合理使用 preload、prefetch
  2. 图片优化:选择合适的格式,实施延迟加载
  3. 减少 HTTP 请求:合并文件,使用图标字体
  4. 启用缓存:设置合适的缓存策略
  5. 压缩资源:压缩 HTML、CSS、JavaScript

8.3 可访问性

  1. 提供替代文本:为图片、视频提供 alt 文本和字幕
  2. 支持键盘导航:确保所有功能可通过键盘访问
  3. 使用 ARIA 属性:增强可访问性
  4. 提供跳转链接:帮助用户快速导航到主要内容
  5. 确保颜色对比:保证足够的颜色对比度

8.4 SEO 优化

  1. 合理使用标题:保持标题层级结构
  2. 提供元数据:完善 title、description、keywords
  3. 使用结构化数据:Schema.org 微数据标记
  4. 优化 URL 结构:语义化、简洁的 URL
  5. 内部链接优化:合理的锚文本和链接结构

9. 常见问题和解决方案

9.1 跨浏览器兼容性

html
<!-- HTML5 兼容性 -->
<!--[if lt IE 9]>
<script src="html5shiv.min.js"></script>
<![endif]-->

<!-- 条件注释 -->
<!--[if IE]>
<link rel="stylesheet" href="ie.css">
<![endif]-->

<!-- Meta 标签兼容 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

9.2 常见错误及修正

html
<!-- ❌ 错误:忘记 alt 属性 -->
<img src="photo.jpg">

<!-- ✅ 正确:提供有意义的 alt 文本 -->
<img src="photo.jpg" alt="一张展示产品特点的图片">

<!-- ❌ 错误:不正确的嵌套 -->
<p><div>错误嵌套</div></p>

<!-- ✅ 正确:合理嵌套 -->
<div><p>正确嵌套</p></div>

<!-- ❌ 错误:重复的 ID -->
<div id="content">内容1</div>
<div id="content">内容2</div>

<!-- ✅ 正确:使用唯一的 ID -->
<div id="content1">内容1</div>
<div id="content2">内容2</div>
<!-- 或者使用 class -->
<div class="content">内容1</div>
<div class="content">内容2</div>

参考资料与更多内容:

  1. MDN 学习Web开发
  2. W3C HTML教程
  3. W3C HTML5教程
  4. HTML5 语义化
  5. Web 可访问性指南
  6. 性能优化最佳实践
  7. 响应式设计
  8. Schema.org 结构化数据