ul表示无序集合,项目间无先后;ol表示顺序依赖,如步骤、排名;嵌套须语义对齐,禁用CSS隐藏序号而应换用合适标签。

ul 和 ol 的语义区别不能只看序号有无
有数字就用 ol、没数字就用 ul 是常见误解。ol 表达的是**顺序依赖关系**,比如步骤、排名、时间线;ul 表示**项目间无先后、可互换**的集合,比如导航菜单、标签列表、功能特性点。
错误示例:用 ol 列出「关于我们」「联系我们」「加入我们」三个导航项——它们没有执行顺序,用 ol 会误导屏幕阅读器和搜索引擎。
- 表单校验失败提示用
ul:各项独立,顺序无关 - 菜谱制作步骤必须用
ol:第2步依赖第1步完成 - 搜索结果页的分页链接属于「顺序位置」,适合
ol(即使显示为圆点)
嵌套列表必须保持语义层级对齐
嵌套不是为了视觉缩进,而是表达「子集归属」。外层 ul 或 ol 描述一个整体范畴,内层列表必须是该范畴下的细分项,不能跨语义跳跃。
比如「编程语言特性」作为主项,子项可以是「类型系统」「内存管理」「并发模型」;但不能在其中嵌套「Python 安装命令」这种操作步骤——它属于另一个语义域,应单独用 ol 或移到别处。
立即学习“前端免费学习笔记(深入)”;
- 禁止在
ul中直接嵌套ol来“强调顺序”,除非子项天然存在顺序性(如某特性的演化阶段) - 多级导航菜单中,二级菜单是「一级菜单项的子选项」,可用
ul > li > ul,但每个li必须包裹ul,不能ul > ul - 浏览器对
li内容无限制,可包含段落、图片甚至section,但嵌套的列表必须由li包裹
- 前端框架
- React:组件驱动
- Vue:响应式模板
- 构建工具
- Webpack:模块打包
- Vite:按需编译
用 role="list" 和 role="listitem" 补充非标准结构
某些场景下,你无法或不该用原生 ul/ol,比如用 div 实现的虚拟滚动列表、卡片式布局中的横向项目流。此时需手动补全语义,否则屏幕阅读器会忽略其列表本质。
- 仅当 DOM 结构无法使用
ul/ol时才加role,优先用原生元素 -
role="list"必须直接包裹role="listitem",不能中间插div或span - 避免给
li再加role="listitem"——原生li已自带该语义
JavaScriptTypeScriptRust
无障碍细节:不要依赖 CSS 隐藏序号或符号
用 list-style: none 清除 ol 数字后,视觉上没了序号,但屏幕阅读器仍会读出「1.」「2.」——这会造成信息污染。真不需要序号语义,就该换用 ul。
- 若只是想改样式(比如用图标代替圆点),保留
list-style-type并配合::marker伪元素定制 - 用
aria-hidden="true"隐藏序号会同时隐藏整个列表项,不可取 - 动态生成的列表(如 JS 渲染)要确保首次渲染即带正确标签,不要靠 JS 后续补
role
语义化列表的核心,是让结构表达意图,而不是让样式决定结构。很多人调完 CSS 就以为完成了,其实 DOM 层的层级错位和角色缺失,才是影响可访问性和 SEO 的关键点。











