容器
Card - 卡片
一块有边界的表面,下面没有阴影。
用法
什么时候用它
import { Card } from '@misoto22/folio'说明
一块有边界的表面。
按法则,没有阴影:这套系统里的深度是一条细线和一次底色变化,绝不是模糊。一张需要读作“浮起来”的卡片应该用 plate,它靠反转来区分。
它会按自己的圆角裁剪。一张只圆角、不裁剪的卡片,会让一张通栏图片的直角压在自己的圆角上,四个角都是;第一个子元素带底色时同理——这个缺陷要等到第一张顶部放图的卡片出现才看得见。少数刻意让内容探出去的卡片,传 overflow-visible。
用带名字的子部件来组合;当一张卡片没有像样的头部和尾部时,直接把内容丢进去也行。
结构
| 部件 | 说明 |
|---|---|
| 盒子必填 | 一个 <div>,--radius-lg 的圆角,三种底选一种:outline 是页面底色上的一条细线,也是默认;plate 是唯一那块反色的特写面;flat 完全没有边框,给那种网格本身已经在单元格之间画好线的卡片。它不带任何内边距,并且会按自己的圆角裁剪。 |
| 头部 | CardHeader——细线之上的一行两端对齐,px-5 py-4:标题贴行首,一个标记或一个动作贴行尾。 |
| 标题 | CardTitle,用编辑用的衬线体、--fs-item 字号。除非 as 另有说法,否则是 <h3>;它读的是 --card-title 而不是直接读 --ink,正是这一点让它在 plate 把这个变量改指到别处时仍然看得清。 |
| 正文 | CardBody——放内容的那口井,p-5、--ink-2、放松的行高。 |
| 页脚 | CardFooter——细线之下安静的一条,等宽的元信息、--ink-3-aa,放元数据或者一个次要动作。 |
实践建议
推荐
- CardTitle 上要传 as:h3 只有在一个自带 h2 的 section 里才对,别处几乎都不对,否则十二张卡片的网格就是十二个 h3,上面没有任何标题可以归属。
- plate 里要用 CardTitle,不要自己写标题——plate 把 --card-title 改指到 --on-feature,而一个直接读 --ink 的标题在那块底上算出来是 1.25:1:看不见,而且偏偏只在那个以“长得不一样”为职责的变体上看不见。
- 不用那些子部件时,内边距要自己加:盒子自己一点都没有,所以直接扔进去的子元素会贴着边框。
- 刻意要探出边界的卡片要传 overflow-visible——一个钉在边上的标记、一个压过描边的控件。盒子默认就裁剪,因为一张磨了圆角却不裁剪的卡片,会让出血图把自己的直角盖在卡片的圆角上。
避免
- 带 onClick 的 Card 就是一个带 onClick 的 div——不可聚焦、不会被播报、键盘够不到。把一个真正的控件放进去、让它铺满,这样被播报的是一个按钮,而整张卡片仍然是那个可点区域。
- 一屏上 plate 不要花第二次:它是系统唯一那块反色的表面,而一整条都是 plate 的区块,已经没有底色可供它反过来。
示例
variants
有边界的那种表面,和唯一那种反色的,并排放着。两者底下都没有阴影:一张需要读起来是「浮起来」的卡片就是 plate,而它靠反色来分离,因为这套系统没有一档可以把它抬起来的高度阶梯。plate 一屏花一次——一整排 plate,就是一整排没有底可供反色的东西。里面也要用 CardTitle,别用你自己的标题:plate 会把 --card-title 重新指向 --on-feature,而一个直接读 --ink 的标题,在那块底上对比度是 1.25:1,在这个唯一以「看起来不一样」为全部职责的变体上,它是隐形的。
Recent deploys
greenThe reversed plate
a real control
一整张卡片当作一个目标使用,而盒子上没有 onClick。一个挂了点击处理器的 Card 就是一个挂了点击处理器的 div:不可聚焦、不会被播报、键盘够不着。补救办法是在它里面放一个真的控件,用一层绝对定位的覆盖层铺满整个盒子——于是被播报出来的是一条以标题为名字的链接,焦点环有东西可落,而整张卡片仍然是命中区域。要让这个成立,盒子需要 position: relative,而任何读者还必须能单独点到的东西,都得坐在覆盖层之上。
api.misoto22.com
liveDeployed from main four minutes ago, in 2m 14s.
a ruled grid
flat 是给那种「容器已经在单元格之间画好了线」的卡片用的底——三张 outlined 卡片放进一个带边框的网格里,是本来只要一圈边框、结果画了三圈。这里还有两件事是承重的。这个盒子自己不带内边距,所以直接丢进去的子元素会贴着边:CardBody 才是提供它的那个。另外 CardTitle 默认是 h3,紧跟在上面那个 h2 下面时这是对的,而一旦一个十二张卡片的网格上面没有任何标题可供它们归属,它就错了——用 as 说明这里真正的层级是哪一级。
Revenue by region
Australia
1,204 orders
$48,210
Japan
862 orders
$31,940
Singapore
415 orders
$18,704
组成部分
在调用处组合,而不是通过 props 配置——所以这个组件没有预料到的布局,依然表达得出来。
CardHeader
头部一行——标题在左,动作或标记在右。
这个组件没有自己的属性。
CardTitle
卡片的标题,用书刊衬线体。
默认是 <h3>,这在一个自带 <h2> 的区块里是对的,在几乎其他任何地方都是错的——请传 as,而不是留下一个标题层级会跳级的页面。
这个组件没有自己的属性。
CardBody
内容区。
这个组件没有自己的属性。
CardFooter
一条安静的条带,放元数据或次要动作。
这个组件没有自己的属性。