关于 Shopify 与电商的报道与研究
Horizon 的 hero 区块自身有 36 项 section 设置,8 种区块类型另外承载 104 项设置,而它的 Height 下拉菜单会随着屏幕变宽从 rem 切换到 svh。本文读取自该主题源码,提交记录为 8b42ace。
Horizon 是 Shopify 为新店铺默认提供的主题,而它的 Hero 区块是大多数商家最先接触的部分。主题编辑器会给你一个有六个选项的 Height 下拉菜单和一个图片位。它不会告诉你,其中三个选项的计量单位会随屏幕宽度变化,也不会告诉你这里的“Large”与 Dawn 里的“Large”完全不是一回事。
这些数字是怎么来的。 2026 年 9 月 1 日,我们读取了公开的 Shopify/horizon 仓库,提交记录为 8b42ace(2026-08-31)——Horizon 不发布 release,也没有 tag,所以提交就是版本。设置 schema 和 srcset 尺寸阶梯取自 sections/hero.liquid,共 1496 行;高度变量取自 snippets/theme-styles-variables.liquid;区块规则取自 assets/base.css。区块描述则从主题共享的 blocks/ 库中解析而来,因为 hero 的 schema 只给出了名称。所有数据均由脚本从这些文件中提取。
这是让人意外的部分。Horizon 并不是每个选项对应一个高度——而是跨两个断点共三个高度,且单位会切换:
| 设置 | 移动端 | ≥40em | ≥60em |
|---|---|---|---|
| Small | 15rem = 240px | 40svh | 50svh |
| Medium | 25rem = 400px | 55svh | 65svh |
| Large | 35rem = 560px | 70svh | 80svh |
在 40em 以下,高度以 rem 固定。在其之上则变为 svh,即小视口高度单位——可见屏幕的一个百分比。所以在手机上,Large 的 hero 是固定的 560px 高;而在宽屏桌面端,它是访客窗口高度的 80%。
另有两个高度完全绕开了这张表。full-screen 设为 100svh。custom 提供一个滑块 section_height_custom,取值 0 到 100%,默认值为 50——而这个值同样被直接写成 svh,而不是像素。
两个主题都提供 Large 的 hero。它们并不可比,原因有两个,彼此独立。
rem 的基准不同。 我们检索了该主题的每一个文件:Horizon 从不覆盖根字号,所以 1rem 就是浏览器默认值 16px。Dawn 设置了 font-size: calc(var(--font-body-scale) * 62.5%),这让 1rem 变成 10px。同样的 35rem,在 Horizon 里意味着 560px,在 Dawn 里则是 350px。
断点以上的单位不同。 Dawn 的 Large 在桌面端是固定的 720px,在任何屏幕上都一样。Horizon 的 Large 是 80svh,因此会随显示区域增长:在 900px 高的窗口里约 720px,在 1440px 高的窗口里约 1152px。
如果你要在两个主题之间迁移设计,这是最有可能让设计崩掉的那一项设置。
Horizon 用两组硬编码的尺寸阶梯构建 srcset,位于该 section 的第 103 行和第 105 行:
| 尺寸阶梯 | 范围 | 档位 | 请求的宽度 |
|---|---|---|---|
| 全宽媒体 | 832–3840px | 6 | 832, 1200, 1600, 1920, 2560, 3840 |
| 分栏媒体 | 416–1600px | 5 | 416, 600, 800, 1200, 1600 |
如果 hero 要横跨整个页面,请上传 3840px 宽 的图片。较窄的那组阶梯止步于 1600px,因为在那种布局下每张图片只占据部分宽度。
注意最低一档:Horizon 从 832px 起步,而 Dawn 从 375px 起步。Horizon 根本不会为全宽 hero 图片提供手机尺寸的版本——如果你的流量以移动端为主且网络较慢,这一点值得留意。
Dawn 在 section 的 schema 内部描述它的区块。Horizon 只给出名称,把描述放在共享库里,所以单看 sections/hero.liquid 完全无法知道一个区块能做什么。解析之后,这 8 种类型合计承载 104 项设置:
| 类型 | 名称 | 设置数 | 定义于 |
|---|---|---|---|
@theme | — | 0 | wildcard |
text | Text | 19 | blocks/text.liquid |
button | Button | 12 | blocks/button.liquid |
logo | Logo | 15 | blocks/logo.liquid |
jumbo-text | Jumbo text | 9 | blocks/jumbo-text.liquid |
spacer | Spacer | 7 | blocks/spacer.liquid |
group | Group | 36 | blocks/group.liquid |
_marquee | Marquee | 6 | blocks/_marquee.liquid |
@theme 是一个通配符:它接受任意主题区块,因此自身没有设置。group 是最重的一个,有 36 项设置,因为它是一个布局容器,把该 section 自身的大部分对齐与间距控制在下一层重复了一遍。
作为参照:Dawn 的图片横幅提供 3 种区块类型,合计 12 项设置。Horizon 的 hero 提供 8 种,合计 104 项。这才是两个主题之间真正的差别,而它在主题编辑器里任何地方都看不出来。
36 项设置,按它们在编辑器中出现的样子:
| 代码中的 ID | 编辑器中的标签 | 类型 | 默认值 | 范围 / 选项 |
|---|---|---|---|---|
media_type_1 | Type | select | image | 2 个选项 |
image_1 | Image | image_picker | — | — |
video_1 | Video | video | — | — |
media_type_2 | Type | select | image | 2 个选项 |
image_2 | Image | image_picker | — | — |
video_2 | Video | video | — | — |
stack_media_on_mobile | Stack media | checkbox | false | — |
custom_mobile_media | Show different media on mobile | checkbox | false | — |
media_type_1_mobile | Type | select | image | 2 个选项 |
image_1_mobile | Image | image_picker | — | — |
video_1_mobile | Video | video | — | — |
media_type_2_mobile | Type | select | image | 2 个选项 |
image_2_mobile | Image | image_picker | — | — |
video_2_mobile | Video | video | — | — |
link | Link | url | — | — |
open_in_new_tab | Open link in new tab | checkbox | false | — |
content_direction | Direction | select | column | 2 个选项 |
vertical_on_mobile | Vertical on mobile | checkbox | true | — |
horizontal_alignment | Alignment | select | flex-start | 4 个选项 |
vertical_alignment | Position | select | center | 3 个选项 |
align_baseline | Align text baseline | checkbox | false | — |
horizontal_alignment_flex_direction_column | Alignment | select | flex-start | 3 个选项 |
vertical_alignment_flex_direction_column | Position | select | center | 4 个选项 |
gap | Gap | range | 12 | 0–100px,步长 1 |
section_width | Width | select | page-width | 2 个选项 |
section_height | Height | select | medium | 6 个选项 |
section_height_custom | Custom height | range | 50 | 0–100%,步长 1 |
background_color | Background color | color | — | — |
toggle_overlay | Media overlay | checkbox | — | — |
overlay_color | Overlay color | color | #00000026 | — |
overlay_style | Overlay style | select | solid | 2 个选项 |
gradient_direction | Gradient direction | select | to top | 2 个选项 |
blurred_reflection | Blurred reflection | checkbox | false | — |
reflection_opacity | Reflection opacity | range | 75 | 0–100%,步长 1 |
padding-block-start | Top | range | 0 | 0–100px,步长 1 |
padding-block-end | Bottom | range | 0 | 0–100px,步长 1 |
值得指出的几点:
四项彼此独立的对齐设置。 horizontal_alignment 和 vertical_alignment 在内容按行排列时生效;horizontal_alignment_flex_direction_column 和 vertical_alignment_flex_direction_column 则在内容堆叠时生效。改动其中一个,另一个仍保留旧值,这正是 hero 在桌面端看着正常、在移动端却出错的常见原因。
reflection_opacity ——一个从 0 到 100% 的滑块,默认 75,与 blurred_reflection 配套。Dawn 没有对应功能。
四个图片位和四个视频位。 hero 会两次接收媒体——桌面端一套,以及藏在 custom_mobile_media 之后的另一套移动端媒体,该开关默认为 false。
打开 sections/hero.liquid,阅读文件底部的 {% schema %} 块即可看到设置。高度位于 snippets/theme-styles-variables.liquid 的第 143 至 157 行。区块描述在 blocks/ 中——每种类型一个文件,文件名与上表 type 列完全一致。
Horizon 没有 release,所以没有版本号可引用。本页改为注明所依据的提交记录;如果主题发生变化,这些数据也会随之变动。
全宽主视觉用 3840px 宽。Horizon 会请求从 832px 到 3840px 的 6 种宽度。对于分栏媒体,它使用另一组 5 种宽度、最大到 1600px 的尺寸阶梯,所以那里 1600px 就够了。
在移动端,固定选项为 240px、400px 和 560px。在 40em 以上则变为 40svh、55svh 和 70svh,在 60em 以上为 50svh、65svh 和 80svh。全屏为 100svh,自定义则是一个直接按 svh 读取的滑块。
有两个原因。Horizon 从不覆盖根字号,所以 1rem 就是浏览器默认的 16px,而 Dawn 设置了 62.5%,得到 10px。并且在断点以上,Horizon 用 svh 计量,即窗口的一个百分比,而 Dawn 仍然使用固定值。
section 本身有 36 项,另外 8 种区块类型合计承载 104 项设置。这些区块设置并不在 section 文件里——Horizon 把它们放在共享的 blocks/ 库中。
在主题的 blocks/ 目录下,每种区块类型一个文件。hero 的 schema 只列出类型名称,所以单看 section 文件会显示这些区块完全没有设置。@theme 条目是一个通配符,可接受任意主题区块。