复选框点击区域应通过label扩大而非仅调整input;划线推荐用::after伪元素实现,避免text-decoration;状态同步需确保dom结构正确或统一用class控制;动画须用transform配合opacity/visibility。

复选框点击区域太小,用户总点不中
移动端或密集列表里,input[type="checkbox"] 默认样式只有几像素宽高,手指一划就错过。浏览器不会自动把文字区域绑定到 checkbox 上,除非你显式声明关联。
- 给
label包住input和文字,或者用for属性绑定id(推荐前者,更可靠) - 别只靠
margin或padding扩大 checkbox 本身——它只是个渲染节点,扩大后仍不响应点击;真正要扩大响应区的是label - 加一句
label { cursor: pointer; },让用户一眼知道能点
label {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
}
label input[type="checkbox"] {
margin: 0;
}勾选后文字划线不自然、断层或偏移
直接用 text-decoration: line-through 很容易出问题:中文字体 baseline 不一致,划线位置浮动;如果文字换行,划线只在首行;加了 opacity 或 transform 后还可能消失。
- 优先用伪元素
::after模拟划线,完全可控位置和长度 - 避免对
label或span直接加line-through,尤其当文字含图标、空格或 emoji 时 - 划线高度建议设为
1px,top 偏移量用calc(50% - 0.5px)居中,比硬写2px更适配不同字号
label.checked::after {
content: "";
position: absolute;
left: 0;
top: calc(50% - 0.5px);
width: 100%;
height: 1px;
background: #999;
}状态同步错乱:勾选了但没划线,或划线了但 checkbox 没打钩
纯 CSS 实现时,依赖 input:checked + label 或 input:checked ~ label 这类相邻/后代选择器。一旦 DOM 结构微调(比如加了个 div 包裹),样式就失效。
- 确保
input和目标文字容器是紧邻兄弟关系,中间不能插其他元素 - 如果用了 Vue/React 等框架,别混用「CSS 控制划线」和「JS 控制 class」——二者状态可能不同步;统一用 class 切换更稳
- 检查是否误用了
:checked ~ .todo-text却把文字放在label内部,此时应改用:checked + label或直接操作label的 class
划线动画生硬、闪烁或不触发
CSS transition 对 text-decoration 完全无效,对伪元素的 width 或 opacity 才可动画。而且若划线从 0→100% 动画,需配合 transform: scaleX(0) 避免重排。
立即学习“前端免费学习笔记(深入)”;
- 用
transform: scaleX()替代width动画,性能更好,且不触发 layout - 动画起始态必须设
transform-origin: left center,否则缩放中心偏移导致划线“甩出去” - 别给
::after加display: none→block切换,这会中断 transition;改用opacity: 0和visibility: hidden组合
label::after {
transform: scaleX(0);
transform-origin: left center;
transition: transform 0.2s ease;
}
label.checked::after {
transform: scaleX(1);
}划线效果看着简单,但实际卡点都在 DOM 关系、伪元素定位精度和过渡时机上。哪怕只改一个 flex 的 align-items 值,都可能让划线突然偏移两像素。










