推荐统一用 completed 作为 class 名,JS 更新状态时只操作这个类,CSS 也只响应它;避免使用 checked,因其仅对 checkbox 有效且易与 JS 脱节;最稳写法是 li.completed,.task-item.completed { color: #999; text-decoration-line: line-through; text-decoration-color: #999; },并配合 transition 实现自然过渡。

任务完成状态用 checked 类还是 completed?
直接用 completed 更稳妥。很多教程用 checked 是为了蹭 checkbox 的语义,但实际 DOM 里你很可能用的是 <span></span> 或 <li>,没有原生 checked 属性,强行用反而容易和 JS 逻辑脱节。
推荐统一用 completed 作为 class 名,JS 更新状态时只操作这个类,CSS 也只响应它:
li.completed {
color: #999;
text-decoration: line-through;
}
- 别写
li[checked]—— 这个属性只对<input type="checkbox">有效,其他元素不识别 - 避免用
:checked伪类去控制非表单元素样式,浏览器不会触发 - 如果用了
<input type="checkbox">做状态开关,样式要写在它的相邻<label></label>上,比如input:checked + label
灰色字体 + 删除线,为什么有时不生效?
常见原因是 CSS 优先级被覆盖,或者样式写在了错误的选择器层级上。比如:
-
.todo-item.completed和li.completed同时存在时,前者优先级更高,但如果 JS 给<li>加了completed而 CSS 只写了.todo-item.completed,样式就挂了 - 用了
!important临时修复,结果后续改其他样式时被它锁死,调试困难 - 字体颜色被父容器的
color继承覆盖,没加color: #999 !important(不推荐)或没提高选择器 specificity
最稳写法是锚定到具体元素类型 + 状态类:
立即学习“前端免费学习笔记(深入)”;
li.completed,
.task-item.completed {
color: #999;
text-decoration: line-through;
}
如何让完成态过渡更自然?
纯 CSS 实现淡入划线效果,不需要 JS 动画库。关键是把 text-decoration 拆成 text-decoration-line 和 text-decoration-color,并配合 transition:
li {
transition: color 0.2s, text-decoration-color 0.2s;
}
li.completed {
color: #999;
text-decoration-line: line-through;
text-decoration-color: #999;
}
-
text-decoration整体不支持 transition,但它的子属性可以 - 必须显式声明
text-decoration-line,否则从无到有会突兀出现 - 移动端 Safari 对
text-decoration-color支持较晚,iOS 14+ 才稳定,老版本会回退为默认颜色
完成状态要不要加背景色区分?
加浅灰背景(如 background: #f8f8f8)能提升视觉分组感,但要注意两点:
- 如果列表用了
border-bottom分隔,加背景后底部边框可能被盖住,得调z-index或改用padding-bottom+border-top - 深色主题下
#f8f8f8会发白刺眼,建议用opacity控制或走 CSS 变量:background: var(--completed-bg, #f8f8f8) - 别用
opacity: 0.7整体降透明度——文字和删除线都会变淡,可读性反而下降
真正省事又兼容的做法:只动颜色和删线,背景留白。复杂交互场景再叠加背景,别一上来就堆视觉层。


















