纯 CSS 可实现复选框状态切换过渡,但须避免 display: none 和跨层结构;:checked 仅影响同级后继元素,input 必须在 label 前且不可脱离渲染流,推荐 opacity: 0 + absolute + pointer-events: none 隐藏;伪元素动效应基于 transform/opacity 过渡,禁用 left/top 等触发重排属性;需兼容键盘、屏幕阅读器及 prefers-reduced-motion。

纯 CSS 能做出复选框状态切换的过渡效果,但必须绕开 display: none 和跨层结构这两个致命坑;:checked 伪类只影响同级后继元素,且原生 input 必须可被状态捕获——一旦用 display: none 隐藏,状态链就断了。
为什么 :checked + ::after 动画不触发
常见现象是写了 input[type="checkbox"]:checked + label::after 却没动画,点击后样式也不变。根本原因是 :checked 只能影响它后面的同级元素,而且前提是 input 元素本身未被移出渲染流。
-
input和目标label必须同级、且input在前(例如:<input><label></label>),不能是<label><input></label>或嵌套在不同父容器里 - 别用
display: none隐藏复选框,改用opacity: 0; position: absolute; pointer-events: none; - 如果想对
input的父元素做动画(比如整个卡片翻转),CSS 无解,必须换 JS 监听change事件
::before/::after 做勾选标记的动效写法
核心思路是:用伪元素画一个“未选中态”,再用 :checked 控制它的 transform 和 opacity 过渡,避免依赖 display 切换。
- 初始状态设为
transform: scaleX(0); opacity: 0;,并加transition: transform .2s cubic-bezier(.2, .7, .4, 1), opacity .15s ease - 选中时设
transform: scaleX(1) rotate(45deg); opacity: 1;,这样能模拟对勾“画出来”的效果 - 若用 SVG data URI 当背景图,记得把
background-size设为固定值(如100% 100%),否则缩放时可能失真
移动端兼容性与渲染优化要点
伪元素动画在 iOS Safari 上容易卡顿或跳帧,尤其在低配设备上。关键不是加更多动画,而是限制重绘范围。
立即学习“前端免费学习笔记(深入)”;
- 优先使用
transform和opacity触发 GPU 加速,避免用left/top或background-color做过渡 - 确保
input和label同在一个 stacking context 下,否则 iOS 可能忽略:checked对伪元素的影响 - 在
@supports (prefers-reduced-motion: reduce)下关闭动画,这是 WCAG 2.1 强制要求,不是可选项
最易被忽略的是:动画是否在所有触发路径下都生效——比如用户用空格键切换、用屏幕阅读器操作、或通过 JS 手动设置 input.checked = true,这些都会触发 :checked,但不会触发 :hover 或 :focus。所以动效逻辑必须只绑定在 :checked 上,且不能依赖其他伪类叠加。



















