应使用语义化 <ol> 和 <li> 实现课程目录,嵌套 <ol> 管理小节,用 start 属性跳号,::marker 自定义样式;每章独立包裹 <details> 实现可折叠;锚点 id 需合法命名且避免隐藏;移动端用 position: sticky 固定目录。

用语义化 <ol> 和 <li> 实现带编号的课程目录
课程目录本质是有序内容列表,<ol> 是唯一符合语义且默认支持自动编号的标签。别用 <div> + CSS 计数器模拟,那会破坏可访问性,屏幕阅读器无法识别层级和顺序。
实操建议:
- 每一章用一个
<li>,章内小节用嵌套<ol>(不要用<ul>,否则编号逻辑断裂) - 避免手动写 “1.”、“2.”——浏览器自动处理,且支持
start属性跳号(比如续接上一页面:<ol start="5">) - 如需自定义编号样式(如 “第1章”),用 CSS 的
::marker伪元素,而非在 HTML 里硬编码文字
用 <details> + <summary> 做可折叠章节(无需 JS)
用户常想点开/收起某章内容,原生 <details> 就是为此设计的。比手写 JS 切换 display 更轻量、更健壮,还自带 ARIA 状态。
常见错误现象:
立即学习“前端免费学习笔记(深入)”;
- 给
<summary>加onclick或监听toggle事件再手动控制显隐——多余,浏览器已内置行为 - 把整个章节目录包进一个
<details>——这样只能整体开关,应为每章独立包裹 - 忽略默认箭头样式冲突:某些 CSS 重置会清掉
<summary>的 disclosure triangle,需用list-style或::marker恢复
锚点跳转失效?检查 id 命名和空格问题
课程目录点击跳到对应章节,靠的是 <a href="#chapter2"> → <h2 id="chapter2">。看似简单,但实际踩坑最多。
使用场景与参数差异:
-
id值不能以数字开头(id="1-intro"非法,应为id="chap1-intro") - 中文或空格会编码成
%E4%B8%AD%E6%96%87,导致链接失效;一律用短横线分隔的小写字母(id="shi-yong-fang-fa") - 确保目标元素存在且未被
display: none或visibility: hidden隐藏(<details>展开前,目标元素在 DOM 中仍存在,可正常锚点跳转)
移动端目录太长?用 position: sticky 固定导航区
当课程页滚动时,希望目录始终可见,position: sticky 是最直接解法。比 JS 监听 scroll 再 toggle class 更稳定,性能也更好。
性能与兼容性影响:
- 必须设置有效的
top值(如top: 1rem),否则不生效 - 父容器不能有
overflow: hidden或transform(会创建新的层叠上下文,截断 sticky 行为) - iOS Safari 旧版本(sticky 在
<details>内的支持不稳定,可加transform: translateZ(0)强制硬件加速作为临时缓解
最易被忽略的是语义层级:目录不只是视觉列表,它承担着文档结构、SEO 和辅助技术导航三重角色。哪怕只改一个 <ol> 为 <ul>,都可能让视障用户无法感知学习进度。


















