拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Yeti Scroller 布局:用不换行的横向滚动轨道组织照片条、卡片组与步骤胶片

Yeti Scroller 布局用不换行的横向滚动轨道组织照片条、卡片组与步骤胶片【免费下载链接】yetiA CSS-first, native, zero-build layout and styling framework for web designers.项目地址: https://gitcode.com/gh_mirrors/fo/yeti导读Scroller 是 Yeti 中专门负责横向滚动单行的布局当一组同质内容必须保持在同一行、不能换行时它让容器自身横向滚动而不是挤压或折断子项。本文从 src/layouts/scroller/docs.md 出发结合 scroller.css、manifest.json 与浏览器测试完整讲解它的适用场景、实现原理、data-snap/data-width/data-gap三个数据属性、无障碍要求tabindex 可访问名称并给出可直接复制的示例与测试验证。读完你可以独立在 Yeti 项目中落地一个可键盘访问、可吸附对齐的横向滚动条。何时使用 Scroller一行必须是一行的内容Scroller 解决的是一类特定的布局需求一行内容应该始终是一行。典型场景包括一溜照片photo strip一组相关的卡片related cards一组步骤的胶片条filmstrip of steps横向溢出的大元素例如一张宽表格或一张超宽图片。关键判断标准是与 cluster 的对比cluster 是可换行的 flex 行空间不足时子项会折行而 scroller 恰恰相反——空间不足时子项保持原宽容器开启横向滚动让访客沿着这一行移动查看。因此凡是内容多到塞不下也不许换行的横向条带就是 scroller 的领地。从 docs/guides/layouts.md 的 Foundation 6 对照表还能看到它的历史定位Foundation 6 时代的 Orbit 轮播组件在 Yeti 中就由scroller承担——一个不依赖 JavaScript 的原生横向滚动布局。工作原理不换行的 flex 行 overflow-xScroller 的全部实现只有一份零依赖的 CSS位于 src/layouts/scroller/scroller.csslayer yeti.layouts { .scroller { display: flex; gap: var(--_yeti-gap); overflow-x: auto; overscroll-behavior-x: contain; } .scroller:not([data-gap]) { --_yeti-gap: var(--yeti-space-md); } .scroller * { margin: 0; flex: 0 0 auto; } .scroller[data-width] * { inline-size: var(--_yeti-width); } .scroller[data-snap] { scroll-snap-type: x mandatory; } .scroller[data-snap] * { scroll-snap-align: start; } }逐行拆解其机制display: flex 不换行flex 容器默认不换行这是保持一行的基础。子项flex: 0 0 auto这是核心——子项既不收缩也不伸展保留自然宽度。当整行宽度超过容器时行溢出容器因此可以滚动。这正是文档中Children are told not to shrink, so the row overflows and the container scrolls的源码对应。overflow-x: auto只在横向溢出时出现滚动条纵向不干预。overscroll-behavior-x: contain当滚动到轨道尽头时把滚动关在轨道内部避免连锁滚动触发外层页面或相邻滚动区的滚动这是横向嵌套滚动场景中容易被忽略的细节。子项margin: 0间距完全交给gap决定子项不携带任何外边距——这符合 Yeti 的总体原则间距由持有子项的布局负责测试中也有expectNoChildMargins专门校验这一点。浏览器测试 test/browser/layouts/scroller.spec.js 精确验证了这套机制在 400px 视口下断言scrollWidth clientWidth即确实溢出并可滚动同时断言相邻子项top对齐、水平间距等于--yeti-space-md。支持性方面manifest.json 的support字段标注了三个无降级风险的依赖flexbox gap、scroll snap、overscroll-behavior并且js: null——整个布局不需要任何脚本。三个数据属性data-gap />[data-gapxs] { --_yeti-gap: var(--yeti-space-xs); } [data-gaplg] { --_yeti-gap: var(--yeti-space-lg); }值得注意的两点默认值用:not([data-gap])选择器提供.scroller:not([data-gap]) { --_yeti-gap: var(--yeti-space-md); }。这是 Yeti 的既定惯例只有属性缺席时布局才提供默认因此嵌套布局永远不会继承父级的间距值。支持流体间距对data-gapsm-lg不会在sm与lg之间跳变而是从窄视口下的sm端点平滑流动到宽视口下的lg端点与字体尺度本身的流式逻辑一致见 src/tokens/scale.css 的插值机制。data-snap滚动吸附data-snap开启两条规则.scroller[data-snap] { scroll-snap-type: x mandatory; } .scroller[data-snap] * { scroll-snap-align: start; }scroll-snap-type: x mandatory让横向滚动强制吸附scroll-snap-align: start让每个子项的起始边缘成为吸附点滚动停下时子项会干净地对齐到轨道起始边不会卡在两张卡片中间。对应测试断言未加data-snap的轨道scroll-snap-type为none加了之后以x开头scroll-snap-type: x mandatory。data-width等宽子项data-width让轨道从自然宽度各异变为每格等宽的胶片感序列.scroller[data-width] * { inline-size: var(--_yeti-width); }取值同样是令牌后缀data-widthxs读取--yeti-width-xs16remsm为 24rem、md为 32rem、lg为 48rem、xl为 64rem、2xl为 80rem见 space.css 的宽度令牌定义。测试对此的断言是加了data-widthxs后子项宽度精确等于--yeti-width-xs的令牌值。直接可用的最小示例来自组件自带示例 src/layouts/scroller/example.htmldiv classscroller>div classscroller contenteditable="false">【免费下载链接】yetiA CSS-first, native, zero-build layout and styling framework for web designers.项目地址: https://gitcode.com/gh_mirrors/fo/yeti创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门