纯CSS实现数字角标需父容器设position: relative,角标用position: absolute+content: attr(data-count)配合伪元素显示,支持自动隐藏、无障碍标注及IE11降级方案。

如何用纯 CSS 实现不依赖 JS 的数字角标(badge)
数字角标能直接用 position: absolute + 伪元素实现,无需 JS 控制显隐或数值更新——只要 HTML 结构预留了 data-badge 属性或子元素,CSS 就能读取并渲染。关键在于避免把角标写死在 DOM 里,否则每次变更都要操作 DOM 节点。
推荐结构:
<button class="notify-btn">消息<span class="badge" data-count="3"></span></button>
-
.badge设为position: absolute,父容器.notify-btn必须设position: relative - 用
content: attr(data-count)配合::after伪元素显示数字,比 innerHTML 更轻量且可被 CSS 完全控制样式 - 若需支持“无数字时隐藏”,加
display: none并用属性选择器触发:.badge[data-count="0"] { display: none; }
角标位置偏移在不同按钮尺寸下的适配问题
固定像素值(如 top: -6px; right: -6px)在小按钮上会溢出,在大按钮上又显得太靠里。真正稳定的方案是用 transform 配合百分比定位。
实操建议:
.badge::after {
position: absolute;
top: 50%;
right: 50%;
transform: translate(120%, -120%);
/* 这样角标右上角始终锚定在按钮右上角外侧 */
}
- 避免用
em或rem,它们受字体继承影响,按钮内文字缩放会导致角标漂移 - 如果按钮高度动态(比如响应式中从 32px 变到 48px),优先用
calc(50% + 4px)替代固定px偏移 - 圆角按钮要额外加
border-radius: 50%到角标本身,否则尖角会刺出
无障碍与可访问性容易被忽略的细节
视觉上的红点和数字对屏幕阅读器完全不可见,用户可能根本不知道有新通知。不能只靠颜色或位置暗示。
- 给
.badge加aria-hidden="true"(仅当它只是装饰性视觉提示);如果数字有语义(如“3 条未读”),则必须用aria-label或aria-live - 例如:
- 禁止仅用颜色区分状态(如红底白字表示“有通知”),至少叠加图标或文字提示,否则色觉障碍用户无法识别
- 角标尺寸不能小于 16×16px,否则触控设备上难以点击,也违反 WCAG 2.5.5 目标尺寸要求
IE11 兼容场景下 attr() 不生效怎么办
IE11 不支持 content: attr(data-count),这是最常踩的坑——看起来样式写了,但数字就是不显示。
绕过方式只有两个:要么放弃纯 CSS 方案,用 JS 注入文本;要么改用内联文本节点 + CSS 控制显隐:
<span class="badge"><span class="badge-text">3</span></span>
- JS 只负责更新
.badge-text的textContent,不操作样式类,性能开销极小 - CSS 用
.badge-text:empty { display: none; }隐藏空值,比属性判断更兼容 - 若项目已弃用 IE11,可放心用
attr(),现代浏览器全部支持
角标看着小,但涉及定位逻辑、可访问性声明、跨浏览器行为差异,最容易在迭代中悄悄失效。尤其当按钮变成加载态、禁用态或被封装进 Web Component 后,position: relative 的上下文可能丢失,角标就飘到页面左上角去了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











