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

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











