新闻详情

新闻详情

首页 / 资讯中心 / 详情

Yeti 卡片组件(Card)完全指南:从纯 CSS 表面到自适应缩略图行

发布时间:2026/9/19 2:22:29来源:尧图网络
Yeti 卡片组件(Card)完全指南:从纯 CSS 表面到自适应缩略图行
Yeti 卡片组件Card完全指南从纯 CSS 表面到自适应缩略图行【免费下载链接】yetiA CSS-first, native, zero-build layout and styling framework for web designers.项目地址: https://gitcode.com/gh_mirrors/fo/yetiCard 是 Yeti 框架中用来承载单一事物的带边框表面可选的通边配图figure、正文主体与贴底的页脚footer当卡片内容宽度窄于 22rem 时自动切换为左缩略图 右正文的双列行形态。本文以 docs/card.md 为主线结合 card.css 源码与 card.spec.js 测试用例完整讲解卡片的结构、属性、Token 体系与无障碍实践读完即可在列表、产品展示、价格方案等场景中直接落地使用。卡片是什么一个盒子只装一件事Yeti 把 Card 定义为 A bordered surface for one thing为单一事物准备的带边框表面一篇列表文章、一个商品、一个人物、一个方案都可以放进一张卡里。它由三部分构成可选的配图figure通边到卡片边缘按比例裁切正文主体标题、段落等任意内容可选的页脚footer贴底排列的操作区。看官方 example.html 中最基础的用法article classcard img srctrail.jpg altA mountain trail at dawn h3a href/hills>.card { position: relative; display: flex; flex-direction: column; gap: var(--yeti-card-gap); padding: var(--yeti-card-padding); background-color: var(--yeti-card-surface); color: var(--yeti-color-text); border: var(--yeti-border-width) solid var(--yeti-card-border); border-radius: var(--yeti-card-radius); container-type: inline-size; overflow: clip; }四个关键设计点flex 纵向排列 gap 控制节奏卡片内部所有部分配图、正文、页脚由gap: var(--yeti-card-gap)统一控制间距。同时.card * { margin-block: 0; }card.css清除了子元素的纵向外边距避免正文自身的 prose 边距破坏卡片节奏——测试 card.spec.js 验证了图片底边到标题顶边的距离恰好等于--yeti-card-gap通边配图放在第一位且是img、video、picture或figure的元素通过负 margin 反向穿透内边距让配图铺满到卡片边框.card :is(img, video, picture, figure):first-child { inline-size: calc(100% 2 * var(--yeti-card-padding)); margin: calc(-1 * var(--yeti-card-padding)) calc(-1 * var(--yeti-card-padding)) 0; max-inline-size: none; aspect-ratio: var(--_yeti-aspect); object-fit: cover; }源码注释说明了一个细节这里显式指定inline-size而不是依赖 flex item 默认的交叉轴拉伸因为stretch 计算出的宽度 可替换元素上的 aspect-ratio组合在 WebKit 中会导致高度计算错误card.css页脚贴底.card footer使用margin-block-start: autocard.css把页脚推到卡片底部这样一排高度不一的卡片其操作按钮仍然底边对齐——测试 card.spec.js 用一短一长两张卡验证了两者页脚底边对齐容器尺寸查询container-type: inline-size使卡片成为自己的查询容器缩略图行模式正是基于它实现的见下文。配图的裁切比例由data-ratio决定未指定时默认16/9由内部变量承接.card:not([data-ratio]) { --_yeti-aspect: 16 / 9; }card.css。figure 的两种形态普通图注与叠加式 captionfigure元素本身是一个图片 figcaption的组合。源码对两种形态做了区分card.css普通 figure显示为纵向 flex 列图片按比例裁切figcaption以--yeti-text-sm字号、--yeti-color-text-muted颜色排在图注下方.layer形态的 figure保留 layer 布局自身的层叠行为caption 覆盖在图片之上并带一层用color-mix(in oklch, var(--yeti-color-surface) 85%, transparent)调出的 scrim暗色遮罩保证可读性。测试 card.spec.js 验证了 layer 形态下 caption 底部与图片底部重合、且背景色非透明。配图始终是可选的——data-variantwarning那张无图卡片同样是合法用法manifest.json的 children 约束写得很清楚 *至少 1 个figure和footer都是 0 到 1 个。属性总览data-ratio />.card[data-raised] { border-color: transparent; box-shadow: var(--yeti-shadow-sm); }card.css边框颜色透明化改用--yeti-shadow-sm阴影。测试用box-shadow非none且border-top-color为透明来断言该行为card.spec.js。data-variant着色边框 顶部色条.card[data-variant] { border-color: var(--_yeti-variant); border-block-start-width: calc(var(--yeti-border-width) * 4); }card.css边框颜色取--_yeti-variant变量且顶边宽度放大为常规边框宽度的 4 倍形成一条醒目的色条。注意正文和背景不受影响——着色只发生在边框层。测试断言了border-top-width等于 4 倍--yeti-border-width、而border-left-width仍为 1 倍。子元素契约Childrenmanifest.json 定义了 Card 的子元素结构这也是组件可验证的约束子元素数量说明 *至少 1有配图则配图在前然后是正文最后是可选的页脚 figure0 ~ 1容纳媒体与图注的 figure 元素只有其中的媒体被裁切caption 不参与裁切 footer0 ~ 1操作区被推到底部在 ranked grid 中占据最后一行[data-stretch]0 ~ 1一个被拉伸覆盖整张卡片的链接使整卡可点击而链接保留自己的可访问名称响应式魔法窄于 22rem 自动变成缩略图行这是 Card 最值得展开的实现细节。当卡片自身内容宽度小于 22rem 时带配图的卡片会从纵向排列切换为左缩略图 右正文的双列行。源码实现card.csscontainer (inline-size 22rem) { .card:not(.grid[data-ranks] .card) :is(img, video, picture, figure):first-child { position: absolute; inset-block-start: 0; inset-inline-start: 0; inline-size: 40%; block-size: 100%; margin: 0; aspect-ratio: auto; } /* ... */ .card:not(.grid[data-ranks] .card) :is(img, video, picture, figure):first-child ~ * { margin-inline-start: calc(40% - 0.2 * var(--yeti-card-padding) var(--yeti-card-gap)); } }三处值得注意的工程细节容器查询不能改容器自身container query 只能重排容器后代不能重排容器本身。因此卡片始终保持 flex column靠把配图position: absolute拉出文档流、正文用margin-inline-start缩进让位来实现看起来是双列的效果阈值是字面量源码注释card.css明确说明容器条件无法读取自定义属性所以 22rem 是写死的字面值——它大致相当于 sm 断点24rem见 space.css减去两侧 padding 后的内容宽度缩进的换算缩略图宽度是 padding box 的 40%而兄弟元素的margin-inline-start百分比是按较窄的 content box 解析的因此缩进被改写成 content box 口径40% - 0.2 × padding gapcard.css 有完整的推导注释。测试 card.spec.js 验证了缩略图宽约 40%、高充满卡片、正文左边界与图片右边界之间恰好是--yeti-card-gap带data-variant的卡片在缩略图模式下色条仍保留在缩略图上方variantImg.top与卡片顶边相差 4 倍边框宽度。与 grid 组合普通网格与 ranked 网格原文档强调了两类组合放进普通 gridul classgrid>.grid[data-ranks] .card { display: grid; grid-template-rows: subgrid; grid-row: span var(--_yeti-ranks); row-gap: var(--yeti-card-gap); container-type: normal; } .grid[data-ranks] .card footer { margin-block-start: 0; grid-row: -2; }三件事同时发生卡片各部分与邻居卡片逐行对齐图片对图片、正文对正文页脚显式放入最后一行grid-row: -2即使某张卡内容更少页脚依然对齐container-type: normal关闭了查询容器能力——因为 subgrid 化的轴与祖先共享轨道尺寸而 containment 会禁止这一点且缩略图查询本来也不会命中 ranked 卡片查询选择器用:not(.grid[data-ranks] .card)显式排除。测试 card.spec.js 验证ranked 行中所有页脚底边像素级对齐Set去重后只有 1 个值且卡片保持宽配图形态而非缩略图。无障碍实践整卡可点但绝不包链接原文档的无障碍规则非常明确而且被data-stretch的实现直接支撑Do not wrap a card in a link. Put the link on the heading and adddata-stretch: the link grows to cover the card, so the whole card is clickable, while its accessible name stays the heading text.为什么不能把整张卡包进a那样卡片内所有文本都会变成链接的可访问名称读屏器会念出一长串冗余内容。正确的做法是把链接放在标题上加data-stretchdata-stretch的实现是给链接生成一个绝对定位的::after伪元素覆盖整卡card.css.card { position: relative }提供了定位上下文.card [data-stretch]::after { content: ; position: absolute; inset: 0; }于是整卡可点而链接的可访问名称仍是标题文本。测试 card.spec.js 模拟点击卡片右下角断言跳转到了标题链接的#hills若页脚重复了同样的链接做成按钮给它tabindex-1键盘用户就不会在同一张卡上遇到两次相同的 Tab 焦点。语义标签的选择独立成卡的用article列表中的卡用li列表会被播报为含 N 项。测试还通过了 axe 无障碍扫描card.spec.js并在明暗两种配色方案下逐元素断言文本对比度达到 WCAG AAexpectAA。Token 体系一处改处处变Card 的全部外观都由公共 Token 驱动默认值定义在 components.css每个都回退到全局 TokenToken默认值说明--yeti-card-radiusvar(--yeti-radius-md)圆角--yeti-card-paddingvar(--yeti-space-md)卡内边距配图从它上面穿透过去--yeti-card-gapvar(--yeti-space-sm)卡片各部分之间的间距--yeti-card-bordervar(--yeti-color-border)边框颜色--yeti-card-surfacevar(--yeti-color-surface-raised)背景色--yeti-shadow-sm0 1px 2px var(--yeti-shadow-color)悬浮raised时的阴影其中--yeti-card-surface默认取抬升表面色color.css--yeti-shadow-sm定义在 surface.css。间距 Token 由比例尺度推导space.css因此卡片的留白天然与字号比例联动。主题定制组件级 Token 的默认值就是给主题覆盖用的——components.css 的注释写明a theme that wants pill buttons or square cards sets one line here即想要方角卡片只需覆写--yeti-card-radius一行。换肤机制详见 theming 指南 与 tokens 文档。另外还有两个内部 Token带单下划线前缀可能在 minor 版本间变动不建议外部依赖--_yeti-aspect当前长宽比和--_yeti-variant当前变体色已在 manifest.json 中标注为非公开。浏览器支持与零 JavaScript按 manifest.json 的声明无降级直接使用容器尺寸查询container size queries、aspect-ratio、overflow: clipsupports保护无没有任何能力需要特性检测兜底JavaScript无。该组件纯 CSS 实现js: null。这意味着 Card 的三个核心机制——flex 列布局、aspect-ratio 裁切、container query 缩略图切换——全部依赖现代浏览器的原生 CSS 能力无需任何脚本参与。组件自7.0.0起可用manifest.json。延伸阅读与源码入口组件文档与清单docs.md、manifest.json、example.html核心实现card.css全部样式仅此一个文件测试与夹具card.spec.js、card.html关联布局grid 文档、grid.css普通网格与data-ranksranked 网格依赖体系components.css、surface.css、space.css、theming 指南综上Yeti 的 Card 是一个声明式 容器自适应的纯 CSS 组件三个属性覆盖边框、悬浮、变体三种视觉形态22rem 容器查询让同一段标记在宽列、窄列、ranked 网格中各自呈现正确布局而data-stretch与tabindex-1的组合给出了整卡可点又不牺牲可访问性的标准答案。在你的下一个列表页或价格表中直接抄起本文的标记即可。【免费下载链接】yetiA CSS-first, native, zero-build layout and styling framework for web designers.项目地址: https://gitcode.com/gh_mirrors/fo/yeti创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

同一把 TaoToken Key,从 DeepSeek 切到豆包AI梳理文献综述 2026/9/19 3:13:37

同一把 TaoToken Key,从 DeepSeek 切到豆包AI梳理文献综述

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
齿轮-轴-轴承系统含间隙非线性动力学的Matlab仿真指南 2026/9/19 3:13:37

齿轮-轴-轴承系统含间隙非线性动力学的Matlab仿真指南

去年做齿轮箱早期故障诊断时,甲方那边反馈最典型的一个现象是:设备在某一转速区间内振动异常刺耳,换挡或加减速时变速箱体有“咔哒”异响,停机拆检却发现齿轮没有明显点蚀或断齿,轴承也无明显磨损痕迹。这个问题让不少…

阅读更多 →
机器学习驱动招投标风险防控:四大智能化场景实践 2026/9/19 3:13:37

机器学习驱动招投标风险防控:四大智能化场景实践

简介:一份聚焦机器学习在招投标活动风险防控中应用的研究型文献,面向电网采购管理、招标管理及风险管理从业者,也适合作为相关课题的参考文献和专业指导资料。该PDF文档以电网公司采购流程为背景,系统探讨了如何利用人工智能与机器…

阅读更多 →
ninja -t compdb 导出 UTF-16 LE 乱码?用 TaoToken 接的 Codex 对照 out-file 编码 2026/9/19 3:13:37

ninja -t compdb 导出 UTF-16 LE 乱码?用 TaoToken 接的 Codex 对照 out-file 编码

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
DeepSeek-V4 跑 1M 上下文 Agent 任务:Key 用 TaoToken 2026/9/19 3:13:37

DeepSeek-V4 跑 1M 上下文 Agent 任务:Key 用 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
开发测试环境选型:大厂云还是低成本方案?芯飞云实践复盘 2026/9/19 3:10:36

开发测试环境选型:大厂云还是低成本方案?芯飞云实践复盘

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞