码上问学问代码之理,学编程之道

单元三 · HTML5 新增标签及属性

让页面「自带骨架」,而不是一坨 div。本单元对应教材单元三(8 学时):结构标签与分组标签、页面交互标签、层次语义标签与全局属性。 学完你会明白:好的 HTML 不用 class 也能让人读懂页面结构——这对可访问性、SEO 和后期维护都关键。

本单元目标:① 能用 header/nav/main/section/article/aside/footer 搭结构,会用 hgroup 组合主副标题;② 掌握页面交互标签 details/summary、dialog、datalist、menu、search;③ 理清层次语义标签与文档大纲;④ 掌握全局属性 class/id/style/title/lang/dir/hidden/data-*/contenteditable/tabindex 的用途与边界。
一、知识准备 ① 结构标签与分组标签 ② 页面交互标签 ③ 层次语义标签 ④ 全局属性 ⑤ 易混概念对比 二、实战演练 三、强化训练 四、课后实训

一、知识准备:结构标签 = 页面的「房间布局」

语义化结构 = 页面的「房间布局」:每个标签是一间房,用途一目了然<header> 页头:logo · 站点名 · 主导航<nav>侧边导航(链接列表)<main> 主要内容<article> 一篇文章<section><section><aside> 侧栏补充相关推荐 · 广告位<footer> 页脚:版权 · 联系方式对浏览器/读屏软件,标签就是「房间门牌」——语义化让机器也看得懂页面

生活类比:住宅户型图

div 像「一个空房间」,你只能靠名字猜用途;语义标签像户型图上的「客厅/卧室/厨房」——<header> 是门厅、<nav> 是走廊指引、<main> 是主厅、<footer> 是后院。结构一目了然。

① 结构标签与分组标签

<header> 页眉/区头<nav> 导航<main> 主内容 <section> 区块<article> 独立文章<aside> 侧栏 <footer> 页脚<hgroup> 标题组合 <figure>/<figcaption> 图与图注<div> 无语义容器
hgroup:主标题 + 副标题
<header>
  <hgroup>
    <h1>网站开发技术</h1>
    <p>HTML5 + CSS3 + JavaScript 项目式教程</p>
  </hgroup>
  <nav><a href="#">首页</a> <a href="#">课程</a></nav>
</header>
效果预览运行结果
要点:副标题用 <p> 写在 hgroup 里,不要为了「小一号」而把它降级成 <h2>——那会进入大纲。

② 页面交互标签:不写 JS 也能交互

生活类比:自带零件的家具

以前想做个「点击展开」,得像自己打家具一样写一堆 JavaScript;现在浏览器把零件做好了——<details> 就是现成的抽屉,<dialog> 就是现成的门帘。用原生标签,连键盘和读屏软件的支持都一起白送。

表 3-1 页面交互标签速览
标签作用关键点
<details>可展开/收起的折叠面板open 属性表示默认展开;折叠是浏览器原生行为
<summary>折叠面板的「标题行」必须是 details 的第一个子元素,点击它切换开合
<dialog>对话框 / 弹窗showModal() 打开模态(遮罩 + 焦点锁定 + Esc 关闭),close() 关闭
<datalist>输入框的「建议下拉」用 input list="id" 关联;只给建议,不限制用户输入
<menu>一组命令 / 工具项是「命令清单」不是「内容清单」;子项仍用 li
<search>搜索区域的语义容器只标语义,不带样式;里面通常放一个 form
<progress>任务进度条表示「一件在推进的事」
<meter>已知范围内的度量值表示「一个静态的量」,如磁盘占用、评分
免 JS 折叠 + 模态框 + 输入建议
<!-- ① 折叠面板:一行 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>
效果预览运行结果
打开模态的方式(写在自己的 JS 里): document.getElementById("confirm").showModal(); // 带遮罩、锁焦点、Esc 可关
故意写错:show() 与 showModal() 不是一个东西——show() 只是把框显示出来,没有遮罩、不锁焦点、底下的内容还能点。要模态效果必须用 showModal()。

③ 层次语义标签:把「层级」写进结构里

生活类比:书的目录

h1~h6 就是目录的层级:书名、章、节、小节。读屏软件正是靠标题层级生成页面目录,让用户一键跳转;搜索引擎也用它判断主题。层次乱,机器就瞎。

层次语义标签的用法
<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>

④ 全局属性:所有标签都能挂的「通用螺丝」

全局属性不属于某一个标签,而是写在任何标签上都有效的通用属性。用得最多的是下面这些。

表 3-2 常用全局属性
属性作用一句话记住
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>
效果预览运行结果
读 data-* 的方式: const li = document.querySelector("li"); li.dataset.id // "42" li.dataset.role // "admin"

⑤ 易混概念对比(考前扫一眼)

表 3-3 本单元最容易考混的 7 组概念
容易混区别怎么选
section / article / divarticle 可独立分发;section 是一章;div 无语义能独立剪走 → article;有标题的一节 → section;只为装东西 → div
details / dialogdetails 就地展开收起;dialog 是浮层弹窗页内展开内容 → details;需要打断用户处理的确认 → dialog
progress / meterprogress 是在推进的任务;meter 是静态的量上传进度 → progress;磁盘占用率 → meter
strong-em / b-i前者有语义、读屏会变语气;后者只是外观表达重要性用 strong/em;纯视觉粗细用 CSS 更好
class / idclass 可重复可多个;id 唯一样式用 class;锚点与 JS 定位用 id
hidden / display:none效果相近,hidden 语义更强「本就不该出现」→ hidden;动画/响应式显隐 → CSS
hgroup / 两个标题hgroup 里的副标题不进大纲主标题 + 副标题 → hgroup + p;两个并列标题 → 拆成两个 section

二、实战演练:语义化页面骨架

文件 1: u3/layout.html (结构标签 + hgroup)
layout.html(结构部分)
<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>
效果预览运行结果
验收标准:F12 打开 Elements,能一眼看出「头 / 主 / 侧 / 脚」四块,且 h1 只有一个。
文件 2: u3/interactive.html (交互标签 + 全局属性)
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 的标签匹配高亮能立刻发现。

三、强化训练

1为什么用 <nav> 比用 <div class="nav"> 更好?(提示:可访问性 / SEO)
2主标题「网站开发技术」下面要加一行副标题「HTML5 项目式教程」,用 hgroup 怎么写?如果不用 hgroup、直接写成 h2 会有什么问题?
3做一个「点击查看答案」的折叠效果,最少需要几个标签?需要写 JavaScript 吗?再说明 show() 与 showModal() 的区别。
4progress 和 meter 分别用在什么场景?各写一行示例代码。
5说明 class 与 id 的差别;再从「谁能复用、谁是唯一」的角度解释为什么做样式优先用 class。
6hidden 和 CSS 的 display:none 效果差不多,为什么要单独学它?data-* 又解决了什么问题?

四、课后实训

作业(交一个能打开的文件):把单元二做的 recipe.html 用语义标签重构—— ① 加 <header><main><section><footer> 搭骨架,标题区用 <hgroup> 放「主标题 + 副标题」; ② 每道菜用 <article> 包起来,菜品图片用 <figure>+<figcaption>; ③ 用 <details><summary> 做一个「小贴士」折叠; ④ 给列表项加 data-dish="菜名",并在文件末尾的脚本里用 dataset 打印出来验证。
提交前自查:h1 是否只有一个?标题有没有跳级?页面隐藏后读屏是否仍能读懂结构?

本单元小结

← 上一单元单元二 · HTML5 语言基础

📝 本节自测

做完点「检查本节」看解析与得分;做错可重做。