首页
/ ant-design Badge 徽标数深度指南:封顶数字、状态点、缎带与 Semantic DOM 定制

ant-design Badge 徽标数深度指南:封顶数字、状态点、缎带与 Semantic DOM 定制

2026-09-06 14:38:08作者:翟江哲Frasier

本文围绕 ant-design 的 Badge(徽标数)组件展开,基于官方文档 Badge 中文文档 的完整 API 体系,结合 Badge 主组件实现Ribbon 缎带实现样式 Token 定义 的源码细节,讲解如何在通知图标、头像、卡片等场景中使用 Badge 展示消息数、状态点与缎带标记,以及如何通过 Semantic DOM 和 Design Token 对其进行精细化定制。

何时使用

Badge 一般出现在通知图标或头像的右上角,用于显示需要处理的消息条数,通过醒目的视觉形式吸引用户去处理。它属于 ant-design「数据展示」类组件,除了数字徽标外,还提供三种形态:独立小红点(dot)、状态点(status)、以及包裹在内容角部的缎带(Badge.Ribbon)。

基础用法与核心演示

基本徽标

最典型的用法是把徽标目标(如头像)作为 children 传入,count 传入要展示的数字。官方示例 basic.tsx 展示了三种形态:普通数字、showZero 展示 0、以及用图标作为 count 内容:

import { Avatar, Badge, Space } from 'antd';
import { ClockCircleOutlined } from '@ant-design/icons';

export default () => (
  <Space size="medium">
    <Badge count={5}>
      <Avatar shape="square" size="large" />
    </Badge>
    <Badge count={0} showZero>
      <Avatar shape="square" size="large" />
    </Badge>
    <Badge count={<ClockCircleOutlined style={{ color: '#f5222d' }} />}>
      <Avatar shape="square" size="large" />
    </Badge>
  </Space>
);

Badge.tsx 的源码可以看到,当 count 是一个 React 元素(isPlainObject(livingCount))时,组件会通过 cloneElement 把它克隆进徽标容器,并合并外部 style——这就是「用图标替代数字」的实现原理。此时数字徽标会带上 -custom-component 类名(见 ScrollNumber.tsx)。

封顶数字(overflowCount)

count 大于 overflowCount 时,展示为 ${overflowCount}+。默认封顶值为 99(见 Badge.tsxoverflowCount = 99 的解构默认值)。核心计算逻辑在 Badge.tsx

const numberedDisplayCount = (
  (count as number) > (overflowCount as number) ? `${overflowCount}+` : count
) as string | number | null;

官方示例 overflow.tsx 演示了 <Badge count={1000} overflowCount={999} /> 显示为 999+ 的封顶效果。

动态变化与小红点

官方 change.tsxuseState 驱动 count 增减,展示数字变化时的过渡动画;同时用 Switch 控制 dot 属性开关小红点。

关于动画,有两层实现值得注意:

  1. 出现/消失动画BadgeCSSMotion 包裹徽标,motionName${prefixCls}-zoom,对应 样式文件 中的 antZoomBadgeIn / antZoomBadgeOut 关键帧(独立使用时为 antNoWrapperZoomBadgeIn/Out,不带位移)。
  2. 数字滚动动画ScrollNumber.tsx 中,只有整数才会被拆分为逐位渲染——每一位由 SingleNumber.tsx 负责纵向滚动切换,从而产生「数字翻牌」效果;非整数或非数字内容则原样展示。

另外,源码用 countRef / displayCountRef / isDotRef 三个 ref 缓存隐藏前的数值与 dot 状态(见 Badge.tsx),注释说明其目的是「移除动画进行时不应改变计数显示」,避免徽标淡出过程中内容闪烁。

大小(size)

size 在设置了 count 的前提下有效,取值为 medium(默认)或 small,官方示例见 size.tsx。注意 size="default" 已被标记为废弃:Badge.tsx 在开发环境下会输出 size="default" 将被移除、请使用 size="medium" 的告警,对应样式类为 样式文件中的 -count-sm 规则(更小的 minWidthheightfontSizeborderRadius)。

Badge 完整 API

以下参数表继承自官方文档 Badge API,并结合源码补充了实现层面的说明。通用属性(如 rootClassName)遵循 ant-design 通用属性约定。

参数 说明 类型 默认值 版本 全局配置
color 自定义小圆点的颜色 string - ×
count 展示的数字,大于 overflowCount 时显示为 ${overflowCount}+,为 0 时隐藏 ReactNode - ×
classNames 用于自定义组件内部各语义化结构的 class,支持对象或函数 Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> - 5.7.0
dot 不展示数字,只有一个小红点 boolean false ×
offset 设置状态点的位置偏移 [number, number] - ×
overflowCount 展示封顶的数字值 number 99 ×
showZero 当数值为 0 时,是否展示 Badge boolean false ×
size 在设置了 count 的前提下有效,设置小圆点的大小 medium | small - - ×
status 设置 Badge 为状态点 success | processing | default | error | warning - ×
styles 用于自定义组件内部各语义化结构的行内 style,支持对象或函数 Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties> - 5.7.0
text 在设置了 status 的前提下有效,设置状态点的文本 ReactNode - ×
title 设置鼠标放在状态点上时显示的文字。设置为 nullfalse 时移除原生 tooltip string | null | false - 6.5.0 ×

各参数的源码级说明

count / showZero / 隐藏逻辑。 判断徽标是否隐藏的核心在 Badge.tsx

const isZero =
  numberedDisplayCount === '0' || numberedDisplayCount === 0 || text === '0' || text === 0;
const ignoreCount = count === null || (isZero && !showZero);

即:countnull,或为 0 且未开启 showZero 时,计数不渲染;dot 模式下 showAsDot = dot && !isZero,因此 count={0} dot 同样不显示小红点。

offset。 offset 数组的第一个值会被解析为水平偏移并取负(insetInlineEnd: -horizontalOffset,正值表示向外推),第二个值作为 marginTop,实现见 Badge.tsx。默认情况下徽标通过 position: absolute; top: 0; insetInlineEnd: 0; transform: translate(50%, -50%) 定位在目标右上角(见 样式文件),offset 是在此基础上的微调。

color。 源码通过 isPresetColor(color, false) 区分预设色板与自定义颜色:预设色(pinkredcyan 等)会生成 -color-${color} 类名,其背景色由 样式文件中的 genPresetColor 统一派生;非预设的自定义颜色则以内联 stylebackground/color)注入(见 Badge.tsxL292-L295)。

title。 默认行为是:当 count 是字符串或数字时,自动把该值作为原生 title tooltip 展示;显式传入 nullfalse 会移除原生 tooltip,实现见 Badge.tsxtitleNode 计算。

状态点分支。 当没有 children 且设置了 statuscolor(且 ignoreCount)时,组件走独立的「状态徽标」渲染分支:输出一个内联 span,内含状态点 -status-dot 和可选的 -status-text 文本,见 Badge.tsxL240-L258。官方 status.tsx 演示了全部五种状态及带文本的形态:

import { Badge, Space } from 'antd';

export default () => (
  <>
    <Space>
      <Badge status="success" />
      <Badge status="error" />
      <Badge status="default" />
      <Badge status="processing" />
      <Badge status="warning" />
    </Space>
    <Space vertical>
      <Badge status="success" text="Success" />
      <Badge status="error" text="Error" />
      <Badge status="processing" text="Processing" />
      {/* ... */}
    </Space>
  </>
);

其中 processing 状态点的呼吸动画由 样式文件中的 antStatusProcessing 关键帧 驱动(scale(0.8) → scale(2.4) 并淡出)。此外,当 text === 0 时状态文本的显示同样受 showZero 控制(见 Badge.tsx)。

Badge.Ribbon 缎带

Badge.Ribbon 用于在卡片等容器右上角包裹一条斜切缎带,官方示例见 ribbon.tsx

import { Badge, Card, Space } from 'antd';

export default () => (
  <Space vertical size="medium" style={{ width: '100%' }}>
    <Badge.Ribbon text="Hippies" color="pink">
      <Card title="Pushes open the window" size="small">
        and raises the spyglass.
      </Card>
    </Badge.Ribbon>
    <Badge.Ribbon text="Hippies" color="cyan">
      <Card title="Pushes open the window" size="small">
        and raises the spyglass.
      </Card>
    </Badge.Ribbon>
  </Space>
);
参数 说明 类型 默认值 版本 全局配置
classNames 用于自定义组件内部各语义化结构的 class,支持对象或函数 Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> - 6.0.0
color 自定义缎带的颜色 string - ×
placement 缎带的位置,startend 随文字方向(RTL 或 LTR)变动 start | end end ×
styles 用于自定义组件内部各语义化结构的行内 style,支持对象或函数 Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties> - 6.0.0
text 缎带中填入的内容 ReactNode - ×

Ribbon.tsx 的源码看,渲染结构为:外层 div.antd-ribbon-wrapper(相对定位的包裹层)→ 子内容 → div.antd-ribbon(缎带本体,携带 antd-ribbon-placement-{placement}antd-ribbon-color-{color} 类名)→ 内部 span.antd-ribbon-content(文本)与 div.antd-ribbon-corner(右下角的三角补角)。缎带的斜切造型由 Token 派生的 badgeRibbonCornerTransform / badgeRibbonCornerFilter 控制(见 Token 定义)。颜色机制与 Badge 一致:预设色走 genPresetColor 类名,自定义色以内联 background 注入,并同步给 corner 元素的 color(见 Ribbon.tsx)。RTL 环境下会自动追加 antd-ribbon-rtl 类适配方向。

Semantic DOM:语义化结构与 classNames / styles

ant-design 5.7.0 起,Badge 支持通过 classNames / styles 精确定制内部各语义化结构,官方文档通过 语义结构示例 展示了可定制的部分。从源码中的 BadgeSemanticType 定义(Badge.tsx)可确认 Badge 暴露两个语义节点:

语义节点 含义
root 徽标根元素(span.antd-badge
indicator 右上角的徽标本体(数字、小红点或自定义内容)

Ribbon 的 RibbonSemanticTypeRibbon.tsx)则暴露三个语义节点:root(wrapper 包裹层)、content(缎带文本)、indicator(缎带本体)。

两者均支持「对象」或「函数」两种写法,函数形式可拿到 { props } 依据当前属性做条件定制。合并逻辑由 useMergeSemantic 工具完成,优先级为:ConfigProvider 全局配置(contextClassNames/contextStyles,key 为 badge / ribbon)< 组件自身属性,见 Badge.tsx。使用 ConfigProvidertheme.components.Badgebadge 组件级配置即可全局下发这些语义样式。

一个典型的语义定制写法:

<Badge
  count={5}
  classNames={{ indicator: 'my-indicator' }}
  styles={{ root: { marginLeft: 8 } }}
>
  <Avatar shape="square" size="large" />
</Badge>

主题变量(Design Token)

官方文档页尾通过 ComponentTokenTable 自动生成 Badge 的 Token 表格;这些 Token 的源码定义位于 style/index.ts。其中关键的组件级 Token 包括:

Token 说明
indicatorZIndex 徽标 z-index
indicatorHeight 徽标高度(默认尺寸)
indicatorHeightSM 小号徽标高度
dotSize 点状徽标尺寸
textFontSize / textFontSizeSM 徽标文本尺寸(默认 / 小号)
textFontWeight 徽标文本粗细
statusSize 状态徽标尺寸
paddingInline 多字符徽标水平内边距

此外还有派生 Token(BadgeToken):badgeColor(徽标主色)、badgeColorHover(悬停色)、badgeTextColor(文本色)、badgeShadowSize / badgeShadowColor(外圈白色描边阴影,即 -count-dot 上的 box-shadow: 0 0 0 {size} {color})、badgeProcessingDuration(processing 动画时长)、badgeRibbonOffset / badgeRibbonCornerTransform / badgeRibbonCornerFilter(缎带偏移、角部变换与滤镜)。这些 Token 均可通过 ConfigProvidertheme.token / theme.components.Badge 覆盖,从而全局调整徽标配色与几何尺寸。

实现细节速览:源码结构与类名机制

综合 Badge.tsx样式文件,Badge 的关键行为可以归纳为:

  1. wrapper 与非 wrapper:无 children 时根节点附加 antd-badge-not-a-wrapper 类,动画关键帧与定位方式随之切换(不位移的 zoom 动画)。
  2. 多词计数count 字符串长度大于 1 时附加 antd-badge-multiple-words 类(横向内边距由 paddingInline 控制),数字包裹在 <bdi> 中以 unicodeBidi: plaintext 保证双向文本排布正确(见 样式文件ScrollNumber.tsx)。
  3. borderColor 兼容:老版本允许用 style={{ borderColor }} 给徽标加描边,ScrollNumber.tsx 将其模拟为 box-shadow: 0 0 0 1px {borderColor} inset,保持旧用法兼容。
  4. RTL 支持:根节点与缎带在 direction === 'rtl' 时分别追加 antd-badge-rtl / antd-ribbon-rtl 类,偏移量使用逻辑属性 insetInlineEnd 实现方向自适应。
  5. 主题与 CSS-in-JS:组件样式由 useStyle 以 cssinjs 方式生成,支持 cssVar 模式(cssVarCls),动画关键帧(antZoomBadgeIn/OutantStatusProcessing 等)随组件样式一起注入。

小结

Badge 组件以 count 为核心,围绕封顶展示(overflowCount)、零值控制(showZero)、红点(dot)、状态点(status + text)、自定义颜色(color)、位置微调(offset)、尺寸(size)与原生 tooltip(title)提供完整的通知类视觉方案;Badge.Ribbon 则补充了容器角部缎带形态。工程层面,它通过 Semantic DOM(classNames/styles)暴露 root/indicator(Ribbon 另有 content)语义节点,并通过 style/index.ts 定义的组件 Token 支持全局主题化定制。如需查阅完整演示,可参考官方文档页列出的 demo 目录 下 17 个示例,包括动态变化、可点击、语义结构样式与 Ribbon Debug 等场景。

登录后查看全文
热门项目推荐
相关项目推荐