Dawn 页头与导航:下拉菜单、抽屉、公告栏与吸顶
本文基于 Dawn v15.3.0,源码固定到 ecb06c3(核验于 2026-09-29)。结论限于此提交,不表示其他版本行为相同;本篇为静态源码分析,未完成店铺运行验证。Dawn 上游已发布 v16.0.0(2026-08-10,GitHub Releases 核对),本库 Dawn 正文统一以 v15.3.0 为基线,升级前需重新核对。
对应哪些通用模式
对应Navigation Menu(下拉、Mega Menu、抽屉菜单、面包屑)、Drawer(移动菜单)、Sticky Bar(吸顶页头)与Banner(公告栏)。页头里的搜索弹层见Dawn 预测搜索。面包屑:在固定提交的全仓库搜索中未找到(搜索词:breadcrumb,不区分大小写,含 sections、snippets、assets、templates、locales、config 与隐藏文件),此版本主题没有内置面包屑,不代表平台不能实现。
入口与文件
| 文件 | 职责 | 何时输出 |
|---|---|---|
| layout/theme.liquid | {% sections 'header-group' %} 后接 <main id="MainContent">;顶部有指向它的跳过链接 | 所有页面 |
| sections/header-group.json | 默认组合:announcement-bar + header(main-menu、dropdown、on-scroll-up) | 页头组 |
| sections/header.liquid | Logo、菜单、图标区、sticky-header 元素与其内联 {% javascript %};最多 3 个 @app 块 | 页头 |
| snippets/header-dropdown-menu.liquid / header-mega-menu.liquid | 桌面菜单,由 menu_type_desktop 选择 | 菜单非空且非 drawer |
| snippets/header-drawer.liquid | 抽屉菜单,含账户、语言地区与社交链接 | 菜单非空 |
| sections/announcement-bar.liquid | 公告栏,仅限页头组,最多 12 个块 | 页头组 |
| assets/details-disclosure.js、global.js | header-menu、MenuDrawer、HeaderDrawer 与 details 初始化 | 页面加载 |
数据从哪来
菜单来自 section.settings.menu(link_list,默认 main-menu),逐层读 link.links、childlink.links、grandchildlink.links,用 current 与 child_active 标记当前位置。页头设置:logo_position、mobile_logo_position、menu、menu_type_desktop(dropdown 默认 / mega / drawer)、sticky_header_type(none / on-scroll-up 默认 / always / reduce-logo-size)、颜色方案、国家与语言选择器等。公告栏块只有 text 与 link,另有 auto_rotate(默认关)、change_slides_speed(3–10 秒)。
交互怎样运行
- 下拉与 Mega Menu:每个有子项的顶层项是
<header-menu><details>,summary只是开关,没有并列的父级链接;下拉支持三层(子级再嵌套details),Mega Menu 展示子级与孙级两层链接。details-disclosure.js没有 hover 事件,失焦时关闭并把aria-expanded设为 false。global.js启动时给所有[id^="Details-"] summary写role="button"、aria-expanded、aria-controls(下一个兄弟有 id 时),点击时同步aria-expanded,并在details上监听keyup,Escape 关闭并把焦点还给summary。 - 抽屉菜单:
header-drawer继承MenuDrawer:打开时trapFocus、锁定 body 滚动、给页头加menu-open;Escape、失焦或返回按钮关闭;嵌套details以滑入方式展开。data-breakpoint为desktop(选了drawer类型)或tablet。 - 吸顶:
sticky_header_type非none时外层是<sticky-header>。always/reduce-logo-size在连接时加shopify-section-header-sticky(position: sticky; top: 0);on-scroll-up监听滚动,向下滚过页头后加shopify-section-header-hidden(top为负的页头高度),上滚再显示。隐藏时会关闭所有header-menu与搜索弹层;菜单展开(preventHide)或建议面板打开时不隐藏。--header-height只在连接时与 990px 断点变化时写入。 - 公告栏:单块为
role="region"加可选链接;多块为slideshow-component(aria-roledescription轮播,前后按钮,每块role="group")。自动轮播开启时,悬停、聚焦、点过箭头按钮或系统减少动态都会暂停;公告栏内没有独立的暂停按钮。
与通用契约的一致与差距
| 契约 | Dawn v15.3.0 | 判断 |
|---|---|---|
不滥用 role=menu | 全仓库搜索(role="menu、menuitem、menubar)无命中;用 nav + ul + details | 一致 |
| 展开状态与关联 | 运行时补 role="button"、aria-expanded、aria-controls;初始 HTML 中没有这些属性 | 一致,依赖 JS;aria-expanded 初值取自 open 属性 |
| Escape 与焦点返回 | 下拉、Mega Menu 与嵌套 details 由 onKeyUpEscape 处理;抽屉由 MenuDrawer.onKeyUp 处理 | 一致 |
| hover 只作增强、Tab 不自动展开 | 无 hover 脚本,展开靠点击与键盘 | 一致 |
| 顶层项既是链接又能展开 | 有子项的顶层项只有开关,没有“查看全部”链接;Mega Menu 面板也没有 | 差距:父级目的地不可直达 |
| 导航地标命名 | nav.header__inline-menu 与 nav.menu-drawer__navigation 都没有 aria-label;分页的 nav 有 | 差距 |
| 当前页 | 叶子链接有 aria-current="page";有子项的顶层项只加 header__active-menu-item 类(child_active) | 部分一致 |
| 抽屉作为模态 | 有 trapFocus、Escape 与滚动锁定;header-drawer.liquid 未输出 role="dialog" / aria-modal,MenuDrawer 也未写入;assets、sections、snippets、layout 中 inert 无命中 | 差距:背景是否真正不可达未核验 |
| 桌面与窄屏结构一致 | 同一菜单数据分别输出为下拉 / Mega / 抽屉,顺序与去向相同;深度不同(Mega 两层) | 基本一致 |
| 吸顶不遮挡焦点 | on-scroll-up 向下滚时隐藏;always 时页头常驻;未设置面向页头的 scroll-padding(该词命中仅在 slider、商品、本地化等局部样式) | always 下的 2.4.11 风险未核验 |
| 吸顶占位 | sticky 保留文档流高度;--header-height 不随页头高度变化更新 | 风险:公告或页头换行后高度可能失真 |
| Banner:有效期、关闭、空状态 | schema 无有效期与关闭控件;utility-bar 容器始终输出,单块文案为空时仍输出带标签的空 region | 差距 |
| Banner:自动更新可暂停 | 默认不自动;开启后悬停 / 聚焦 / 点箭头暂停,无暂停按钮 | 部分一致 |
| 面包屑 | 未内置(见上) | 无法对照 |
定制入口与风险
商家可在页头设置里改菜单、桌面菜单类型、吸顶方式、Logo 位置与选择器,在公告栏改文案、链接、轮播;菜单层级由 Shopify 菜单数据决定。耦合点:.section-header、.header-wrapper、header-menu、details-modal 被 sticky-header 的脚本按选择器取用;global.js 的 [id^="Details-"] 依赖 id 前缀;top-center 或无菜单时页头会输出两份搜索片段;header.liquid 内联样式按 menu_type_desktop 与 990px 断点切换抽屉显隐。
建议的验证范围
本篇均未执行:用键盘遍历每一层菜单并记录 Escape 后焦点;读屏软件核对 aria-expanded、nav 名称与当前页;<990px 抽屉的焦点循环与背景可达性;三种 sticky_header_type 下 Tab 遍历是否被页头遮挡;公告栏多块、轮播与系统减少动态;菜单三层数据下三种桌面类型的表现。