展示类

头像

头像,支持图片或字符展示。

代码演示

如何引入

<script lang="ts">
    import { Avatar, AvatarGroup } from '@fibrae/semi-ui-svelte';
</script>

尺寸

可以通过 size 属性设置图标大小,支持extra-extra-small,extra-small,small,default,medium,large,extra-large。

U U U U U U U
代码
<script lang="ts">
    import { Avatar } from '@fibrae/semi-ui-svelte';

    const sizes = ['extra-extra-small', 'extra-small', 'small', 'default', 'medium', 'large', 'extra-large'];
</script>

<div>
    {#each sizes as size (size)}
        <Avatar alt="用户" {size} style="margin: 4px">U</Avatar>
    {/each}
</div>

颜色

Avatar 支持默认色板的 15 种颜色和白色,包括:amber、 blue、 cyan、 green、 grey、 indigo、 light-blue、 light-green、 lime、 orange、 pink、 purple、 red、 teal、 violet、 yellow。也可以通过 style 来自定义颜色样式。默认为grey。

AS BM TJ ZL YZ
代码
<script lang="ts">
    import { Avatar } from '@fibrae/semi-ui-svelte';
</script>

<div>
    <Avatar alt="Alice Swift" style="margin: 4px">AS</Avatar>
    <Avatar alt="Bob Matteo" color="red" style="margin: 4px">BM</Avatar>
    <Avatar alt="Taylor Joy" color="light-blue" style="margin: 4px">TJ</Avatar>
    <Avatar alt="Zank Lance" style="color: #f56a00; background-color: #fde3cf; margin: 4px">ZL</Avatar>
    <Avatar alt="Youself Zhang" style="background-color: #87d068; margin: 4px">YZ</Avatar>
</div>

自适应字符大小

字符类型的头像,字体大小会根据头像宽度自适应调整。使用gap调整字符头像距离左右两侧的像素大小。

AS Semi Semi
代码
<script lang="ts">
    import { Avatar } from '@fibrae/semi-ui-svelte';
</script>

<div>
    <Avatar style="margin: 4px">AS</Avatar>
    <Avatar gap={4} style="margin: 4px">Semi</Avatar>
    <Avatar gap={10} style="margin: 4px">Semi</Avatar>
</div>

图片

可以通过 src 设置图片格式的头像。

漂亮的猫咪 可爱的猫咪
代码
<script lang="ts">
    import { Avatar } from '@fibrae/semi-ui-svelte';

    const src = '/assets/placeholder/avatar-a.svg';
</script>

<div>
    <Avatar alt="漂亮的猫咪" {src} style="margin: 4px" />
    <Avatar alt="可爱的猫咪" size="small" {src} style="margin: 4px" />
</div>

形状

Avatar 支持 circle、square 两种形状,默认为 circle。

U U
代码
<script lang="ts">
    import { Avatar } from '@fibrae/semi-ui-svelte';
</script>

<div>
    <Avatar alt="用户" style="margin: 4px">U</Avatar>
    <Avatar alt="用户" shape="square" style="margin: 4px">U</Avatar>
</div>

事件

Avatar 支持 onclick、onMouseEnter、onMouseLeave,传了 onclick 才成为可聚焦的 button。通过 hoverMask snippet 传入悬停覆盖层,用 {#snippet hoverMask()}...{/snippet} 写在 Avatar 标签内,覆盖层无默认样式。

BD
代码
<script lang="ts">
    import { IconCamera } from '@fibrae/semi-icons-svelte';
    import { Avatar } from '@fibrae/semi-ui-svelte';
</script>

<Avatar alt="Bob Downton" color="red">
    BD
    {#snippet hoverMask()}
        <div style="background-color: var(--semi-color-overlay-bg); height: 100%; width: 100%; display: flex; align-items: center; justify-content: center">
            <IconCamera />
        </div>
    {/snippet}
</Avatar>

顶部和底部 Slot

topSlot、bottomSlot 属性配置标记外观,topSlotText、bottomSlotText snippet 提供内容。topSlot.render、bottomSlot.render 传 snippet 时,由它完全渲染标记;topSlot.style、bottomSlot.style 是字符串。

漂亮的猫咪
直播
代码
<script lang="ts">
    import { IconPlus } from '@fibrae/semi-icons-svelte';
    import { Avatar } from '@fibrae/semi-ui-svelte';
</script>

<Avatar alt="漂亮的猫咪" border={{ color: '#FE2C55', motion: true }} bottomSlot={{ shape: 'circle', bgColor: '#FE2C55' }} contentMotion size="large" src="/assets/placeholder/avatar-a.svg" style="margin: 4px" topSlot={{ gradientStart: 'rgb(255,23,100)', gradientEnd: 'rgb(237,52,148)' }}>
    {#snippet topSlotText()}直播{/snippet}
    {#snippet bottomSlotText()}
        <IconPlus />
    {/snippet}
</Avatar>

顶部

T
直播
T
直播
T
直播
代码
<script lang="ts">
    import { Avatar } from '@fibrae/semi-ui-svelte';

    const sizes = ['medium', 'large', 'extra-large'];
</script>

<div>
    {#each sizes as size (size)}
        <Avatar color="amber" {size} topSlot={{ gradientStart: 'rgb(255,23,100)', gradientEnd: 'rgb(237,52,148)' }}>
            T
            {#snippet topSlotText()}直播{/snippet}
        </Avatar>
    {/each}
</div>

底部

T
直播中
T
直播中
T
直播中



T
T
T
代码
<script lang="ts">
    import { IconPlus } from '@fibrae/semi-icons-svelte';
    import { Avatar } from '@fibrae/semi-ui-svelte';

    const sizes = ['medium', 'large', 'extra-large'];
</script>

<div>
    {#each sizes as size (size)}
        <Avatar bottomSlot={{ shape: 'square', bgColor: '#FE2C55' }} color="amber" {size}>
            T
            {#snippet bottomSlotText()}直播中{/snippet}
        </Avatar>
    {/each}
    <br /><br /><br />
    {#each sizes as size (size)}
        <Avatar bottomSlot={{ shape: 'circle', bgColor: '#FE2C55' }} color="amber" {size}>
            T
            {#snippet bottomSlotText()}
                <IconPlus />
            {/snippet}
        </Avatar>
    {/each}
</div>

额外边框

T
T
T
代码
<script lang="ts">
    import { Avatar } from '@fibrae/semi-ui-svelte';
</script>

<div>
    {#each [1, 2, 3] as index (index)}
        <Avatar border color="amber" style="margin-right: 8px">T</Avatar>
    {/each}
</div>

额外动效

通过 border 的 motion 字段和 contentMotion 开启边框和内容区域的额外动效。

T
T
T
代码
<script lang="ts">
    import { Avatar } from '@fibrae/semi-ui-svelte';

    const sizes = ['medium', 'large', 'extra-large'];
</script>

<div>
    {#each sizes as size (size)}
        <Avatar border={{ motion: true }} color="amber" contentMotion {size} style="margin-right: 8px">T</Avatar>
    {/each}
</div>

头像组

可以通过 AvatarGroup 将 avatar 显示为组。

Svelte 的 AvatarGroup 用 items 传入每个头像的属性,用 item snippet(参数 { item, index })提供头像内的文字,不接受 Avatar 子节点。

LL CX RM ZL YZ
代码
<script lang="ts">
    import { AvatarGroup } from '@fibrae/semi-ui-svelte';

    const items = [{ alt: 'Lisa LeBlanc', color: 'red' as const }, { alt: 'Caroline Xiao' }, { alt: 'Rafal Matin', color: 'amber' as const }, { alt: 'Zank Lance', style: 'color: #f56a00; background-color: #fde3cf' }, { alt: 'Youself Zhang', style: 'background-color: #87d068' }];

    const initials = (alt = '') =>
        alt
            .split(' ')
            .map((word) => word[0])
            .join('');
</script>

<div>
    <AvatarGroup {items}>
        {#snippet item({ item })}
            {initials(item.alt)}
        {/snippet}
    </AvatarGroup>
</div>

可以通过 maxCount 设置展示的头像数量。

LL CX RM +2
代码
<script lang="ts">
    import { AvatarGroup } from '@fibrae/semi-ui-svelte';

    const items = [{ alt: 'Lisa LeBlanc', color: 'red' as const }, { alt: 'Caroline Xiao' }, { alt: 'Rafal Matin', color: 'amber' as const }, { alt: 'Zank Lance', style: 'color: #f56a00; background-color: #fde3cf' }, { alt: 'Youself Zhang', style: 'background-color: #87d068' }];

    const initials = (alt = '') =>
        alt
            .split(' ')
            .map((word) => word[0])
            .join('');
</script>

<div>
    <AvatarGroup {items} maxCount={3}>
        {#snippet item({ item })}
            {initials(item.alt)}
        {/snippet}
    </AvatarGroup>
</div>

可以通过 more snippet 自定义 more 标签,参数为 { restNumber, restAvatars }。restAvatars 是被隐藏的完整数据项(items 中的对应项);头像的文字内容由 item snippet 提供,不在数据项里。

LL CX RM +2
代码
<script lang="ts">
    import { Avatar, AvatarGroup, Popover } from '@fibrae/semi-ui-svelte';

    const items = [{ alt: 'Lisa LeBlanc', color: 'red' as const }, { alt: 'Caroline Xiao' }, { alt: 'Rafal Matin', color: 'amber' as const }, { alt: 'Zank Lance', style: 'color: #f56a00; background-color: #fde3cf' }, { alt: 'Youself Zhang', style: 'background-color: #87d068' }];

    const initials = (alt = '') =>
        alt
            .split(' ')
            .map((word) => word[0])
            .join('');
</script>

<AvatarGroup {items} maxCount={3}>
    {#snippet item({ item })}
        {initials(item.alt)}
    {/snippet}
    {#snippet more({ restNumber, restAvatars })}
        <Popover autoAdjustOverflow={false} position="bottomRight" style="padding: 12px 8px; padding-bottom: 0">
            <!-- the trigger props go on the avatar itself: a wrapper span would put a non-listitem tab stop inside the group's list -->
            {#snippet child({ props })}
                <Avatar {...props}>{`+${restNumber}`}</Avatar>
            {/snippet}
            {#snippet content()}
                <div>
                    {#each restAvatars as avatar (avatar.alt)}
                        <div style="padding-bottom: 12px">
                            <Avatar {...avatar} size="extra-small">{initials(avatar.alt)}</Avatar>
                            <span style="margin-left: 8px; font-size: 14px">这是段文字描述</span>
                        </div>
                    {/each}
                </div>
            {/snippet}
        </Popover>
    {/snippet}
</AvatarGroup>

可以通过 overlapFrom 控制头像组的覆盖方式。可选值有 start 和 end,分别表示左边覆盖右边和右边覆盖左边。默认值为 start。

LL CX RM ZL YZ
LL CX RM ZL YZ
代码
<script lang="ts">
    import { AvatarGroup } from '@fibrae/semi-ui-svelte';

    const directions = ['start', 'end'] as const;

    const items = [{ alt: 'Lisa LeBlanc', color: 'red' as const }, { alt: 'Caroline Xiao' }, { alt: 'Rafal Matin', color: 'amber' as const }, { alt: 'Zank Lance', style: 'color: #f56a00; background-color: #fde3cf' }, { alt: 'Youself Zhang', style: 'background-color: #87d068' }];

    const initials = (alt = '') =>
        alt
            .split(' ')
            .map((word) => word[0])
            .join('');
</script>

<div>
    {#each directions as direction (direction)}
        <div>
            <AvatarGroup {items} overlapFrom={direction}>
                {#snippet item({ item })}
                    {initials(item.alt)}
                {/snippet}
            </AvatarGroup>
        </div>
    {/each}
</div>

API 参考


Avatar

Props

属性说明类型默认值
alt头像图片或文字的替代文本。string-
border显示额外边框,可配置颜色和动画。boolean | { color?: string; motion?: boolean }-
bottomSlot底部标记的形状、背景色、文字颜色、类名和样式字符串;内容使用 bottomSlotText snippet,render 为 snippet 时完全自定义标记。AvatarBottomSlot-
bottomSlotText预设底部标记中的文字或节点的 snippet。Snippet-
children头像的文字或自定义内容的 snippet。Snippet-
color头像的预设背景颜色。AvatarColor"grey"
contentMotion启用头像内容区域的动画。boolean-
gap字符内容与头像左右两侧的间距,单位为像素。number3
hoverMask悬停时显示的覆盖层的 snippet,自行设置样式。Snippet-
imgAttr传给内部 img 元素的原生属性。HTMLImgAttributes-
onError图片加载失败时调用,返回 false 阻止默认回退。Type() => boolean | void-
onMouseEnter指针进入头像时调用。Type(event: MouseEvent) => void-
onMouseLeave指针离开头像时调用。Type(event: MouseEvent) => void-
shape头像形状,可选 circle 或 square。AvatarShape-
size头像尺寸,支持预设名称或合法 CSS 尺寸。string-
src图片头像的资源地址。string-
srcSet图片头像的响应式资源集合。string-
topSlot顶部标记的渐变色、文字颜色、类名和样式字符串;内容使用 topSlotText snippet,render 为 snippet 时完全自定义标记。AvatarTopSlot-
topSlotText预设顶部标记中的文字或节点的 snippet。Snippet-

class、style、id 与其他原生属性落在头像 span 上;使用 border、topSlot 或 bottomSlot 时,style 落在外层包裹元素上,class 与其他原生属性仍落在头像 span 上。可点击头像的 tabindex、aria-* 落在内部唯一的焦点元素上。

AvatarGroup

Props

属性说明类型默认值
item每个头像内容的 snippet,参数为 { item, index },优先于数据项自带的 children。TypeSnippet<[AvatarGroupItemContext]>-
items组内头像的数据,每项是 Avatar 的属性;组的 size、shape 覆盖数据项自己的。AvatarGroupItem[][]
maxCount显示的最大头像数,超出后显示 +N。number-
more自定义溢出标签的 snippet,参数为 { restNumber, restAvatars }:剩余数量与被隐藏的数据项。TypeSnippet<[AvatarGroupMoreContext]>-
overlapFrom头像重叠方向,可选 start 或 end。AvatarGroupOverlapFrom"start"
shape组内头像的形状。AvatarGroupShape"circle"
size组内头像的尺寸。string"medium"

class、style 与原生属性(包括 aria-*)落在 AvatarGroup 根元素上,不会传给组内的头像。

Accessibility

  • Avatar 一般不用于操作,不需要被获取焦点。但当 Avatar 可以被点击操作时(如:Semi 官网上方的头像)需要被聚焦,并响应键盘 Enter 和空格事件。
  • 可点击且有图片或文字的 Avatar 只有一个 Tab 停靠点,即图片或文字标签;它收到的焦点顺序与 aria-* 属性(包括 Tooltip 注入的)都落在这个元素上。
  • 当 Avatar 与其他组件结合使用时,需要同时检查该组件的可访问性指南。
  • Avatar的alt属性可以被屏幕阅读器读取,使用头像组件时,请使用alt 属性解释头像的内容。
<script lang="ts">
    import { Avatar } from '@fibrae/semi-ui-svelte';

    const src = '/assets/placeholder/avatar-a.svg';
</script>

<Avatar alt="一只可爱的猫咪" {src} />
<Avatar alt="姜鹏志" {src} />

替代文本描述头像内容,避免空字符串,也不必重复说明「图片」。可点击时用 onclick 声明操作,组件自动提供 Tab 停靠点,并将 Enter 和空格转为点击。

设计变量

下表是组件内部的 Sass 变量,不能覆写。定制样式请覆写 --semi-* CSS 变量(见 Design Token 页),或写不分层的 CSS 规则。
Sass 变量值用法
$animation_duration-additionalBorder800ms边框动画持续时间
$animation_duration-content1000ms内容动画持续时间
$animation_opacity-additionalBorder-start1边框动画起始透明度
$animation_opacity-additionalBorder-end0边框动画结束透明度
$animation_scale-additionalBorder-start1边框动画起始缩放比例
$animation_scale-additionalBorder-end1.15边框动画结束缩放比例
$animation_scale-content-start1边框动画起始缩放比例
$animation_scale-content-middle0.9边框动画中间态缩放比例
$z-avatar-default100头像 z-index
$color-avatar_default-border-defaultvar(--semi-color-bg-1)头像描边颜色
$color-avatar_more_default-bg-defaultvar(--semi-grey-5)「更多」描边颜色
$color-avatar-outline-focus$color-focus-ring头像聚焦轮廓颜色
$width-avatar_extra_extra_small20px头像尺寸 - 极小
$font-avatar_extra_extra_small-size10px文本字号 - 极小
$font-avatar_extra_extra_small-lineHeight15px文本行高 - 极小
$width-avatar_extra_small24px头像尺寸 - 超小
$font-avatar_extra_small-size10px文本字号 - 超小
$font-avatar_extra_small-lineHeight15px文本行高 - 超小
$width-avatar_small32px头像尺寸 - 小
$width-avatar_default40px头像尺寸 - 默认
$width-avatar_medium48px头像尺寸 - 中
$width-avatar_large72px头像尺寸 - 大
$width-avatar_extra_large128px头像尺寸 - 超大
$font-avatar_extra_large-size64px文本字号 - 超大
$font-avatar_extra_large-lineHeight77px文本行高 - 超大
$radius-avatarvar(--semi-border-radius-circle)头像圆角
$width-avatar_extra_large-border3px头像组头像描边尺寸 - 超大
$spacing-avatar_extra_large-marginLeft-32px头像组头像左侧外边距 - 超大
$width-avatar_large-border3px头像组头像描边尺寸 - 大
$spacing-avatar_large-marginLeft-18px头像左侧外边距 - 大
$width-avatar_medium-border2px头像组头像描边尺寸 - 中
$spacing-avatar_medium-marginLeft-12px头像左侧外边距 - 中
$width-avatar_default-border2px头像组头像描边尺寸 - 默认
$spacing-avatar_default-marginLeft-12px头像左侧外边距 - 默认
$width-avatar_small-border2px头像组头像描边尺寸 - 小
$spacing-avatar_small-marginLeft-12px头像左侧外边距 - 小
$width-avatar_extra_small-border1px头像组头像描边尺寸 - 超小
$spacing-avatar_extra_small-marginLeft-10px头像左侧外边距 - 超小
$width-avatar_extra_extra_small-border1px头像组头像描边尺寸 - 极小
$spacing-avatar_extra_extra_small-marginLeft-4px头像左侧外边距 - 极小
$width-avatar-outline$width-focus-ring头像聚焦轮廓宽度
$width-avatar_additional-border1.5px额外描边尺寸
$color-avatar_additional-bordervar(--semi-color-primary)额外描边颜色
$spacing-avatar_additional-borderGap2px额外描边与内侧间距
$width-avatar-bottom_slot_circle_extra_small12pxextra small 头像底部 slot 圆形半径
$width-avatar-bottom_slot_circle_small12pxsmall 头像底部 slot 圆形半径
$width-avatar-bottom_slot_circle_default16pxdefault 头像底部 slot 圆形半径
$width-avatar-bottom_slot_circle_medium18pxmedium 头像底部 slot 圆形半径
$width-avatar-bottom_slot_circle_large28pxlarge 头像底部 slot 圆形半径
$width-avatar-bottom_slot_circle_extra_large28pxextra large 头像底部 slot 圆形半径
$color-avatar-bottom_slot_bgvar(--semi-color-primary)头像底部 slot 背景色
$radius-avatar-bottom_slot_square4px底部 slot square 圆角
$font-avatar_bottom_slot-extra_small-fontSize5pxextra small 底部 slot 文字大小
$font-avatar_bottom_slot-small-fontSize5pxsmall 底部 slot 文字大小
$font-avatar_bottom_slot-default-fontSize12pxdefault 底部 slot 文字大小
$font-avatar_bottom_slot-medium-fontSize12pxmedium 底部 slot 文字大小
$font-avatar_bottom_slot-large-fontSize12pxlarge 底部 slot 文字大小
$font-avatar_bottom_slot-extra_large-fontSize14pxextra large 底部 slot 文字大小
$spacing-avatar-bottom_slot_square-paddingX4px底部 slot square 形状左边距
$spacing-avatar-bottom_slot_square-paddingY1px底部 slot square 形状右边距
$font-avatar_top_slot-small-fontSize5pxsmall 顶部 slot 文字大小
$font-avatar_top_slot-default-fontSize6pxdefault 顶部 slot 文字大小
$font-avatar_top_slot-medium-fontSize8pxmedium 顶部 slot 文字大小
$font-avatar_top_slot-large-fontSize14pxlarge 顶部 slot 文字大小
$font-avatar_top_slot-extra_large-fontSize16pxextra large 顶部 slot 文字大小
$spacing-avatar-top_slot_small-content-marginTop0pxsmall 顶部文字 marginTop
$spacing-avatar-top_slot_default-content-marginTop-2pxdefault 顶部文字 marginTop
$spacing-avatar-top_slot_medium-content-marginTop0pxmedium 顶部文字 marginTop
$spacing-avatar-top_slot_large-content-marginTop0pxlarge 顶部文字 marginTop
$spacing-avatar-top_slot_extra_large-content-marginTop0pxextra large 顶部文字 marginTop
$color-avatar-bottom_slot_square-bordervar(--semi-color-bg-0)底部 square 边框颜色
$width-avatar-bottom_slot_square_extra_small-border2pxsmall 头像底部 square 边框宽度
$width-avatar-bottom_slot_square_small-border2pxsmall 头像底部 square 边框宽度
$width-avatar-bottom_slot_square_default-border2pxdefault 头像底部 square 边框宽度
$width-avatar-bottom_slot_square_medium-border2pxmedium 头像底部 square 边框宽度
$width-avatar-bottom_slot_square_large-border2pxlarge 头像底部 square 边框宽度
$width-avatar-bottom_slot_square_extra_large-border2pxextra large 头像底部 square 边框宽度
$color-avatar-top_slot_textvar(--semi-color-bg-0)顶部 Slot 文字颜色
$spacing-avatar-top_slot_small-shift-28pxsmall 顶部 slot 偏移量, 和 scale 一起控制 slot 的位置
$spacing-avatar-top_slot_default-shift-32pxdefault 顶部 slot 偏移量, 和 scale 一起控制 slot 的位置
$spacing-avatar-top_slot_medium-shift-30pxmedium 顶部 slot 偏移量, 和 scale 一起控制 slot 的位置
$spacing-avatar-top_slot_large-shift-30pxlarge 顶部 slot 偏移量, 和 scale 一起控制 slot 的位置
$spacing-avatar-top_slot_extra_large-shift-32pxextra large 顶部 slot 偏移量, 和 scale 一起控制 slot 的位置
$spacing-avatar-top_slot_small-scale0.4small 顶部 slot 缩放比例
$spacing-avatar-top_slot_default-scale0.7default 顶部 slot 缩放比例
$spacing-avatar-top_slot_medium-scale0.8medium 顶部 slot 缩放比例
$spacing-avatar-top_slot_large-scale1.1large 顶部 slot 缩放比例
$spacing-avatar-top_slot_extra_large-scale1.4large 顶部 slot 缩放比例
$radius-avatar_extra_extra_small3px极小尺寸头像的圆角
$radius-avatar_extra_small3px超小尺寸头像的圆角
$radius-avatar_small3px小尺寸头像的圆角
$radius-avatar_default3px默认尺寸头像的圆角
$radius-avatar_medium3px中尺寸头像的圆角
$radius-avatar_large6px大尺寸头像的圆角
$radius-avatar_extra_large12px超大尺寸头像的圆角