纯CSS幻灯片切换用radio+:checked实现状态驱动,所有radio需同name互斥,通过~选择器控制同级幻灯片显隐,初始设.slide{display:none},配合input:checked ~ .slide{display:block}激活当前项。

radio + :checked 如何触发幻灯片切换
纯 CSS 幻灯片的核心不是动画本身,而是「状态驱动」:用 <input type="radio"> 的 :checked 状态作为开关,控制对应 <section></section> 或 <div> 的显隐。浏览器原生支持 <code>:checked 伪类对 radio 的实时响应,无需 JS 监听,也不存在事件延迟或重排问题。
关键点在于:所有 radio 必须有相同的 name 属性(如 name="slide"),才能形成单选组;每个 radio 的 id 需与目标幻灯片区块通过 for/id 或相邻/子元素关系关联。
- 推荐用
~(通用兄弟选择器):radio 和幻灯片容器同级时最稳定 - 避免用
+(相邻兄弟):它只匹配紧邻的下一个元素,容错性差 - 不要把幻灯片内容直接塞进
<label></label>内部——会干扰点击区域和语义
如何让当前 slide 显示、其余隐藏
默认所有幻灯片区块设为 display: none,再用 :checked ~ .slide 规则单独显示匹配项。注意:必须确保 CSS 选择器权重足够,且没有更宽泛的 display: block 规则覆盖它。
常见错误是写成 input:checked ~ .slide { display: block; } 却忘了给 .slide 设初始 display: none —— 浏览器会按层叠顺序应用,未声明即按默认值(如 div 是 display: block),导致所有幻灯片同时可见。
立即学习“前端免费学习笔记(深入)”;
- 务必在基础样式中统一设
.slide { display: none; } - 用
opacity+visibility替代display可实现淡入淡出,但需配合transition -
z-index不是必需的——只要 DOM 顺序固定,靠~选中的那个元素自然在视觉上“生效”
为什么用 radio 而不是 checkbox
因为幻灯片是单页模式:同一时间只能有一个激活态。<input type="checkbox"> 支持多选,即使加 JS 限制也破坏了纯 CSS 方案的简洁性;而 radio 的原生互斥行为刚好契合需求,且无障碍支持更好(屏幕阅读器能正确识别单选组)。
另一个常被忽略的优势:radio 的 :checked 状态可被 URL hash(如 #slide-2)或页面刷新保留(如果配合 <input checked> 或服务端渲染),而 checkbox 没有这种天然锚点映射能力。
- 每个 radio 应配一个唯一
id,如id="slide-1" - 对应 label 的
for属性必须精确匹配该 id - 不要依赖
value做逻辑判断——CSS 无法读取 value,只认:checked状态
移动端点击失效或滑动冲突怎么解
在 iOS Safari 或部分安卓 WebView 中,radio 的 :checked 可能不响应 touch 事件,尤其当 label 内含 display: block 或设置了 touch-action: manipulation 时。根本原因不是 CSS,而是浏览器对表单控件触摸区域的判定策略。
最轻量的修复方式是确保 label 具备明确的可点击区域,并禁用默认高亮:
label {
-webkit-tap-highlight-color: transparent;
-webkit-user-select: none;
user-select: none;
}
- 别给 label 设
pointer-events: none——这会让整个点击失效 - 避免在 label 内嵌套
<div> 或其他块级元素作“按钮”,改用 <code>span+display: inline-block - 如果幻灯片区域本身需要手势滑动(如轮播图),
radio方案就不适用——它本质是点击跳转,不是连续拖拽
真正麻烦的不是写法,而是当你要加自动播放、键盘导航、缩略图联动或响应式断点切换时,纯 CSS 的边界就到了。那些功能要么得退回到 JS 控制状态,要么用属性选择器(如 [data-slide="2"])做间接桥接——但那就不再是“简单幻灯片”了。


















