在前端开发内容学习中,HTML列表标签怎么制作文章目录结构的嵌套列表是常见主题。很多人在阅读时会遇到概念分散、步骤不清和注意点难以归纳的问题。本文按照基础概念、操作流程和关键细节,对相关内容进行整理。
HTML目录必须语义正确:子ul/ol必须作为父li的直接子元素;多级编号用CSS counters实现;四层以上推荐details/summary或树形组件;链接路径统一用base href="/"管理。
用 HTML 列表做文章目录,关键不是“看起来像目录”,而是结构语义正确——浏览器、屏幕阅读器、SEO 和键盘导航都依赖这个结构。核心就一条:子列表必须完整写在父级 li 标签内部,否则层级就断了。
错误写法(常见):
把子 <ul> 写在父 </li> 之后、同级位置,或者塞进 <div> 里再放进去——这在 DOM 中是平级关系,不是父子关系。
后果:JS 找不到父项、aria-expanded 失效、Tab 键跳不过去、读屏软件读作“两个独立列表”。
正确写法只有一种:
子 <ul> 或 <ol> 必须是父 <li> 的直接子元素:
HTML 原生 <ol> 不支持跨层编号继承。哪怕你写三层 <ol type="1"><ol type="a"><ol type="i">,浏览器也只按当前层重置计数,不会自动拼出 “2.3.1”。
可靠方案是用 CSS 计数器:
<ol class="toc"> 设置 counter-reset: sec
<li> 触发 counter-increment: sec
::before + counters(sec, ".") 生成带分隔符的编号例如:
ol.toc { counter-reset: sec; }
ol.toc > li { counter-increment: sec; }
ol.toc > li::before { content: counters(sec, ".") ". "; }
ol.toc ol { counter-reset: sub; }
ol.toc ol > li { counter-increment: sub; }
ol.toc ol > li::before { content: counters(sec, ".") "." counters(sub, ".") " "; }
四层以上嵌套不仅编号难控,视觉上也拥挤,可访问性下降明显。W3C 不推荐过深纯 HTML 嵌套。
更实用的选择:
<details><summary> —— 原生可折叠、键盘友好、无需 JS、自带焦点管理多级目录下相对路径极易出错。比如从 /guide/ch1.html 跳到 /api/v2/core.html,手写 ../../api/v2/core.html 很容易漏掉层级。
解决办法是在 <head> 加一行:
<base href="/">
之后所有链接统一写根路径:href="guide/ch1.html"、href="api/v2/core.html"。
注意:href 值结尾必须带斜杠(/docs/ ≠ /docs),且本地 file:// 协议下不生效,需起本地服务测试。