Badge
Badge indicates quantitative data associated with a parent element.
Anatomy

- High Emphasis: For conveying notifications.
- Low Emphasis: For conveying non-pertinent quantitative data.
- High Emphasis Inverse: For use on backgrounds darker than 500 level.
- Low Emphasis Inverse: For use on backgrounds darker than 500 level.
Usage Guidance
When to Use
- Use a Badge to indicate quantitative data associated with a parent element (e.g., icons, applets, Avatars, text, etc.).
When to Consider Something Else
- Consider using a Status Indicator to identify the status of a task.
Behaviors
Expansion
A Low Emphasis Badge should always expand rightwards from its absolute position when featuring a larger count and / or descriptive metadata. When expanding beyond 99, the count cuts off at 99+.

Screen Readers
When a Low Emphasis Badge is used in-line with text, the order in which it is read should be configurable, so it can be read how it makes the most logical sense. High Emphasis Badges do not have focus stops, since they do not support text.
High Emphasis
High Emphasis Badges are intended for usage as an indicator of notification.

After navigating resolving the source of the notification, the Badge should no longer appear. However, High Emphasis Badges may not always disappear after resolving an item if it is representative of multiple pieces of data.
Low Emphasis
Low Emphasis Badges are intended for conveying less pertinent numerical information. By accepting text, these Badges also allow for additional descriptive text to be passed in to compliment the numerical data.

Low Emphasis Badges could be used in the place of using parentheses to convey quantitative data.
After resolving the source of the indicator, the Badge should either augment down or not appear if it is representative of a standalone piece of data.
Examples
The following section provides examples for common use cases. Please be sure to also read the Accessibility section below.
Basic
Use the default CountBadge variant for most situations. The default high emphasis is ideal for
drawing attention to important or primary information.
import {CountBadge} from '@workday/canvas-kit-react/badge';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const containerStyles = createStyles({
display: 'flex',
gap: system.space.x2,
padding: system.space.x4,
});
export default () => {
return (
<div className={containerStyles}>
<CountBadge count={427} />
</div>
);
};
Emphasis
Select the low emphasis option for less prominent or secondary information. This is useful when
you want the badge to be visible but not distracting.
high emphasis is ideal for drawing attention to important or primary information.
import {CountBadge} from '@workday/canvas-kit-react/badge';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
import {Text} from '@workday/canvas-kit-react/text';
const containerStyles = createStyles({
display: 'flex',
gap: system.space.x2,
padding: system.space.x4,
flexDirection: 'column',
});
const textStyles = createStyles({
paddingInlineEnd: system.space.x2,
});
export default () => {
return (
<div className={containerStyles}>
<div>
<Text as="strong" className={textStyles}>
Low Emphasis:
</Text>
<CountBadge count={427} emphasis="low" />
</div>
<div>
<Text as="strong" className={textStyles}>
High Emphasis:
</Text>
<CountBadge count={427} emphasis="high" />
</div>
</div>
);
};
Inverse
Apply the inverse variant when displaying the badge on dark or accent backgrounds to maintain
proper contrast and readability. This ensures the badge remains legible in visually dense or colored
areas. The same rules apply for low and high emphasis. Only use this combination on backgrounds with
a token of 600 or greater
to ensure sufficient contrast and accessibility.
import {CountBadge} from '@workday/canvas-kit-react/badge';
import {createStyles, cssVar} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
import {Text} from '@workday/canvas-kit-react/text';
const containerStyles = createStyles({
display: 'flex',
gap: system.space.x2,
padding: system.space.x4,
backgroundColor: system.color.static.blue.default,
flexDirection: 'column',
});
const textStyles = createStyles({
paddingInlineEnd: system.space.x2,
});
export default () => {
return (
<div className={containerStyles}>
<div>
<Text as="strong" variant="inverse" className={textStyles}>
Low Emphasis:
</Text>
<CountBadge count={427} variant="inverse" emphasis="low" />
</div>
<div>
<Text as="strong" variant="inverse" className={textStyles}>
High Emphasis
</Text>
<CountBadge count={427} variant="inverse" emphasis="high" />
</div>
</div>
);
};
Custom Limit
By default, CountBadge’s limit is set to 1000. Once the count reaches the limit, the badge will
format the number: 1000 becomes 999+. The default limit is largely arbitrary and intended to
prevent unexpected overflow. You should choose a limit based on your specific use case and consider
the user’s experience. For example, someone looking for a new job finds there are 99+ new
opportunities. Or perhaps someone returns from extended leave and is overwhelmed by 999+ unread
messages on their first day back.
import * as React from 'react';
import {CountBadge} from '@workday/canvas-kit-react/badge';
import {TertiaryButton} from '@workday/canvas-kit-react/button';
import {createStyles} from '@workday/canvas-kit-styling';
import {system} from '@workday/canvas-tokens-web';
const columnStyles = createStyles({
boxSizing: 'border-box',
display: 'flex',
flexDirection: 'column',
gap: system.space.x4,
});
const controls = createStyles({
boxSizing: 'border-box',
borderBottom: `solid 1px ${system.color.border.divider}`,
display: 'flex',
gap: system.space.x1,
padding: system.space.x1,
});
const defaultBackground = createStyles({
boxSizing: 'border-box',
backgroundColor: system.color.bg.alt.soft,
padding: system.space.x4,
});
const inverseBackground = createStyles({
boxSizing: 'border-box',
backgroundColor: system.color.bg.primary.default,
padding: system.space.x4,
});
const initialCount = 1;
export default () => {
const [count, setCount] = React.useState(initialCount);
return (
<div className={columnStyles}>
<div className={controls}>
<TertiaryButton size="small" onClick={() => setCount(count + 1)}>
Increment
</TertiaryButton>
<TertiaryButton size="small" onClick={() => setCount(initialCount)}>
Reset
</TertiaryButton>
</div>
<div className={defaultBackground}>
<CountBadge count={count} limit={10} />
</div>
<div className={inverseBackground}>
<CountBadge count={count} limit={10} variant="inverse" />
</div>
</div>
);
};
Accessibility
Notification Badge
Notifications are a major use case for CountBadge. When the CountBadge value is updated in
real-time, screen readers must be supported with an AriaLiveRegion that will automatically
describe the change in the number of notifications. If the web app only updates CountBadge as part
of another screen update, then this use of AriaLiveRegion is unnecessary and not recommended.
Tooltipis set on theSecondaryButtonautomatically applying thearia-labelto the button.aria-describedbyproperty is conditionally set on theSecondaryButtonwhen greater than zero referencing a uniqueidfor theCountBadgevalue .AriaLiveRegionis used around theCountBadge, enabling screen readers to monitor changes in value.aria-labelstring is conditionally set onAriaLiveRegionwhen greater than zero, describing “New notification”
import * as React from 'react';
import {CountBadge} from '@workday/canvas-kit-react/badge';
import {SecondaryButton, TertiaryButton} from '@workday/canvas-kit-react/button';
import {AriaLiveRegion, useUniqueId} from '@workday/canvas-kit-react/common';
import {createStyles, cssVar} from '@workday/canvas-kit-styling';
import {notificationsIcon} from '@workday/canvas-system-icons-web';
import {system} from '@workday/canvas-tokens-web';
import {Tooltip} from '@workday/canvas-kit-react/tooltip';
import {Flex} from '@workday/canvas-kit-react/layout';
function negate(value: string, fallback?: string) {
return `calc(${cssVar(value, fallback)} * -1)`;
}
const container = createStyles({
boxSizing: 'border-box',
flexDirection: 'column',
gap: system.space.x4,
});
const controls = createStyles({
boxSizing: 'border-box',
gap: system.space.x2,
padding: system.space.x1,
});
const notificationContainerStyles = createStyles({
boxSizing: 'border-box',
position: 'relative',
});
const countBadgeStyles = createStyles({
boxSizing: 'border-box',
position: 'absolute',
top: negate(system.space.x1),
insetInlineEnd: negate(system.space.x1),
});
// Testing notes (Aug. 30, 2024):
// Windows 11
// JAWS 2024 + Chrome / Edge: "New notifications" once, then only the count change "2"
// JAWS 2024 + FF: "New notifications" once, then describes nothing
// NVDA + Chrome / Edge: Consistently describes "{X} New notifications"
// NVDA + FF: Consistently describes count value only "{X}"
// macOS v14.6.1
// VoiceOver + Chrome / Safari: Consistently describes "New notifications {X}"
export default () => {
const [count, setCount] = React.useState(4);
const badgeID = useUniqueId();
return (
<Flex cs={container}>
<Flex cs={controls}>
<TertiaryButton size="small" onClick={() => setCount(count + 1)}>
Add Notification
</TertiaryButton>
<TertiaryButton size="small" onClick={() => setCount(0)}>
Clear
</TertiaryButton>
</Flex>
<Flex>
<span className={notificationContainerStyles}>
<Tooltip title="Notifications">
<SecondaryButton
size="medium"
icon={notificationsIcon}
aria-describedby={!!count ? badgeID : undefined}
/>
</Tooltip>
<AriaLiveRegion aria-label={!!count ? 'New notifications' : undefined}>
{!!count && <CountBadge id={badgeID} count={count} limit={100} cs={countBadgeStyles} />}
</AriaLiveRegion>
</span>
</Flex>
</Flex>
);
};
Custom Styles
Count Badge supports custom styling via the cs prop. For more information, check our
“How To Customize Styles”.
Component API
CountBadge
CountBadge provides a quantity-based summary with dynamic values.
Props
Props extend from span. Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
count | number | Sets the count displayed in the badge | 0 |
emphasis | 'high' | 'low' | Sets the emphasis of the badge | 'high' |
limit | number | Sets the maximum count to display before formatting the number.
E.g. Given a count of | 1000 |
variant | 'inverse' | Sets the variant of the Count Badge | |
cs | | The | |
children | React.ReactNode | ||
as | React.ElementType | Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | span |
ref | React.Ref<R = span> | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If |
Anatomy

- High Emphasis Variant: For conveying notifications.
- Stroke (Optional): Differentiates the container from its parent in overlapping instances.
- Low Emphasis Variant: For conveying non-pertinent quantitative data.
- Container: Round circle with fixed height and dynamic width.
- Count: Centered dynamic value that communicates quantities in low emphasis variations.
Usage Guidance
When to Use
- Use a Badge to indicate quantitative data associated with a parent element (e.g., icons, applets, Avatars, text, etc.).
When to Consider Something Else
- Consider using a Status Indicator to identify the status of a task.
Behaviors
Strokes
Both High and Low Emphasis Badges feature an optional stroke that increases visibility by delineating a Badge from its parent in overlapping instances.

Adding a stroke may also be appropriate to ensure graphic contrast guidelines are being upheld against certain background fills.
Expansion
A Low Emphasis Badge should always expand rightwards from its absolute position when featuring a larger count and / or descriptive metadata. When expanding beyond 99, the count cuts off at 99+.

Screen Readers
When a Low Emphasis Badge is used in-line with text, the order in which it is read should be configurable, so it can be read how it makes the most logical sense. High Emphasis Badges do not have focus stops, since they do not support text.
Examples
Badges vary on the basis of emphasis and size.
High Emphasis
High Emphasis Badges are intended for usage as an indicator of notification.

After navigating resolving the source of the notification, the Badge should no longer appear. However, High Emphasis Badges may not always disappear after resolving an item if it is representative of multiple pieces of data.
Low Emphasis
Low Emphasis Badges are intended for conveying less pertinent numerical information. By accepting text, these Badges also allow for additional descriptive text to be passed in to compliment the numerical data.

Low Emphasis Badges should always be used in the place of using parentheses to convey quantitative data.

Do
Use low emphasis variations to convey quantitative data in place of parentheses.

Don't
Use parentheses to convey quantitative data in text items.
After resolving the source of the indicator, the Badge should either augment down or not appear if it is representative of a standalone piece of data.
Sizing
Badges are available in small for high emphasis variations and medium and large for low emphasis variations.

High emphasis variations only come in small to declutter the UI and cognitive load of users pertaining to work-related notifications. Choosing between medium and large for low emphasis variations should be based on the sizing of the parent UI element. When used in-line with text for example, the Badge should not exceed the type size of the parent. Low Emphasis Badges are intended to blend in with the UI.

API Guidelines
Low Emphasis Badge View
Component Definition
This view creates a Low Emphasis Badge that you can use however you need.
Methods
Class name: LowEmphasisBadgeViewAPI Module name: UIComponentsPlugin
public init(
count: Int,
size: LowEmphasisBadgeSize,
showStroke: Bool = false,
localizer: LocalizationAdapting,
featureData: FeatureMetricsData
)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| count | Int | The written count to display inside the badge. | |
| size | LowEmphasisBadgeSize | Parameter that allows you to set the size of the Low Emphasis Badge | |
| showStroke | Bool | false | Optional Bool which allows you to show the stroke on the badge or not. Default is false. |
| localizer | LocalizationAdapting | Localization provider | |
| featureData | FeatureMetricsData |
Low Emphasis Badge View Modifier
Component Definition
This view modifier is used to apply a Low Emphasis Badge to the trailing top edge of a view.
Methods
Class name: LowEmphasisBadgeAPI Module name: UIComponentsPlugin
public extension View {
func applyLowEmphasisBadge(
count: Int,
size: LowEmphasisBadgeSize,
showStroke: Bool = false,
localizer: LocalizationAdapting,
featureData: FeatureMetricsData
) -> some View
}Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| count | Int | The written count to display inside the badge. | |
| size | LowEmphasisBadgeSize | Parameter that allows you to set the size of the Low Emphasis Badge | |
| showStroke | Bool | false | Optional Bool which allows you to show the stroke on the badge or not. Default is false. |
| localizer | LocalizationAdapting | Localization provider | |
| featureData | FeatureMetricsData |
Low Emphasis Badge on Avatar
Component Definition
This view modifier is used to apply a Low Emphasis Badge to the trailing top edge of an avatar. Only certain sized avatars are allowed to apply the badge so this modifier will account for that and 0nly apply the badge to valid avatar sizes.
Methods
Class name: LowEmphasisBadgeAPI Module name: UIComponentsPlugin
public extension Avatar {
func applyLowEmphasisBadge(
count: Int,
showStroke: Bool = false,
localizer: LocalizationAdapting,
featureData: FeatureMetricsData
) -> some View
}Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| count | Int | The written count to display inside the badge. | |
| showStroke | Bool | false | Optional Bool which allows you to show the stroke on the badge or not. Default is false. |
| localizer | LocalizationAdapting | Localization provider | |
| featureData | FeatureMetricsData |
High Emphasis Badge
Component Definition
This view modifier is used to apply a Low Emphasis Badge to the trailing top edge of a view.
Methods
Class name: HighEmphasisBadgeAPI Module name: UIComponentsPlugin
public extension View {
func applyHighEmphasisBadge(
showStroke: Bool = false,
localizer: LocalizationAdapting,
featureData: FeatureMetricsData,
offsetX: CGFloat = 0,
offsetY: CGFloat = 0
) -> some View
}Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| showStroke | Bool | false | Optional Bool which allows you to show the stroke on the badge or not. Default is false. |
| localizer | LocalizationAdapting | Localization provider | |
| featureData | FeatureMetricsData | ||
| offsetX | CGFloat | 0 | A CGFloat that allows you to position the HighEmphasisBadge in the X axis. This number is inverted so that positive values push it towards the leading edge. Default is 0. |
| offsetY | CGFloat | 0 | A CGFloat that allows you to position the HighEmphasisBadge in the Y axis. Default is 0. |
Accessibility Guidelines
Coming soon…
Content Guidelines
Coming soon…
Anatomy

- High Emphasis Variant: For conveying notifications.
- Stroke (Optional): Differentiates the container from its parent in overlapping instances.
- Low Emphasis Variant: For conveying non-pertinent quantitative data.
- Container: Round circle with fixed height and dynamic width.
- Count: Centered dynamic value that communicates quantities in low emphasis variations.
Usage Guidance
When to Use
- Use a Badge to indicate quantitative data associated with a parent element (e.g., icons, applets, Avatars, text, etc.).
When to Consider Something Else
- Consider using a Status Indicator to identify the status of a task.
Behaviors
Strokes
Both High and Low Emphasis Badges feature an optional stroke that increases visibility by delineating a Badge from its parent in overlapping instances.

Adding a stroke may also be appropriate to ensure graphic contrast guidelines are being upheld against certain background fills.
Expansion
A Low Emphasis Badge should always expand rightwards from its absolute position when featuring a larger count and / or descriptive metadata. When expanding beyond 99, the count cuts off at 99+.

Screen Readers
When a Low Emphasis Badge is used in-line with text, the order in which it is read should be configurable, so it can be read how it makes the most logical sense. High Emphasis Badges do not have focus stops, since they do not support text.
Examples
Badges vary on the basis of emphasis and size.
High Emphasis
High Emphasis Badges are intended for usage as an indicator of notification.

After navigating resolving the source of the notification, the Badge should no longer appear. However, High Emphasis Badges may not always disappear after resolving an item if it is representative of multiple pieces of data.
Low Emphasis
Low Emphasis Badges are intended for conveying less pertinent numerical information. By accepting text, these Badges also allow for additional descriptive text to be passed in to compliment the numerical data.

Low Emphasis Badges should always be used in the place of using parentheses to convey quantitative data.

Do
Use low emphasis variations to convey quantitative data in place of parentheses.

Don't
Use parentheses to convey quantitative data in text items.
After resolving the source of the indicator, the Badge should either augment down or not appear if it is representative of a standalone piece of data.
Sizing
Badges are available in small for high emphasis variations and medium and large for low emphasis variations.

High emphasis variations only come in small to declutter the UI and cognitive load of users pertaining to work-related notifications. Choosing between medium and large for low emphasis variations should be based on the sizing of the parent UI element. When used in-line with text for example, the Badge should not exceed the type size of the parent. Low Emphasis Badges are intended to blend in with the UI.

API Guidelines
Low Emphasis Badge View
Component Definition
This Composable creates a Low Emphasis Badge that you can use however you need.
Methods
Jvm name: LowEmphasisBadgeUiComponent
fun BadgeUiComponent(
modifier: Modifier = Modifier,
badgeCount: Int,
badgeSize: BadgeSize = BadgeSize.Medium,
showStroke: Boolean = false
)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| modifier | Modifier | Modifier | The modifier to apply to the component. |
| badgeCount | Int | The count to display in the badge. | |
| badgeSize | BadgeSize | [BadgeSize.Medium] | The size of the badge. |
| showStroke | Boolean | false | Whether to show a stroke around the badge. |
Low Emphasis Badge on Avatar
Component Definition
A convenience Composable to create an AvatarUiComponent with a badge that displays a count of items or notifications. This Composable is a wrapper around [AvatarUiComponent] and [BadgeUiComponent]. The badge will be displayed in the top right corner of the avatar and will be sized relative to the size of the avatar.
A AvatarSizeConfig.M will have a medium badge, a AvatarSizeConfig.L and AvatarSizeConfig.XL will have a large badge. All other avatar sizes are not supported and will throw an IllegalArgumentException.
Methods
Jvm name: AvatarUiComponentWithBadge
fun BadgeUiComponent(
modifier: Modifier = Modifier,
avatarSizeConfig: AvatarSizeConfig = AvatarSizeConfig.S,
avatarColorConfig: AvatarColorConfig? = null,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
onColorBackground: Boolean = false,
enabled: Boolean = true,
isLoading: Boolean = false,
initials: String,
fullName: String? = null,
imageResourceId: Int? = null,
bitmap: Bitmap? = null,
role: Role? = null,
clearSemantics: Boolean = true,
onClick: (() -> Unit)? = null,
badgeCount: Int,
showStroke: Boolean = false
)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| modifier | Modifier | Modifier | The modifier to apply to the component. |
| avatarSizeConfig | AvatarSizeConfig | AvatarSizeConfig.S | The size of the avatar. |
| avatarColorConfig | AvatarColorConfig | null | The color of the avatar. |
| interactionSource | MutableInteractionSource | remember { MutableInteractionSource() } | The interaction source for the avatar. |
| onColorBackground | Boolean | false | Whether the avatar is on a colored background. |
| enabled | Boolean | true | Whether the avatar is enabled. |
| isLoading | Boolean | false | Whether the avatar is loading. |
| initials | String | String to be displayed in the Avatar if no image is provided. Will only take the first two characters in the string or the entire string if its less than two characters. If you pass in an empty string but provide the full name we will parse the initials for you. | |
| fullName | String? | null | Nullable String used to generate initials if you don’t provide any. Will be ignored if you pass any initials in. |
| imageResourceId | Int? | null | The resource ID of the image to display in the avatar. |
| bitmap | Bitmap? | null | The bitmap to display in the avatar. |
| role | Role? | null | The role of the avatar. |
| clearSemantics | Boolean | true | Whether to clear the semantics of the avatar. |
| onClick | (() -> Unit)? | null | The click listener for the avatar. |
| badgeCount | Int | The count to display in the badge. | |
| showStroke | Boolean | false | Whether to show a stroke around the badge. |
High Emphasis Badge
Component Definition
This Composable creates a high emphasis badge that can be used to display a notification dot over another component.
Methods
Jvm name: HighEmphasisBadgeUiComponent
fun BadgeUiComponent(
modifier: Modifier = Modifier,
showStroke: Boolean = false
)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| modifier | Modifier | Modifier | The modifier to apply to the component. |
| showStroke | Boolean | false | Whether to show a stroke around the badge. Defaults to false. |
High Emphasis Badge Convenience Wrapper
Component Definition
This Composable creates a convenience wrapper for adding a high emphasis badge over another content. This version of the component allows for additional customization of the badge’s position. This is useful when the badge needs to be offset from the component it is overlaying.
Methods
Jvm name: ComponentWithAHighEmphasisBadge
fun BadgeUiComponent(
modifier: Modifier = Modifier,
showStroke: Boolean = false,
xOffset: Dp = 0.dp,
yOffset: Dp = 0.dp,
content: @Composable BoxScope.() -> Unit
)Parameters
| Name | Type | Default | Description |
|---|---|---|---|
| modifier | Modifier | Modifier | The modifier to apply to the component. |
| showStroke | Boolean | false | Whether to show a stroke around the badge. |
| xOffset | Dp | 0.dp | The horizontal offset of the badge. |
| yOffset | Dp | 0.dp | The vertical offset of the badge. |
| content | Boolean | @Composable BoxScope.() -> Unit | The content to display the badge over. |
Accessibility Guidelines
Coming soon!
Content Guidelines
Coming soon!
Can't Find What You Need?
Check out our FAQ section which may help you find the information you're looking for. For further information, contact the #ask-canvas-design or #ask-canvas-kitchannels on Slack.