通知抽屉不能用 checkbox Hack 实现,因其无法支持多状态、动态操作和精确控制;应采用 JavaScript 控制 class 与 CSS transform 组合方案,兼顾交互性、动画性能与可访问性。
通知抽屉不是普通菜单,它需要自动展开、带清除逻辑、支持多条消息、能被点击收起,且不能干扰主页面滚动——用纯 checkbox Hack 很难满足这些需求。推荐用 JavaScript 控制 class + CSS transform 的组合方案,兼顾可控性与动画质量。
checkbox 实现通知抽屉通知抽屉常需动态插入新消息、标记已读、点击跳转、自动超时关闭,而 checkbox 是二元状态(开/关),无法表达“有 3 条未读”或“第 2 条已点击”。更关键的是:
label 触发后无法 programmatically 关闭(比如用户点完通知想自动收起)overflow-y: auto,label 的点击热区可能失效(尤其 iOS Safari)document.addEventListener('click') 怎么安全关闭通知抽屉点击遮罩层或页面其他区域时收起抽屉,但必须排除抽屉自身和触发按钮。常见错误是直接监听 document 然后无差别 remove,结果点击抽屉内链接也触发关闭。
class="notification-drawer"
id="notify-trigger"
event.target 是否在抽屉或按钮内部:if (!event.target.closest('.notification-drawer') && !event.target.closest('#notify-trigger')) { drawer.classList.remove('open'); }
pointer-events: none 遮罩层——它会阻断所有事件,包括抽屉内的按钮点击height + overflow 做动画通知抽屉常固定高度、内容可滚动,但若用 height: 0 → height: 300px 做展开动画,会触发浏览器重排(reflow),导致卡顿,尤其低端安卓机。
立即学习“前端免费学习笔记(深入)”;
transform: scaleY(0) → transform: scaleY(1),GPU 加速,不触发重排max-height 和 overflow-y: auto,不要套在动画元素里will-change: scroll-position 提升滚动性能innerHTML 批量插入,而非循环 appendChild
抽屉弹出时,若没处理可访问性,屏幕阅读器会继续读主页面,键盘 Tab 仍能进入抽屉后的内容,造成混乱。
<body> 加 aria-hidden="true",同时给抽屉加 aria-hidden="false"
inert 属性(现代浏览器支持)禁用抽屉外所有可交互元素:document.body.inert = true; drawer.inert = false;
drawer.focus({ preventScroll: true }) 将焦点移到抽屉根节点triggerBtn.focus()
通知抽屉真正的难点不在“滑出来”,而在“状态同步”:已读未读标记要和服务端对齐,本地清除操作得幂等,自动关闭不能打断用户操作。这些没法靠 CSS 动画解决,得从事件生命周期和数据流设计入手。