
本文介绍一种无需 javascript 的纯 css 方案,通过 :checked + label 选择器为待办事项列表实现“勾选即删除线”效果,兼顾语义化、可访问性与性能。
在构建 To-Do 列表应用(如基于 Express + EJS 的服务端渲染项目)时,常见的交互需求是:用户勾选任务旁的复选框后,对应文本立即呈现删除线(strikethrough),直观表示任务已完成。虽然可通过 JavaScript 动态操作 DOM 样式实现,但存在执行时机错位(如 EJS 渲染后脚本未正确获取元素)、重复 ID 冲突(如原代码中所有 共用 id="checkbox_id")、以及可访问性(a11y)和维护性问题。
更优解是采用语义化 HTML + 纯 CSS 响应式样式,利用 CSS 的 :checked 伪类与相邻兄弟选择器 +,配合
✅ 推荐实现方式(推荐用于 EJS 模板)
将每项任务重构为语义化结构: +
<% for (let i = listItems2.length - 1; i >= 0; i--) { %>
<%= listItems2[i] %>
<% } %>? 关键点说明:使用 id="task-" 避免重复 ID(原代码中 id="checkbox_id" 违反 HTML 规范); 的 for 属性与 input 的 id 严格匹配,点击文字即可触发勾选;添加 cursor-pointer 和 select-none 提升交互反馈与用户体验。
? CSS 样式(支持现代浏览器)
在
立即学习“前端免费学习笔记(深入)”;
/* 基础样式 */
label {
color: #1f2937;
transition: color 0.2s ease, text-decoration 0.2s ease;
}
/* 勾选后应用删除线与灰阶色 */
input[type="checkbox"]:checked + label {
color: #6b7280;
text-decoration: line-through;
}
/* 可选:增强可访问性(屏幕阅读器提示)*/
input[type="checkbox"]:checked + label::before {
content: "[已完成] ";
font-size: 0.8em;
color: #6b7280;
}✅ 优势总结:
- 零 JavaScript:规避 DOM 加载时机、事件监听绑定失败等问题(原 JS 中 getElementsByName("para") 因 name 非标准属性且未唯一标识,极易失效);
- 语义正确:
显式关联提升可访问性,支持键盘导航与屏幕阅读器; - 性能优异:CSS 引擎原生响应,无 JS 执行开销;
- 样式可控:text-decoration: line-through 是标准、跨浏览器兼容的删除线方案,比 webkitTextStroke 更可靠(后者非标准、不支持所有字体、且无法真正“删除”文本)。
⚠️ 注意事项
- ❌ 避免在循环中重复使用相同 id 或 name(如原代码 id="checkbox_id"),否则 document.getElementById() 或 CSS 选择器将仅匹配首个元素;
- ❌ 不要依赖 name="para" 获取段落——HTML 中
不支持 name 属性,应改用 class 或语义化标签(如
); - ✅ 若需服务端感知勾选状态(如提交表单),确保 具有 name 和 value,并在 Express 路由中通过 req.body.task(数组)接收已勾选项;
- ✅ 如需动画过渡,可添加 transition 属性(如上例所示),使颜色与删除线变化更平滑。
此方案已在主流浏览器(Chrome/Firefox/Safari/Edge ≥ v100)中稳定运行,适用于 SSR 场景,是构建健壮、可维护 To-Do 应用的推荐实践。










