展示类

卡片

常规的卡片容器,可以承载标题、段落、图片、列表等内容。

代码演示

如何引入

<script setup lang="ts">
    import { Card, CardGroup, CardMeta } from '@fibrous/semi-ui-vue';
</script>

CardMeta 即 Card.Meta,两种写法等价。

基础卡片

基础卡片包含标题、内容等部分。

Semi Design
Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
代码
<script setup lang="ts">
    import { Card, TypographyText } from '@fibrous/semi-ui-vue';
</script>

<template>
    <Card :style="{ maxWidth: '360px' }" title="Semi Design">
        <template #headerExtraContent>
            <TypographyText link>更多</TypographyText>
        </template>
        Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
    </Card>
</template>

简洁卡片

卡片可以只设置内容区域。

Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。

Card meta img
Semi Doc
代码
<script setup lang="ts">
    import { IconInfoCircle } from '@fibrous/semi-icons-vue';
    import { Avatar, Card, CardMeta, Popover } from '@fibrous/semi-ui-vue';

    const bodyStyle = { display: 'flex', alignItems: 'center', justifyContent: 'space-between' };
</script>

<template>
    <Card :style="{ maxWidth: '360px' }"> Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。 </Card>
    <br />
    <Card :bodyStyle="bodyStyle" :style="{ maxWidth: '360px' }">
        <CardMeta title="Semi Doc">
            <template #avatar>
                <Avatar alt="Card meta img" size="default" src="/assets/placeholder/logo.svg" />
            </template>
        </CardMeta>
        <Popover position="top" showArrow>
            <template #content>
                <article :style="{ padding: '6px' }">这是一个 Card</article>
            </template>
            <IconInfoCircle aria-label="信息" :style="{ color: 'var(--semi-color-primary)' }" />
        </Popover>
    </Card>
</template>

封面

可以使用 #cover 插槽设置封面。

example
卡片封面
代码
<script setup lang="ts">
    import { Card, CardMeta } from '@fibrous/semi-ui-vue';
</script>

<template>
    <Card :style="{ maxWidth: '300px' }">
        <template #cover>
            <img alt="example" src="/assets/root-web-sites/card-cover-docs-demo2.jpeg" />
        </template>
        <CardMeta title="卡片封面" />
    </Card>
</template>

边线和外边框

可以使用 bordered 设置卡片是否有外边框,默认为 true 。同时,也可以使用 headerLine 设置内容区和标题区是否有边线, footerLine 设置内容区和页尾区是否有边线。

Semi Design
Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
代码
<script setup lang="ts">
    import { Card } from '@fibrous/semi-ui-vue';
</script>

<template>
    <div :style="{ display: 'inline-block', padding: '20px', backgroundColor: 'var(--semi-color-fill-0)' }">
        <Card :bordered="false" headerLine :style="{ maxWidth: '360px' }" title="Semi Design"> Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。 </Card>
    </div>
</template>

阴影

可以使用 shadows 设置显示阴影的时机,可选值为: hover(hover 时显示阴影)、always(始终显示阴影),如果不设置该属性则没有阴影。

Card meta img
Semi Doc

Card meta img
Semi Doc
代码
<script setup lang="ts">
    import { IconInfoCircle } from '@fibrous/semi-icons-vue';
    import { Avatar, Card, CardMeta, Popover } from '@fibrous/semi-ui-vue';

    const bodyStyle = { display: 'flex', alignItems: 'center', justifyContent: 'space-between' };
</script>

<template>
    <div>
        <Card :bodyStyle="bodyStyle" shadows="hover" :style="{ maxWidth: '360px' }">
            <CardMeta title="Semi Doc">
                <template #avatar>
                    <Avatar alt="Card meta img" size="default" src="/assets/placeholder/logo.svg" />
                </template>
            </CardMeta>
            <Popover position="top" showArrow>
                <template #content>
                    <article :style="{ padding: '6px' }">这是一个 Card</article>
                </template>
                <IconInfoCircle aria-label="信息" :style="{ color: 'var(--semi-color-primary)' }" />
            </Popover>
        </Card>
        <br />
        <Card :bodyStyle="bodyStyle" shadows="always" :style="{ maxWidth: '360px' }">
            <CardMeta title="Semi Doc">
                <template #avatar>
                    <Avatar alt="Card meta img" size="default" src="/assets/placeholder/logo.svg" />
                </template>
            </CardMeta>
            <Popover position="top" showArrow>
                <template #content>
                    <article :style="{ padding: '6px' }">这是一个 Card</article>
                </template>
                <IconInfoCircle aria-label="信息" :style="{ color: 'var(--semi-color-primary)' }" />
            </Popover>
        </Card>
    </div>
</template>

更灵活的内容展示

可以利用 CardMeta 支持更灵活的内容,通过 #title(或 title 属性)、#avatar、#description 插槽设置。

Card meta img
Semi Doc
全面、易用、优质
example
Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。
代码
<script setup lang="ts">
    import { Avatar, Button, Card, CardMeta, Space, TypographyText } from '@fibrous/semi-ui-vue';
</script>

<template>
    <Card :footerStyle="{ display: 'flex', justifyContent: 'flex-end' }" footerLine :style="{ maxWidth: '340px' }">
        <template #title>
            <CardMeta title="Semi Doc">
                <template #description>全面、易用、优质</template>
                <template #avatar>
                    <Avatar alt="Card meta img" size="default" src="/assets/placeholder/logo.svg" />
                </template>
            </CardMeta>
        </template>
        <template #headerExtraContent>
            <TypographyText link>More</TypographyText>
        </template>
        <template #cover>
            <img alt="example" src="/assets/root-web-sites/card-cover-docs-demo.jpeg" />
        </template>
        <template #footer>
            <Space>
                <Button theme="borderless" type="primary">精选案例</Button>
                <Button theme="solid" type="primary">开始使用</Button>
            </Space>
        </template>
        Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。
    </Card>
</template>

内部卡片

卡片内部可以嵌套其他卡片。

Card title
Inner Card title
Inner Card content
Inner Card title
Inner Card content
代码
<script setup lang="ts">
    import { Card, TypographyText } from '@fibrous/semi-ui-vue';
</script>

<template>
    <Card title="Card title">
        <Card :style="{ marginBottom: '20px' }" title="Inner Card title">
            <template #headerExtraContent>
                <TypographyText link>More</TypographyText>
            </template>
            Inner Card content
        </Card>
        <Card title="Inner Card title">
            <template #headerExtraContent>
                <TypographyText link>More</TypographyText>
            </template>
            Inner Card content
        </Card>
    </Card>
</template>

栅格卡片

在系统概览页面常常和栅格进行配合。

Card Title
Card Content
Card Title
Card Content
Card Title
Card Content
Card Title
Card Content
Card Title
Card Content
代码
<script setup lang="ts">
    import { Card, Col, Row } from '@fibrous/semi-ui-vue';

    const rows = [
        [8, 8, 8],
        [16, 8],
    ];
</script>

<template>
    <div :style="{ backgroundColor: 'var(--semi-color-fill-0)', padding: '20px' }">
        <Row v-for="(spans, rowIndex) in rows" :key="rowIndex" :gutter="[16, 16]">
            <Col v-for="(span, colIndex) in spans" :key="colIndex" :span="span">
                <Card :bordered="false" title="Card Title">Card Content</Card>
            </Col>
        </Row>
    </div>
</template>

内置预加载

可以使用 Card 的 loading 属性来设置卡片内容区是否显示占位元素,当它为 true 时将显示占位元素,反之则不显示。




代码
<script setup lang="ts">
    import { ref } from 'vue';
    import { Card, CardMeta, Switch } from '@fibrous/semi-ui-vue';

    const loading = ref(true);
</script>

<template>
    <Switch aria-label="显示内容" @change="(v) => (loading = !v)" />
    <br />
    <br />
    <Card :loading="loading" :style="{ maxWidth: '360px' }">
        <CardMeta title="Semi Doc">
            <template #description>全面、易用、优质</template>
        </CardMeta>
    </Card>
</template>

更丰富的预加载效果

Card 自带的 loading 属性只能设置内容区的预加载效果,如果你想要设置其他部分的预加载,或者自定义更丰富的预加载效果,你可以结合 Skeleton 组件来实现。



代码
<script setup lang="ts">
    import { ref } from 'vue';
    import { Avatar, Card, CardMeta, Skeleton, SkeletonAvatar, SkeletonImage, SkeletonParagraph, SkeletonTitle, Switch, TypographyText, TypographyTitle } from '@fibrous/semi-ui-vue';

    const loading = ref(true);
</script>

<template>
    <Switch aria-label="显示内容" @change="(v) => (loading = !v)" />
    <br />
    <br />
    <Card :style="{ maxWidth: '300px' }">
        <template #title>
            <CardMeta>
                <template #title>
                    <Skeleton :loading="loading" :style="{ width: '80px' }">
                        <template #placeholder>
                            <SkeletonTitle />
                        </template>
                        <TypographyTitle :heading="5">Semi Doc</TypographyTitle>
                    </Skeleton>
                </template>
                <template #description>
                    <Skeleton :loading="loading" :style="{ width: '150px', marginTop: '12px' }">
                        <template #placeholder>
                            <SkeletonParagraph :rows="1" />
                        </template>
                        <TypographyText>全面、易用、优质</TypographyText>
                    </Skeleton>
                </template>
                <template #avatar>
                    <Skeleton :loading="loading">
                        <template #placeholder>
                            <SkeletonAvatar />
                        </template>
                        <Avatar alt="Card meta img" size="default" src="/assets/placeholder/logo.svg" />
                    </Skeleton>
                </template>
            </CardMeta>
        </template>
        <template #headerExtraContent>
            <Skeleton :loading="loading" :style="{ width: '50px' }">
                <template #placeholder>
                    <SkeletonParagraph :rows="1" />
                </template>
                <TypographyText link>More</TypographyText>
            </Skeleton>
        </template>
        <template #cover>
            <Skeleton :loading="loading" :style="{ maxWidth: '100%', height: '220px' }">
                <template #placeholder>
                    <SkeletonImage />
                </template>
                <img alt="example" src="/assets/root-web-sites/card-cover-docs-demo.jpeg" />
            </Skeleton>
        </template>
    </Card>
</template>

带页签的卡片

可以结合 Tabs 组件,实现带页签的卡片。

Card title

content1

content1

content1

代码
<script setup lang="ts">
    import { Card, TabPane, Tabs } from '@fibrous/semi-ui-vue';
</script>

<template>
    <Card title="Card title">
        <Tabs :style="{ marginTop: '-20px', marginBottom: '-20px' }" type="line">
            <TabPane itemKey="1">
                <template #tab>Tab 1</template>
                <p>content1</p>
                <p>content1</p>
                <p>content1</p>
            </TabPane>
            <TabPane itemKey="2">
                <template #tab>Tab 2</template>
                <p>content2</p>
                <p>content2</p>
                <p>content2</p>
            </TabPane>
        </Tabs>
    </Card>
</template>

卡片操作区

#actions 插槽中的每个直接子节点是一个操作,元素间将以 12px 的水平间距展示于内容区底部。

example
Semi Doc
全面、易用、优质
代码
<script setup lang="ts">
    import { Card, CardMeta, Rating } from '@fibrous/semi-ui-vue';
</script>

<template>
    <Card :headerLine="false" :style="{ maxWidth: '300px' }">
        <template #cover>
            <img alt="example" src="/assets/root-web-sites/card-cover-docs-demo.jpeg" />
        </template>
        <template #actions>
            <Rating :defaultValue="4" size="small" />
        </template>
        <CardMeta title="Semi Doc">
            <template #description>全面、易用、优质</template>
        </CardMeta>
    </Card>
</template>

卡片组

CardGroup 中的卡片将呈现为等间距排列,利用 spacing 属性可以设置卡片间距大小。

滑动调节 Card 间距
1040

Card title
Card content
Card title
Card content
Card title
Card content
Card title
Card content
Card title
Card content
Card title
Card content
Card title
Card content
Card title
Card content
代码
<script setup lang="ts">
    import { ref } from 'vue';
    import { Card, CardGroup, Slider, TypographyText } from '@fibrous/semi-ui-vue';

    const spacing = ref(12);

    const onSpacingChange = (value: number | number[]) => {
        if (typeof value === 'number') spacing.value = value;
    };
</script>

<template>
    <TypographyText id="card-group-spacing">滑动调节 Card 间距</TypographyText>
    <Slider aria-labelledby="card-group-spacing" :defaultValue="12" :max="40" :min="10" :style="{ width: '360px' }" @change="onSpacingChange" />
    <br />
    <CardGroup :spacing="spacing">
        <Card v-for="idx in 8" :key="idx" :headerLine="false" shadows="hover" :style="{ width: '260px' }" title="Card title">
            <template #headerExtraContent>
                <TypographyText link>More</TypographyText>
            </template>
            <TypographyText>Card content</TypographyText>
        </Card>
    </CardGroup>
</template>

网格型卡片组

使用 CardGroup 的 type 属性,可以将卡片组设置为网格型。

Card title
Card content
Card title
Card content
Card title
Card content
Card title
Card content
Card title
Card content
Card title
Card content
Card title
Card content
代码
<script setup lang="ts">
    import { Card, CardGroup, TypographyText } from '@fibrous/semi-ui-vue';
</script>

<template>
    <CardGroup type="grid">
        <Card v-for="idx in 7" :key="idx" :headerLine="false" shadows="hover" :style="{ width: '260px' }" title="Card title">
            <template #headerExtraContent>
                <TypographyText link>More</TypographyText>
            </template>
            <TypographyText>Card content</TypographyText>
        </Card>
    </CardGroup>
</template>

API 参考

Card

Props

属性说明类型默认值
bodyStyle内容区的内联样式。StyleValuesemiGlobalDefault("Card", "bodyStyle")
bordered是否显示卡片外边框。booleansemiDefault("Card", "bordered", true)
footerLine页脚区与内容区之间是否有边线。booleansemiDefault("Card", "footerLine", false)
footerStyle页脚区的内联样式。StyleValuesemiGlobalDefault("Card", "footerStyle")
headerLine标题区与内容区之间是否有边线。booleansemiDefault("Card", "headerLine", true)
headerStyle标题区的内联样式。StyleValuesemiGlobalDefault("Card", "headerStyle")
loading是否在内容区显示加载占位,开启时根元素的 aria-busy 为 true。booleansemiDefault("Card", "loading", false)
shadows显示阴影的时机,可选 hover 或 always;不设置则没有阴影。ShadowssemiGlobalDefault("Card", "shadows")
title标题文字,按 6 号标题的样式渲染为 div,超长时省略并显示提示;与 title 插槽等价,两者同时给出时插槽优先。stringundefined

Events

事件说明回调参数
无

Slots

插槽说明作用域参数
default卡片内容。any
title卡片标题;只有一段文字时按 title 属性的样式渲染,其他内容原样渲染。any
headerExtraContent标题右侧的额外内容。any
header自定义整个标题区,会取代 title 和 headerExtraContent。any
cover卡片封面。any
actions操作区,每个直接子节点作为一个操作,位于内容区底部,间距 12px。any
footer自定义页脚。any

Exposes

名称说明类型
无

class、style 及其他未声明的属性落在根元素上。

CardGroup

Props

属性说明类型默认值
spacing卡片间距,数值或 [水平间距, 垂直间距];type 为 grid 时不生效。number | [number, number]semiDefault("CardGroup", "spacing", 16)
type设为 grid 时呈现为网格型,覆盖 spacing。"grid"semiGlobalDefault("CardGroup", "type")
wrap是否换行,传给 Space;纵向排列时不生效。booleansemiDefault("CardGroup", "wrap", true)
align子项的交叉轴对齐方式,传给 Space,可选 start、center、end、baseline。AlignsemiGlobalDefault("CardGroup", "align")
vertical是否纵向排列,传给 Space。booleansemiDefault("CardGroup", "vertical", false)

Events

事件说明回调参数
无

Slots

插槽说明作用域参数
default要排列的卡片。any

Exposes

名称说明类型
无

未声明的属性落在内部 Space 的根元素上。

Card.Meta

Props

属性说明类型默认值
title标题文字,等价于 title 插槽,两者同时给出时插槽优先。stringundefined

Events

事件说明回调参数
无

Slots

插槽说明作用域参数
avatar头像。any
title标题。any
description描述。any

Exposes

名称说明类型
无

未声明的属性落在根元素上。

Accessibility

  • Card 支持传入 aria-label 或 aria-labelledby 来表示该 Card 作用,传入后根元素带 role="group"(传入的 role 优先)
  • Card loading 时,将开启 aria-busy
  • 字符串 title 按 h6 的样式渲染,但元素是 div,不带标题语义,不会打乱页面的标题层级;需要标题语义时,传入自己的标题元素作为 title(Vue 中写在 #title 插槽里)
  • Card 为容器型组件,卡片内部的任何元素需要遵循各自的可访问性指南

文案规范

  • 卡片标题
    • 卡片标题应具有信息描述性,聚焦最重要的信息
    • 尽量将标题限制在 1 个短语或句段中
    • 卡片标题应句子大小写书写
    • 不要以标点符号结尾(除了问号)
  • 正文
    • 可操作的:使用祈使句而不是“你可以”来描述正文,可以更好的告诉用户可以做什么
✅ 推荐用法❌ 不推荐用法
Get order progress for detailsYou can get order progress for details
  • 总是优先说最重要的信息
  • 使用 “Need to”而不是”must“

设计变量

下表是组件内部的 Sass 变量,不能覆写。定制样式请覆写 --semi-* CSS 变量(见 Design Token 页),或写不分层的 CSS 规则。
Sass 变量值用法
$color-card-bg-defaultvar(--semi-color-bg-0)卡片背景颜色
$color-card-bordervar(--semi-color-border)卡片描边颜色
$color-card_title-textvar(--semi-color-text-0)卡片标题文字颜色
$color-card_description-textvar(--semi-color-text-2)卡片描述文字颜色
$color-card_extra-textvar(--semi-color-text-0)卡片附加文字颜色
$color-card_body-textvar(--semi-color-text-1)卡片正文文字颜色
$font-card_default-fontWeight$font-weight-regular卡片文字字重 - 默认
$font-card_extra-fontWeight700卡片文字字重 - 附加文字
$font-card_title-fontWeight700卡片文字字重 - 标题
$font-card_default-lineHeight20px卡片文字行高 - 默认
$font-card_title-lineHeight22px卡片文字行高 - 标题
$font-card_default-fontSize$font-size-regular卡片文字大小 - 默认
$font-card_extra-fontSize$font-size-header-6卡片文字大小 - 附加文字
$font-card_title-fontSize$font-size-header-6卡片文字大小 - 标题
$radius-cardvar(--semi-border-radius-medium)卡片圆角
$motion-card-transition_duration300ms卡片悬浮动画时长
$width-card-border$border-thickness-control卡片描边宽度
$shadow-cardvar(--semi-shadow-elevated)卡片阴影
$spacing-card-padding$spacing-base-loose卡片内边距
$spacing-card-margin$spacing-base-loose卡片外边距
$spacing-card_avatar-marginRight$spacing-base-tight卡片头像右侧外边距
$spacing-cardGroup_card-margin-1px卡片组外边距
$z-card_hover1悬浮后卡片 zindex