让页面「自带骨架」,而不是一坨 div。本单元对应教材单元三(8 学时):结构标签与分组标签、页面交互标签、层次语义标签与全局属性。 学完你会明白:好的 HTML 不用 class 也能让人读懂页面结构——这对可访问性、SEO 和后期维护都关键。
hgroup 组合主副标题;② 掌握页面交互标签 details/summary、dialog、datalist、menu、search;③ 理清层次语义标签与文档大纲;④ 掌握全局属性 class/id/style/title/lang/dir/hidden/data-*/contenteditable/tabindex 的用途与边界。div 像「一个空房间」,你只能靠名字猜用途;语义标签像户型图上的「客厅/卧室/厨房」——<header> 是门厅、<nav> 是走廊指引、<main> 是主厅、<footer> 是后院。结构一目了然。
main 一页只能有一个;section 通常自带标题,没有标题就该用 div。figure + figcaption 表示「图/代码/引文 + 它的说明」,它们是一个整体,删掉图注这个图就不完整。<header>
<hgroup>
<h1>网站开发技术</h1>
<p>HTML5 + CSS3 + JavaScript 项目式教程</p>
</hgroup>
<nav><a href="#">首页</a> <a href="#">课程</a></nav>
</header>
以前想做个「点击展开」,得像自己打家具一样写一堆 JavaScript;现在浏览器把零件做好了——<details> 就是现成的抽屉,<dialog> 就是现成的门帘。用原生标签,连键盘和读屏软件的支持都一起白送。
| 标签 | 作用 | 关键点 |
|---|---|---|
<details> | 可展开/收起的折叠面板 | open 属性表示默认展开;折叠是浏览器原生行为 |
<summary> | 折叠面板的「标题行」 | 必须是 details 的第一个子元素,点击它切换开合 |
<dialog> | 对话框 / 弹窗 | showModal() 打开模态(遮罩 + 焦点锁定 + Esc 关闭),close() 关闭 |
<datalist> | 输入框的「建议下拉」 | 用 input list="id" 关联;只给建议,不限制用户输入 |
<menu> | 一组命令 / 工具项 | 是「命令清单」不是「内容清单」;子项仍用 li |
<search> | 搜索区域的语义容器 | 只标语义,不带样式;里面通常放一个 form |
<progress> | 任务进度条 | 表示「一件在推进的事」 |
<meter> | 已知范围内的度量值 | 表示「一个静态的量」,如磁盘占用、评分 |
<!-- ① 折叠面板:一行 JS 都不用写 -->
<details open>
<summary>查看参考答案</summary>
<p>因为 details 是浏览器原生支持的交互元素。</p>
</details>
<!-- ② 模态对话框 -->
<dialog id="confirm">
<p>确定要删除这篇笔记吗?</p>
<button type="button">取消</button>
</dialog>
<!-- ③ 输入建议:只提示、不限制 -->
<label for="city">城市</label>
<input id="city" list="cities" placeholder="输入城市名">
<datalist id="cities">
<option value="北京"></option>
<option value="上海"></option>
</datalist>
show() 与 showModal() 不是一个东西——show() 只是把框显示出来,没有遮罩、不锁焦点、底下的内容还能点。要模态效果必须用 showModal()。h1~h6 就是目录的层级:书名、章、节、小节。读屏软件正是靠标题层级生成页面目录,让用户一键跳转;搜索引擎也用它判断主题。层次乱,机器就瞎。
<strong> 是「很重要」、<em> 是「重音强调」(有语义,读屏会改变语气);<b>/<i> 只是「粗一点/斜一点」(无强调语义)。语义优先。<mark> 高亮标记、<time> 日期时间、<data> 机器可读值、<ruby>/<rt> 注音、<wbr> 可选换行、<bdi>/<bdo> 双向文字、<address> 联系方式。<time datetime="2026-10-15"> 给日历看,<data value="10086">苹果</data> 给程序看——显示的归人,取值的归机器。<article>
<h2>校园读书月</h2>
<h3>活动安排</h3> <!-- 逐级向下,不跳级 -->
<p>时间:<time datetime="2026-11-05">2026 年 11 月 5 日</time></p>
<p>价格:<data value="39.9">39.9 元</data>(早鸟价)</p>
<p>请重点复习 <strong>盒子模型</strong>,<em>务必</em>动手写一遍。</p>
<p>日语「<ruby>桜<rt>さくら</rt><rp>(</rp><rp>)</rp></ruby>」指樱花。</p>
<address>报名咨询:<a href="mailto:hi@example.com">hi@example.com</a></address>
</article>
全局属性不属于某一个标签,而是写在任何标签上都有效的通用属性。用得最多的是下面这些。
| 属性 | 作用 | 一句话记住 |
|---|---|---|
class | 类名,可重复、可多个(空格分隔) | 「班牌」——一批元素共用样式,做样式优先用它 |
id | 唯一标识,文档内不可重复 | 「身份证号」——锚点跳转、label 关联、JS 精准定位 |
style | 行内样式 | 优先级最高却最难维护;只在动态计算时用 |
title | 鼠标悬停的补充说明 | 不是「标题」;触屏看不到,关键信息别只写这里 |
lang | 声明内容语言(zh-CN / en) | 读屏软件据此决定发音 |
dir | 书写方向 ltr / rtl / auto | 阿拉伯语等从右往左的文字 |
hidden | 隐藏该元素 | 语义化隐藏;做动画显隐请改用 CSS 类 |
data-* | 自定义数据,JS 用 dataset 读写 | 给元素贴「自己写的便利贴」,数据与样式解耦 |
contenteditable | 内容可直接编辑 | 网页里的「白板」;提交前必须转义,防 XSS |
tabindex | 键盘 Tab 顺序(0 / -1 / 正数) | 正数会打乱焦点顺序,慎用;-1 = 可编程聚焦 |
draggable | 是否可拖拽 | 配合 dragstart / drop 事件做拖放 |
spellcheck / translate | 拼写检查 / 自动翻译开关 | 代码、品牌名要设 false / no |
role / aria-* | 给辅助技术补充角色与状态 | 能用原生元素就不用 ARIA;用错比不用更糟 |
<!-- class 与 id:一个管一批,一个管唯一 -->
<p class="note warn">这是一条警告</p>
<h2 id="install">安装步骤</h2>
<a href="#install">跳到「安装步骤」</a>
<!-- data-*:把数据挂在元素上,JS 随取随用 -->
<li data-id="42" data-role="admin">小明</li>
<!-- 代码与品牌名:关掉拼写检查与翻译 -->
<p spellcheck="false">vscode.html</p>
<p translate="no">码上问学</p>
<!-- 可编辑区域:像白板一样直接改 -->
<div contenteditable="true">点这里就能编辑我</div>
| 容易混 | 区别 | 怎么选 |
|---|---|---|
| section / article / div | article 可独立分发;section 是一章;div 无语义 | 能独立剪走 → article;有标题的一节 → section;只为装东西 → div |
| details / dialog | details 就地展开收起;dialog 是浮层弹窗 | 页内展开内容 → details;需要打断用户处理的确认 → dialog |
| progress / meter | progress 是在推进的任务;meter 是静态的量 | 上传进度 → progress;磁盘占用率 → meter |
| strong-em / b-i | 前者有语义、读屏会变语气;后者只是外观 | 表达重要性用 strong/em;纯视觉粗细用 CSS 更好 |
| class / id | class 可重复可多个;id 唯一 | 样式用 class;锚点与 JS 定位用 id |
| hidden / display:none | 效果相近,hidden 语义更强 | 「本就不该出现」→ hidden;动画/响应式显隐 → CSS |
| hgroup / 两个标题 | hgroup 里的副标题不进大纲 | 主标题 + 副标题 → hgroup + p;两个并列标题 → 拆成两个 section |
u3/layout.html (结构标签 + hgroup)<header>
<hgroup>
<h1>古典文学网</h1>
<p>读一首诗,识一段史</p>
</hgroup>
<nav><a href="#">首页</a> <a href="#">文库</a></nav>
</header>
<main>
<section>
<h2>唐诗精选</h2>
<article>
<h3>静夜思</h3>
<p>床前明月光……</p>
</article>
</section>
<aside>热门榜单</aside>
</main>
<footer>© 古典文学网</footer>
u3/interactive.html (交互标签 + 全局属性)<search>
<form action="#">
<input type="search" list="kw" placeholder="搜索古诗">
<button>搜索</button>
</form>
<datalist id="kw">
<option value="静夜思"></option>
<option value="春晓"></option>
</datalist>
</search>
<section>
<h2>学习小贴士</h2>
<details>
<summary>为什么要语义化?</summary>
<p>可访问性、SEO、可维护性——三赢。</p>
</details>
<p>上传进度:<progress value="30" max="100">30%</progress></p>
<p>磁盘占用:<meter value="0.72" min="0" max="1">72%</meter></p>
</section>
<ul>
<li data-id="101" data-tag="唐诗">静夜思</li>
<li data-id="102" data-tag="宋词">如梦令</li>
</ul>
<summary> 写到 <details> 外面 → 折叠失效;
show() 打开对话框 → 没有遮罩、底下能点;
</section> 和 </article> 顺序写反 → 浏览器会「容错」但结构乱掉,靠 VS Code 的标签匹配高亮能立刻发现。<nav> 比用 <div class="nav"> 更好?(提示:可访问性 / SEO)show() 与 showModal() 的区别。progress 和 meter 分别用在什么场景?各写一行示例代码。class 与 id 的差别;再从「谁能复用、谁是唯一」的角度解释为什么做样式优先用 class。hidden 和 CSS 的 display:none 效果差不多,为什么要单独学它?data-* 又解决了什么问题?recipe.html 用语义标签重构——
① 加 <header><main><section><footer> 搭骨架,标题区用 <hgroup> 放「主标题 + 副标题」;
② 每道菜用 <article> 包起来,菜品图片用 <figure>+<figcaption>;
③ 用 <details><summary> 做一个「小贴士」折叠;
④ 给列表项加 data-dish="菜名",并在文件末尾的脚本里用 dataset 打印出来验证。
做完点「检查本节」看解析与得分;做错可重做。