应避免在ol的li中直接嵌入checkbox,否则会破坏序号显示、样式兼容性和可访问性;推荐用CSS计数器+伪元素生成序号,并通过flex布局控制复选框与文本对齐。

ol 里直接加 <input type="checkbox"> 会破坏语义和样式
HTML 的 <ol></ol> 是有序列表,浏览器默认用数字、字母等标记项序号。如果在 <li> 里硬塞 <input type="checkbox">,虽然能显示复选框,但会导致:
• 序号(如 “1.”)和复选框并排,视觉混乱;
• list-style 可能被干扰,尤其在 Safari 或旧版 Edge 中;
• 屏幕阅读器可能误读结构,把复选框当成列表内容而非交互控件。
推荐方案:用 CSS 重置 list-style,手动控制序号 + 复选框布局
核心思路是放弃依赖浏览器自动生成的序号,改用 ::before 伪元素生成数字,并把复选框作为 <li> 的第一子元素显式排列。
• 给 <ol></ol> 设 counter-reset: item;
• 给 <li> 设 counter-increment: item;
• 用 <li>::before</li> 显示 counter(item);
• 把 <input type="checkbox"> 放在 <li> 开头,用 display: flex 或 grid 控制对齐。
<ol class="checkbox-list"> <li><input type="checkbox"> 第一项</li> <li><input type="checkbox"> 第二项</li> </ol>
.checkbox-list {
counter-reset: item;
padding-left: 0;
}
.checkbox-list li {
counter-increment: item;
display: flex;
align-items: center;
gap: 8px;
}
.checkbox-list li::before {
content: counter(item) ".";
font-weight: bold;
min-width: 2em;
text-align: right;
}
如果必须保留原生 ol 序号,只能靠 JS 动态注入(不推荐)
某些 CMS 或受限环境不允许改 HTML 结构,这时只能用 JS 在每个 <li> 开头插入复选框:
• 不能用 innerHTML 破坏原有文本节点;
• 要用 insertBefore() 插入新节点;
• 需监听后续动态添加的 <li>(如通过 MutationObserver);
• 每次插入后要重新计算序号显示逻辑,容易和原生序号冲突。
更实际的做法是:接受语义降级,改用 <div role="list"> + <code><div role="listitem">,再配合 ARIA 属性(如 <code>aria-setsize/aria-posinset)补全可访问性。
立即学习“前端免费学习笔记(深入)”;
移动端和高对比度模式下的易忽略点
复选框尺寸和点击热区在小屏上容易误操作:
• <input type="checkbox"> 默认尺寸太小,必须用 transform: scale(1.2) 或设置 min-width/min-height;
• 不要只靠颜色区分选中状态,需叠加 ✓ 图标或边框变化;
• Windows 高对比度模式下,自定义 ::before 生成的序号可能消失,得用 @media (forced-colors: active) 单独处理;
• iOS Safari 对 flex 布局中 input 的垂直居中有兼容问题,建议加 margin-top: -2px 微调。



















