html 根元素
<html> 元素是 HTML 文档的根元素,所有其他 HTML 元素都是它的后代。它定义了整个文档的范围,并承载着文档级别的全局属性。
前置知识
阅读本节前,建议先了解:DOCTYPE 声明
基础概念
什么是根元素
在 HTML 文档的树形结构中,<html> 元素处于最顶层,是整个 DOM 树的根节点。一个标准的 HTML 文档有且仅有一个 <html> 元素,其他所有元素都嵌套在它内部。
<!DOCTYPE html>
<html lang="zh-CN">
<head>...</head>
<body>...</body>
</html>从 DOM 树的角度来看:
Document
└── html
├── head
│ ├── meta
│ ├── title
│ └── link
└── body
├── header
├── main
└── footer<html> 元素通常有两个直接子元素:<head> 和 <body>。
根元素的唯一性
每个 HTML 文档中只能有一个 <html> 根元素。如果出现多个,浏览器只会识别第一个:
<!-- 错误!只能有一个 html 根元素 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head><title>第一个</title></head>
<body><p>第一个文档</p></body>
</html>
<html lang="en">
<head><title>第二个</title></head>
<body><p>第二个文档</p></body>
</html>严重错误
多个 <html> 根元素会导致文档结构不合法,搜索引擎爬虫和辅助工具可能无法正确解析页面。
语法
基本语法
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- 头部信息 -->
</head>
<body>
<!-- 页面内容 -->
</body>
</html>全局属性
<html> 元素作为文档的根元素,可以携带以下重要属性:
| 属性 | 值 | 说明 |
|---|---|---|
lang | 语言代码(如 zh-CN、en) | 指定文档的语言 |
dir | ltr / rtl / auto | 指定文本方向 |
class | 类名 | 为根元素添加类(较少使用) |
id | 标识符 | 为根元素添加 ID(较少使用) |
data-* | 自定义值 | 存储自定义数据 |
manifest | URL | 已废弃,用于离线应用缓存 |
详细说明
lang 属性详解
lang 属性是 <html> 元素最重要的属性,它告诉浏览器和辅助技术页面使用的是什么语言。
为什么 lang 属性很重要
- 搜索引擎优化(SEO):帮助搜索引擎判断页面语言,向正确语言的用户展示结果
- 屏幕阅读器:让屏幕阅读器使用正确的语言来朗读页面内容
- 浏览器翻译:帮助浏览器决定是否提供翻译提示
- 拼写检查:浏览器使用正确的语言字典进行拼写检查
- 字体选择:浏览器可以根据语言选择合适的字体渲染
常用语言代码
lang 属性使用 BCP 47 语言标签,由语言代码和可选的区域代码组成:
| 语言代码 | 含义 | 适用场景 |
|---|---|---|
zh | 中文(通用) | 不区分地区的中文内容 |
zh-CN | 简体中文(中国大陆) | 面向中国大陆用户的网站 |
zh-TW | 繁体中文(台湾) | 面向台湾用户的网站 |
zh-HK | 繁体中文(香港) | 面向香港用户的网站 |
en | 英语(通用) | 不区分地区的英文内容 |
en-US | 英语(美国) | 面向美国用户的网站 |
en-GB | 英语(英国) | 面向英国用户的网站 |
ja | 日语 | 面向日本用户的网站 |
ko | 韩语 | 面向韩国用户的网站 |
fr | 法语 | 面向法国用户的网站 |
de | 德语 | 面向德国用户的网站 |
es | 西班牙语 | 面向西班牙用户的网站 |
lang 属性的使用示例
<!-- 中文简体页面 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>中文网站</title>
</head>
<body>
<h1>欢迎来到我的网站</h1>
</body>
</html><!-- 英文页面 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>English Website</title>
</head>
<body>
<h1>Welcome to My Website</h1>
</body>
</html>多语言页面的 lang 处理
如果页面中包含多种语言的内容,可以在 <html> 上设置主要语言,然后在特定元素上覆盖:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>多语言页面</title>
</head>
<body>
<h1>学习 HTML</h1>
<p>HTML 代表 <span lang="en">HyperText Markup Language</span>。</p>
<p>在法语中,它被称为 <span lang="fr">langage de balisage hypertexte</span>。</p>
</body>
</html>无障碍最佳实践
对于多语言内容,在包含外语的元素上单独设置 lang 属性,能让屏幕阅读器切换到正确的语言来朗读该部分内容。
dir 属性
dir 属性指定元素内容的文本方向:
<!-- 从左到右(默认值,适用于大多数语言) -->
<!DOCTYPE html>
<html lang="zh-CN" dir="ltr">
<!-- 从右到左(适用于阿拉伯语、希伯来语等) -->
<!DOCTYPE html>
<html lang="ar" dir="rtl">| 值 | 说明 | 适用语言 |
|---|---|---|
ltr | 从左到右 | 中文、英文、法文等大多数语言 |
rtl | 从右到左 | 阿拉伯语、希伯来语、波斯语等 |
auto | 由浏览器自动判断 | 混合方向的文本 |
manifest 属性(已废弃)
manifest 属性曾用于指定应用缓存清单文件,但在 HTML5.1 中已被废弃:
<!-- 已废弃!不再推荐使用 -->
<!-- <html lang="zh-CN" manifest="cache.appcache"> -->废弃提示
manifest 属性已被废弃。如果需要离线功能,请使用 Service Worker 代替。应用缓存(Application Cache)已被所有现代浏览器移除。
嵌套结构
<html> 元素内部的标准结构包含 <head> 和 <body> 两个子元素:
<!DOCTYPE html>
<html lang="zh-CN">
<!-- head: 文档元信息区域 -->
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面标题</title>
<link rel="stylesheet" href="styles.css">
<script src="app.js" defer></script>
</head>
<!-- body: 页面可见内容区域 -->
<body>
<header>
<nav>导航</nav>
</header>
<main>
<h1>页面主标题</h1>
<p>页面内容</p>
</main>
<footer>
<p>页脚信息</p>
</footer>
</body>
</html>head 和 body 的顺序
规范要求 <head> 必须在 <body> 之前。虽然浏览器对两者的顺序有一定的容错能力,但遵循标准顺序是最佳实践:
<!-- 正确 -->
<html lang="zh-CN">
<head>...</head>
<body>...</body>
</html>
<!-- 不推荐(浏览器会自动修正) -->
<html lang="zh-CN">
<body>...</body>
<head>...</head>
</html>省略 html 标签的情况
根据 HTML 规范,在以下条件下 <html> 标签可以省略:
- 文档根节点没有被另一个元素包裹
- 根节点之后紧跟一个注释(非必须)
<!-- 以下代码合法,因为浏览器会隐式创建 html 元素 -->
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>省略 html 标签</title>
</head>
<body>
<p>这段代码仍然可以正常工作。</p>
</body>但强烈不推荐省略 <html> 标签,原因如下:
- 无法设置
lang属性,影响 SEO 和无障碍 - 代码可读性降低
- 不符合团队协作的编码规范
实战示例
完整的 HTML5 文档结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- 字符编码 -->
<meta charset="UTF-8">
<!-- 视口设置 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 页面标题 -->
<title>完整的 HTML5 文档结构</title>
<!-- 外部样式表 -->
<link rel="stylesheet" href="css/style.css">
<!-- 外部脚本 -->
<script src="js/app.js" defer></script>
</head>
<body>
<header>
<h1>我的网站</h1>
<nav>
<ul>
<li><a href="/">首页</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>© 2024 我的网站</p>
</footer>
</body>
</html>使用 JavaScript 访问根元素
<!DOCTYPE html>
<html lang="zh-CN" data-theme="light">
<head>
<meta charset="UTF-8">
<title>访问根元素</title>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 600px;
margin: 40px auto;
padding: 0 20px;
}
.output {
background-color: #f5f5f5;
padding: 15px;
border-radius: 4px;
font-family: monospace;
white-space: pre-line;
}
</style>
</head>
<body>
<h1>访问 html 根元素</h1>
<div id="output" class="output"></div>
<script>
var output = document.getElementById('output');
// 方法 1: document.documentElement
var htmlEl = document.documentElement;
output.textContent += 'document.documentElement.tagName: ' + htmlEl.tagName + '\n';
output.textContent += 'lang 属性: ' + htmlEl.lang + '\n';
output.textContent += 'dir 属性: ' + htmlEl.dir + '\n';
output.textContent += 'data-theme: ' + htmlEl.dataset.theme + '\n\n';
// 方法 2: document.getElementsByTagName('html')[0]
var htmlEl2 = document.getElementsByTagName('html')[0];
output.textContent += '通过 getElementsByTagName 获取: ' + htmlEl2.tagName + '\n';
// 方法 3: querySelector
var htmlEl3 = document.querySelector('html');
output.textContent += '通过 querySelector 获取: ' + htmlEl3.tagName + '\n';
</script>
</body>
</html>动态切换主题(通过 html 的 data 属性)
<!DOCTYPE html>
<html lang="zh-CN" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>主题切换</title>
<style>
/* 亮色主题(默认) */
:root {
--bg-color: #ffffff;
--text-color: #333333;
--primary-color: #0066cc;
}
/* 暗色主题 */
[data-theme="dark"] {
--bg-color: #1a1a2e;
--text-color: #e0e0e0;
--primary-color: #4da6ff;
}
body {
background-color: var(--bg-color);
color: var(--text-color);
font-family: system-ui, sans-serif;
transition: background-color 0.3s, color 0.3s;
max-width: 600px;
margin: 40px auto;
padding: 20px;
}
button {
padding: 10px 20px;
background-color: var(--primary-color);
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
</style>
</head>
<body>
<h1>主题切换演示</h1>
<p>点击下方按钮在亮色和暗色主题之间切换。</p>
<button id="toggle-theme">切换到暗色主题</button>
<script>
var toggleBtn = document.getElementById('toggle-theme');
var htmlEl = document.documentElement;
toggleBtn.addEventListener('click', function() {
var currentTheme = htmlEl.getAttribute('data-theme');
if (currentTheme === 'light') {
htmlEl.setAttribute('data-theme', 'dark');
toggleBtn.textContent = '切换到亮色主题';
} else {
htmlEl.setAttribute('data-theme', 'light');
toggleBtn.textContent = '切换到暗色主题';
}
});
</script>
</body>
</html>注意事项
1. lang 属性的常见错误
<!-- 错误!使用了不正确的语言代码 -->
<html lang="cn"> <!-- "cn" 是国家代码,不是语言代码 -->
<html lang="chinese"> <!-- 不能使用语言全名 -->
<html lang="CN"> <!-- 大写的国家代码不是有效的 BCP 47 标签 -->
<!-- 正确 -->
<html lang="zh"> <!-- 中文(通用) -->
<html lang="zh-CN"> <!-- 简体中文 -->2. 不要在 html 上使用过多样式
虽然可以在 <html> 元素上设置样式,但通常应该在 <body> 上设置页面级的样式:
<!-- 不推荐:在 html 上设置过多样式 -->
<html lang="zh-CN" style="font-size: 16px;">
<!-- 推荐:页面级样式放在 body 上 -->
<body style="font-size: 16px;">3. html 标签不是必须闭合的
根据 HTML 规范,<html> 的结束标签可以省略:
<!-- 合法但推荐闭合 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>测试</title>
</head>
<body>
<p>内容</p>
</body>
</html>但为了代码清晰和可维护性,始终建议写上闭合标签。
4. 不要在 html 内部添加文本内容
<html> 元素应该只包含 <head> 和 <body>,不应有直接文本内容:
<!-- 错误!html 内部不应有直接文本 -->
<html lang="zh-CN">
这段文字不该在这里
<head>...</head>
<body>...</body>
</html>最佳实践
1. 始终声明 lang 属性
<!-- 推荐 -->
<!DOCTYPE html>
<html lang="zh-CN">2. 使用精确的语言代码
对于中文网站,建议区分简体和繁体:
<!-- 简体中文 -->
<html lang="zh-CN">
<!-- 繁体中文(台湾) -->
<html lang="zh-TW">
<!-- 繁体中文(香港) -->
<html lang="zh-HK">3. 使用 data-* 属性存储全局数据
<html lang="zh-CN"
data-env="production"
data-version="1.0.0"
data-user-id="12345">4. 代码格式统一
推荐使用 2 个空格缩进,保持标签对齐:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>页面标题</title>
</head>
<body>
<p>页面内容</p>
</body>
</html>下一节
继续学习:head 元素