必须隐藏原生radio并用label模拟卡片交互,通过input:checked + label控制选中态样式,确保name相同实现互斥,兼顾可访问性与键盘导航。

单选按钮组怎么用 CSS 实现卡片式点击效果
直接给 <input type="radio"> 套卡片样式不行——浏览器默认会显示原生控件,必须隐藏它,再用 <label> 绑定并自定义视觉层。核心是「隐藏真实 radio,用 label 模拟卡片交互」。
常见错误是只改 input 的样式(比如 display: none 但没处理 label 的可点击范围),导致点击无响应或无法触发选中状态。
- 必须用
for属性或把input包在label内,确保点击卡片区域能聚焦/选中对应 radio -
input[type="radio"]要用position: absolute; opacity: 0; pointer-events: none;隐藏且不阻断事件(比display: none更安全) - 卡片的「选中态」靠
input:checked + label或input:checked ~ label(取决于 DOM 结构)来控制样式 - 别忘了加
cursor: pointer到卡片上,否则用户看不出可点
HTML 结构怎么组织才方便样式控制
推荐把 input 放在 label 外部、同级,并用 id/for 关联。这样 CSS 选择器更稳定,也避免嵌套过深影响可访问性。
错误结构:<label><input type="radio">选项A</label> —— 看似简洁,但 label 内部包裹 input 后,某些屏幕阅读器行为不一致,且 :checked + * 无法生效。
立即学习“前端免费学习笔记(深入)”;
<div class="radio-card-group">
<input type="radio" name="plan" id="plan-basic" value="basic">
<label for="plan-basic">
<div class="card">
<h4>基础版</h4>
<p>¥99/月</p>
</div>
</label>
<input type="radio" name="plan" id="plan-pro" value="pro">
<label for="plan-pro">
<div class="card">
<h4>专业版</h4>
<p>¥199/月</p>
</div>
</label>
</div>
这样写,CSS 就能用 input#plan-basic:checked + label .card 精准控制选中卡片的边框、阴影等样式。
怎么让选中态有明显视觉反馈
关键不是加个背景色就完事,得兼顾对比度、焦点可见性(键盘 Tab 导航)、和表单验证逻辑。纯 CSS 就能搞定,不需要 JS。
- 用
box-shadow: 0 0 0 3px #007bff比单纯加border更柔和,也避免影响卡片尺寸 - 配合
transition: all 0.2s ease让切换更自然 - 为键盘用户保留
input:focus + label .card样式,例如加outline: 2px solid #007bff - 如果卡片内有图标或徽章,可用
::after在选中时插入 ✔️,但注意用content: "✔"而非图片,保证可访问性
为什么用 radio 而不用 checkbox 实现单选卡片
因为 checkbox 默认允许多选,即使加 JS 控制逻辑,也会破坏原生表单语义——提交时可能传多个值,校验逻辑变复杂,而且 screen reader 会读作「复选框」,造成认知偏差。
用 radio 是语义正确的解法:name 相同即天然互斥,form 提交自动只带一个 value,后端解析零成本,无障碍支持也开箱即用。
容易被忽略的是:所有同组 radio 必须有相同的 name 属性值,且不能为空;如果动态生成,name 值要严格一致,大小写敏感。漏掉这点,卡片就真变成“多选”了。



















