必须用::after伪元素+position: relative父容器实现红点,因字符●受字体渲染影响易变形糊边,span则增加dom负担且易被框架diff误删;核心是content: ""+绝对定位+data-unread属性控制显隐,并用transform: translate(50%, -50%)精准锚定右上角顶点。

直接用 ::after 伪元素 + position: relative 父容器,别写 • 或 span 角标 —— 后者在缩放、多语言、屏幕阅读器下全崩。
为什么不能用字符 ● 或独立 span 做红点
字符 ● 是文本节点,受 font-size、line-height、字体基线(ascent/descent)影响极大;同一行里,<i></i> 和 • 垂直位置可能差 3px 以上。iOS Safari 下还糊边,Windows Chrome 可能渲染成椭圆。独立 span 则需手动管理 DOM 显隐,容易被 Vue/React diff 移除,或触发重排动画卡顿。
-
::after是纯样式层,不占 DOM 节点,无重排开销 -
content: ""+background: #f00+border-radius: 50%才真正可控 - 必须用
data-unread="1"控制显隐,而不是class="show"—— 框架重渲染时 class 可能消失,但 data 属性不会
position: relative 和 transform: translate(50%, -50%) 缺一不可
红点要精准钉在按钮右上角顶点,不是“贴右上”,而是“圆心对齐顶点”。只设 top: 0; right: 0 会因图标 display 类型(inline 默认基线对齐)导致偏移。
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
- 父按钮必须设
position: relative,否则::after的position: absolute会相对 body 定位 -
top: 0; right: 0; transform: translate(50%, -50%)是唯一绕过基线干扰的方案 - 按钮若为
<i></i>或<svg></svg>,请确保其display是inline-block或block,别让它按 inline 默认对齐 - 红点尺寸固定写死:
width: 8px; height: 8px,禁用em/rem—— 字体缩放时会失真
移动端适配和 overflow 裁剪问题
小屏下 8px 红点太突兀,且如果按钮在 overflow: hidden 的导航栏里,红点超出部分会被直接裁掉 —— 这是线上最常被忽略的两个坑。
- 加媒体查询:
@media (max-width: 768px) { .badge::after { width: 6px; height: 6px; } } - 若红点被裁,先检查父容器是否设了
overflow: hidden;解决方式二选一:overflow: visible,或给红点加z-index: 1000并确保父级有定位上下文(即已有position: relative) - 别依赖
:empty判断显隐 —— 即使标签里有个空格,:empty就失效,必须用[data-unread="1"]
怎么动态控制红点显示与数字内容
红点本身不存状态,它只是视觉反射。真实状态来自后端或 JS 数据,通过修改 data-unread 属性驱动 CSS 显隐;若要显示数字(如 9+),得靠 attr(data-count),但注意:这个值必须由后端或 JS 提前拼好字符串,attr() 不支持表达式运算。
- JS 更新写法:
button.dataset.unread = "1"(设未读)、button.dataset.unread = "0"(已读) - CSS 显隐规则:
[data-unread="1"] .notification-bell::after { display: block; },[data-unread="0"] .notification-bell::after { display: none; } - 数字角标示例:
.badge::after { content: attr(data-count); font-size: 10px; line-height: 1; },前提是 HTML 中写了data-count="9+" - Vue 中推荐:
:attr="{ 'data-unread': unread ? '1' : '0' }",避免v-if导致属性彻底消失
红点看着简单,但真正上线不出错的关键,是把定位锚点、属性驱动、移动端缩放、overflow 裁剪这四件事一次性对齐。漏掉任意一个,都会在某个机型或用户操作路径下突然失效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










