Avatar Group
An overlapping stack of avatars with built-in overflow. Cap how many show and the rest fold into a +N chip. The group owns the overlap, the ring separation and the hover lift; the children stay plain Avatars.
Installation#
Usage#
Wrap your Avatar children in AvatarGroup and set max. The group owns only the layout and the overflow chip: the avatars stay plain Avatars with no per-instance ring or z-index. Match the group's size to its children.
import { AvatarGroup } from "@/components/ui/avatar-group"
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar"
export function Team({ members }: { members: Member[] }) {
return (
<AvatarGroup size="md" max={4} total={members.length}>
{members.slice(0, 4).map((m) => (
<Avatar key={m.id} size="md">
<AvatarImage src={m.avatar} alt={m.name} />
<AvatarFallback>{m.initials}</AvatarFallback>
</Avatar>
))}
</AvatarGroup>
)
}Sizes#
Set size on the group to match the avatars; it sizes the +N chip and tightens the overlap as the box grows, so the stack stays a single cluster at every size.
Fallbacks#
With no image the avatar shows its initials. Inside a group, give each fallback a color so the stack reads as distinct people instead of a row of identical gray chips: pass one of the Avatar color hues per child and stride-mix them so no two neighbours share a tint. The neutral gray default is fine for a lone avatar, not for a cluster. The +N chip stays neutral since it's a count, not initials.
Overflow#
max caps the avatars shown; everything past it collapses into a single +N chip. Pass total when more people exist than you render (e.g. a server count) so the chip reflects the real number. Omit max to show every avatar.
Custom overflow#
Take over the chip with renderOverflow, which receives the overflow count. Return any node: here the chip is a Tooltip that names the people the stack hides, riding the same shared bubble as the avatars.
API reference#
AvatarGroup
A <div> that lays out its Avatar children as an overlapping stack and appends the overflow chip. Its children sit inside a TooltipGroup, so every Tooltip in the stack shares one gliding bubble. Forwards all native div props; className is merged last.
size—xs | sm | md | lg | xl(defaultmd). Sizes the chip and the overlap; pass the same value you set on the children.max— cap the visible avatars; the rest fold into the+Nchip.total— the real count when it exceeds the rendered avatars, so+Nreflects it.renderOverflow—(overflow: number) => ReactNode; replace the default chip with a custom affordance.