HTML标准规定ol的直接子元素只能是li,因此radio必须置于li内;正确做法是用label包裹radio并设相同name属性,既保持语义又确保互斥选择。

ol 里不能直接放 <input type="radio"> 当列表项
HTML 标准规定 <ol></ol> 的直接子元素只能是 <li>,而 <li> 内部可以放任何流内容(包括表单控件),但浏览器不会自动把 radio 按顺序编号 —— 你看到的序号来自 <ol></ol> 的计数器,和 radio 无关。强行把 <input> 塞进 <li> 没问题,但“编号 + 单选”是两件事,得分开处理。
用 <li> 包裹 radio,并保留 ol 的语义和样式
正确做法是让每个 <li> 包含一个 <label></label>,里面放 <input type="radio"> 和文本。这样既保持了有序列表的语义(适合屏幕阅读器、SEO),又能正常交互。
<ol> <li><label><input type="radio" name="choice" value="a"> 选项一</label></li> <li><label><input type="radio" name="choice" value="b"> 选项二</label></li> <li><label><input type="radio" name="choice" value="c"> 选项三</label></li> </ol>
- 必须为所有 radio 设置相同的
name属性,否则无法互斥选择 -
<label></label>包裹 input 可点击区域更大,且点击文本也能选中 radio - 不要给
<input>加id再用for关联 —— 包裹方式更简洁、不易出错
如果需要自定义编号样式(比如加圆圈、箭头),别动 <ol></ol> 的 type
<ol type="A"></ol> 或 <ol start="2"></ol> 只控制数字/字母序列,不影响 radio 行为。真要改视觉效果,用 CSS 计数器更可控:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
ol.custom-radio {
counter-reset: item;
}
ol.custom-radio li {
counter-increment: item;
}
ol.custom-radio li::before {
content: counter(item) " → ";
font-weight: bold;
margin-right: 8px;
}
- 避免用
list-style-type: none+ 手动写编号,会丢失语义和可访问性 - CSS 计数器不影响
<input>的功能,radio 依然按原逻辑工作 - 注意:某些旧版 Safari 对
::before在<li>上的支持有边界情况,建议测试
常见错误:用 <div> 替换 <code><ol></ol> 或用 <ul></ul> 模拟序号
有人为了“方便加 radio”直接弃用 <ol></ol>,改用 <div> + 手动写 “1. 2. 3.”,这是退化语义。后果包括:<p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p>
<ul>
<li>屏幕阅读器读不出“这是第几个选项”,只当普通段落</li>
<li>复制整段文字时,编号变成纯文本(如 “1. 选项一”),无法被程序解析结构</li>
<li>打印或高对比度模式下,手动编号可能错位或丢失</li>
<li>
<code><ul></ul> + list-style-type: decimal 是伪序号,不具 <ol></ol> 的语义权重
真正难的不是怎么放 radio,是怎么让机器和人都明白“这是带顺序的单选组”——<ol></ol> + <li> + <input type="radio"> 这个组合,就是目前最稳妥的表达方式。


















