卡片
本页内容
卡片把相关内容归拢到自己的一块面上。它的各部分——cardHeader()、cardMedia()、cardBody()、cardFooter()——是各自独立的函数而不是属性,所以你只用得着的那几个,并按设计想要的顺序摆放。
基础卡片
基于文件的路由
src/about.ht.js → /about
目录变成路径,方括号变成参数。没有路由器要配置。
card(
cardHeader({ title: '基于文件的路由', subtitle: 'src/about.ht.js → /about' }),
cardBody(text({ variant: 'small', tone: 'muted' }, '目录变成路径,方括号变成参数。没有路由器要配置。')),
)变体
outlined 是默认值。elevated 用阴影换掉边框,flat 则两者都不要,改为给面上色。
Outlined
Elevated
Flat
grid({ min: '13rem' },
card({ variant: 'outlined' }, cardBody(text({ variant: 'small' }, 'Outlined'))),
card({ variant: 'elevated' }, cardBody(text({ variant: 'small' }, 'Elevated'))),
card({ variant: 'flat' }, cardBody(text({ variant: 'small' }, 'Flat'))),
)带页脚
divided 会在页脚上方加一条细线。页脚会被推到底部,所以并排的卡片即使上方文字长短不一,操作也能对齐。
基础站点
一个最小项目,外加部署配置。
Markdown 博客
一个装着 .md 文件的目录,渲染成静态页面,带 RSS 订阅,完全没有客户端 JavaScript。
grid({ min: '14rem' },
card(
cardHeader({ title: '基础站点' }),
cardBody(text({ variant: 'small', tone: 'muted' }, '一个最小项目,外加部署配置。')),
cardFooter({ divided: true }, button({ size: 'sm', variant: 'soft' }, '打开')),
),
card(
cardHeader({ title: 'Markdown 博客' }),
cardBody(text({ variant: 'small', tone: 'muted' }, '一个装着 .md 文件的目录,渲染成静态页面,带 RSS 订阅,完全没有客户端 JavaScript。')),
cardFooter({ divided: true }, button({ size: 'sm', variant: 'soft' }, '打开')),
),
)媒体
cardMedia() 以固定宽高比填满卡片顶部,所以不管源图多大,一排卡片都能保持整齐。
默认 16 / 9
ratio: 4 / 3
grid({ min: '13rem' },
card(
cardMedia({ src: '/logo.svg', alt: '', style: 'background: var(--su-surface-2); object-fit: contain; padding: 1rem' }),
cardBody(text({ variant: 'small' }, '默认 16 / 9')),
),
card(
cardMedia({ src: '/logo.svg', alt: '', ratio: '4 / 3', style: 'background: var(--su-surface-2); object-fit: contain; padding: 1rem' }),
cardBody(text({ variant: 'small' }, 'ratio: 4 / 3')),
),
)整张卡片作为链接
给卡片一个 href,整块面就成了一个链接,并附带悬停上浮效果。这种形态下别在卡片里再放按钮或其他链接——可交互内容不能嵌在链接里面。改用普通卡片加一个页脚按钮。
grid({ min: '14rem' },
card({ href: '/zh/docs/routing' },
cardHeader({ title: '路由', subtitle: '阅读指南' }),
cardBody(text({ variant: 'small', tone: 'muted' }, '动态路由、通配路由和路由分组。')),
),
card({ href: '/zh/docs/data' },
cardHeader({ title: '数据加载', subtitle: '阅读指南' }),
cardBody(text({ variant: 'small', tone: 'muted' }, 'data() 在构建时运行,并带 fetch 缓存。')),
),
)内边距
一个属性就能一次设定卡片所有部分的内边距。
padding: sm
padding: xl
stack({ gap: 'md' },
card({ padding: 'sm' }, cardBody(text({ variant: 'small' }, 'padding: sm'))),
card({ padding: 'xl' }, cardBody(text({ variant: 'small' }, 'padding: xl'))),
)自由内容
这些部件是方便,而不是硬性要求——卡片接受任意子元素,cardHeader() 也能在标题旁接受自己的子元素,比如右侧放一个头像或菜单按钮。
Paul Browne
4 分钟前部署
构建通过12 个页面4.1 kB
card(
cardHeader(
{ title: 'Paul Browne', subtitle: '4 分钟前部署' },
avatar({ name: 'Paul Browne', size: 'sm' }),
),
cardBody(
stack({ direction: 'row', gap: 'sm', wrap: true },
chip({ color: 'success', dot: true }, '构建通过'),
chip({ color: 'neutral' }, '12 个页面'),
chip({ color: 'neutral' }, '4.1 kB'),
),
),
)属性
card():
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
variant | 'outlined' | 'elevated' | 'flat' | 'outlined' | 这块面如何与页面区分开。 |
href | string | — | 把整张卡片渲染成链接。 |
padding | Space | 'lg' | 卡片各部分统一使用的内边距。 |
各部件:
| 部件 | 属性 | 默认值 | 说明 |
|---|---|---|---|
cardHeader | title, subtitle | — | 标题和副标题,以及并排放置的任意子元素。 |
cardTitle | as | 'h3' | 单独的标题,用于手写头部时。 |
cardSubtitle | — | 标题下方那行弱化文字。 | |
cardMedia | src, alt, ratio | '16 / 9' | 固定宽高比的封面图。 |
cardBody | — | 主内容区域。 | |
cardFooter | divided | false | 底部的操作行;divided 会在其上方加细线。 |