Sticky Bar:吸顶、吸底与悬浮固定元素
Sticky Bar 是随滚动保持可达的固定元素:吸顶的站点头部、吸底的加购栏、悬浮在角落的聊天入口、回到顶部按钮。它让少量关键控件不因滚动而丢失,代价是永久占用一部分视口,并可能盖住正在阅读或正在聚焦的内容。它与 Banner 的差别是:Banner 关心“说什么”(一条短消息),Sticky Bar 关心“怎样保持可达”;两者可叠加,但固定的 Banner 同时承担两类风险。
适合与不适合
适合每次滚动都可能需要的少量控件:导航与搜索入口、当前商品的价格与加购按钮、联系客服入口、长页面的回到顶部。不适合一次性的推广消息、需要长时间阅读的内容、多控件面板,也不适合在小屏同时固定多条:固定得越多,可读区域越小。
与相邻模式的区别
| 相邻模式 | 判据 | 说明 |
|---|---|---|
| Banner | 消息还是位置策略 | Banner 是短消息容器,可以不固定;Sticky Bar 是位置策略,内容可以是导航、加购或聊天入口 |
| Modal / Drawer | 是否随需出现 | Sticky Bar 不阻断背景,始终存在;Modal 与 Drawer 由动作打开并可关闭 |
| Overlay | 叠放对象 | Overlay 把文字叠在媒体上;Sticky Bar 叠在整个滚动页面之上 |
| Toast | 是否消失 | Toast 是瞬时反馈;Sticky Bar 常驻,两者位置不能互相遮挡 |
优点与缺点
| 优点 | 缺点 |
|---|---|
| 关键操作始终可达,减少回滚 | 永久占用视口,小屏尤其明显 |
| 加购栏缩短从阅读到购买的路径 | 可能遮挡内容与获得焦点的元素 |
| 聊天入口随时可用 | 与软键盘、浏览器工具栏、安全区冲突 |
内容与交互要求
每个固定元素只留一个主行动与最少的辅助信息。吸底加购栏的价格、变体与库存状态必须与主购买区一致,不能各自维护;变体未选择、缺货或价格随地区变化时,固定栏显示同样的状态,不自行猜测(Horizon 商品页解读了吸底购买条与主购买区各自拥有标记)。回到顶部按钮滚动到一定位置后再出现,用真实链接或按钮,落点为页面顶部。
响应式与无障碍
先分清定位方式。MDN:position: sticky 的元素仍在文档流中,先按流布局,再相对最近的滚动祖先与其包含块按 top、right、bottom、left 偏移,偏移不影响其他元素;至少要设置一个非 auto 的 inset 值,且只在其包含块的相反边缘之前保持“粘住”。position: fixed 的元素脱离文档流,不为它保留布局空间,相对初始包含块(视觉媒体中是视口)定位;祖先设置了非 none 的 transform、perspective 或 filter 时定位基准会变。所以 sticky 头部保留自己的高度,fixed 元素则需要为页面预留内边距,否则盖住内容。
遮挡焦点:WCAG 2.2 的 2.4.11 Focus Not Obscured (Minimum)(AA)要求,界面组件获得键盘焦点时不得因作者创建的内容而被完全遮挡;该页明确把粘性页脚、粘性页头和非模态对话框列为可能的遮挡来源,允许部分遮挡。用户主动打开的内容遮住焦点项时,若能用键盘(如 Escape 或滚动)无需先关闭该内容即可露出焦点项,也算满足。该页推荐的技术是 CSS scroll-padding,使焦点滚动与锚点跳转不落在固定元素之下,MDN 的 scroll-padding 页以固定页头为例。发布时用 Tab 走遍页面,并在吸顶与吸底同时存在时检查。
软键盘与安全区:viewport meta 的 interactive-widget 决定虚拟键盘的影响,resizes-visual(默认)只缩小视觉视口,resizes-content 缩小布局视口,overlays-content 都不缩小;吸底元素在键盘弹出时被推起、盖住还是压缩,取决于该设置与实现,必须在真机上测输入框获得焦点的情形。MDN 指出使用 viewport-fit=cover 时强烈建议配合 env(safe-area-inset-*),避免内容进入异形屏幕的不安全区,例如给吸底栏底部内边距加上 env(safe-area-inset-bottom);该变量无特殊区域时为 0,并可写回退值。
占用视口:320 CSS 像素宽度与放大后,固定元素的高度占比会显著上升。1.4.10 Reflow(AA)要求内容在 320 CSS 像素宽度下不需二维滚动地呈现,且不丢失信息与功能;被固定元素长期遮住的内容同样算功能受损。固定元素总高度应设内部上限,横屏与放大时可取消固定;占比没有标准阈值,需按真实设备检查。动画用 prefers-reduced-motion 降级。
状态与退化
- 零项:没有关键控件时不渲染固定容器。
- 一项与多项:同一屏优先只固定一个主行动;多个固定元素规定层级与位置,例如聊天入口避开吸底加购栏。
- 加载与错误:吸底加购栏在变体数据未就绪时保持禁用并说明原因,失败信息就近呈现。
- 无 JavaScript:sticky 头部纯 CSS 可用;依赖脚本的吸底栏退化为页内原位按钮,聊天入口退化为指向联系页的链接。
- 减少动态:取消进入与退出的位移动画。
常承载的内容与模块
导航与搜索入口、商品价格与加购动作、客服渠道入口与回到顶部。聊天入口是 support-contact 内容类型的入口之一:渠道、服务时间与响应预期由该类型维护,悬浮按钮只是呈现,并应链接到联系页作为无脚本退化。平台落点(核验于 2026-09-29):Shopify Help Center 的 Inbox 聊天设置页写明可为聊天按钮(Activator)设置图标、标签以及水平与垂直位置,未提及针对移动端的单独设置,也未说明如何避让吸底元素或软键盘,需自行核对。总览见功能模块。
发布前检查
- 用 Tab 走遍页面,聚焦元素是否被吸顶或吸底元素完全遮挡?是否设置了
scroll-padding? - 320 CSS 像素宽度、放大与横屏下,固定元素总高度是否仍留出足够阅读区域?
- 软键盘弹出与刘海屏安全区下,吸底元素是否可用且不被盖住?
- 固定的加购栏是否与主购买区状态一致?聊天入口、回到顶部与吸底栏是否互相遮挡?
- 无 JavaScript 时是否仍有入口?
固定版本主题实现
- Dawn 页头与导航:Dawn 的 sticky header 由
sticky_header_type设置控制,共四个取值。 - Horizon 页头与导航、Horizon 吸底加购与可售状态:Horizon 的 sticky header,以及商品页吸底加购(
enable_sticky_add_to_cart,默认开启)。
固定基线为 Dawn v15.3.0 与 Horizon 4.2.0;结论限于这两个提交,均为静态源码分析,未运行验证。
待继续完善
- 在真实 iOS 与 Android 浏览器中测试软键盘、地址栏收起与安全区的组合表现。
- 其他主题与版本的吸顶、吸底设置项未核验;固定版本实现见「固定版本主题实现」。