本章目录 / 案例进度
第 2 章 · 经典布局模式
结构方案:从一栏到底到三栏圣杯
布局模式是被反复验证过的结构方案。它们各自诞生于不同的约束 —— 屏幕尺寸、加载顺序、无障碍、SEO,理解差异才知道该抄哪一个,而不是把所有内容都塞进三栏。
案例第 2 阶段:为首页选骨架。上一章我们把内容和间距理顺了,现在要决定它们怎么摆。候选方案三选一:单栏(纯阅读)、两栏(正文 + 侧栏)、三栏 + 通栏头尾(圣杯)。本章提供两条判断线索:行宽,以及读者的浏览路径。
单栏与行宽:最被低估的布局
「单栏就是没有布局」是误解。单栏要解决的是行宽与阅读节奏 —— 而这是所有多栏布局的基础。
讲解
回扫成本决定行宽
读一行文字时,眼睛并不是匀速移动的:它在一行末尾需要回扫(saccade)到下一行的开头。行太短,回扫次数变多,阅读节奏被切碎;行太长,回扫距离变长,容易落到错误的行上(丢行)。
经验区间:西文正文 45–75 个字符(含空格),这个建议从铅字时代一直沿用到今天;中文因为字宽一致、单字信息量大,一行 25–40 字通常更舒适。注意这只约束正文 —— 标题短、按钮短,不需要遵守这条规则。
单栏不等于 width: 100%
单栏的正确写法是容器居中(版心)+ 文字左对齐。初学者常把 text-align: center 当成居中版面的手段,结果得到了每行起点都在变的正文。请把这两件事彻底分开:
- 容器居中:
max-width: 68ch; margin-inline: auto; - 文字对齐:
text-align: left;(不要动)
用 ch 而不是 px 表达行宽:1ch 是当前字体里数字「0」的宽度,所以 68ch 会随着字体自动换算。换一套字体,行宽依然是大约 68 个字符 —— 这是「相对度量」优于「绝对像素」的典型例子。
行宽变了,行高也要跟着变。行越宽,回扫距离越长,越需要更大的行高来「引导」视线回到正确位置。经验值:45ch 用 1.6,75ch 用 1.75–1.8。中文因为字面方整、笔画密集,通常比西文再松 0.1。
- 单栏的优势
- 注意力全部给内容;响应式几乎不需要降级处理;无障碍与移动端最友好;实现成本最低。
- 单栏的代价
- 单屏信息量低,次级入口(标签、订阅、相关文章)没有位置,页面容易显得「一路平铺」缺少节奏变化。
关键代码
.prose {
max-width: 68ch; /* 行宽上限:ch 随字体自动换算 */
margin-inline: auto; /* 容器居中 —— 不是文字居中 */
text-align: left; /* 正文永远左对齐 */
padding-inline: 16px; /* 小屏时的安全边距 */
}
.prose p {
line-height: 1.75; /* 行宽越宽,行高越要大 */
margin-bottom: 1.5em; /* 段间距 ≈ 1.5 倍行距,段落才分得开 */
text-wrap: pretty; /* 现代浏览器:自动避免末行孤字 */
}
/* 更进阶:用 clamp 让行宽本身也有弹性,但仍在可读区间内 */
.prose--fluid {
max-width: clamp(46ch, 60ch + 4vw, 72ch);
}
- 把
max-width交给ch、把居中交给margin-inline,单栏布局其实只有两行代码。 margin-bottom: 1.5em用em:段间距跟随字号自动缩放,标题与正文的间距比例因此保持一致。- 本站的正文容器就是
max-width: var(--measure)(68ch)——这个页面正在示范它。
动态演示
读者在一行末尾需要一次回扫,才能准确落到下一行的开头。行越宽,这次回扫的距离越长,落到错行上的概率就越高。反过来,行太短则换行过于频繁,句子的节奏被切碎,读起来一顿一顿。所以行宽不是审美偏好,而是可以直接测量的阅读成本。
拖动上面的滑块改变容器宽度,下方读数会同时给出「每行约多少个汉字 / 多少个西文字符」。
沿着滑块从左拖到右,注意读数在什么时候翻成橙色 —— 那就是离开可读区间的时刻。全宽(960px)时大约 55 个汉字一行,已经偏长了。
两栏、三栏与圣杯:主内容该排在哪儿
多栏布局真正的决策不是「分几栏」,而是「谁是主、谁在 DOM 里先出现」。
讲解
侧栏放左还是放右
- 侧栏在右(主内容在左):符合从左到右的阅读顺序,主内容优先被看到。博客、新闻、产品页的默认选择。
- 侧栏在左:把侧栏当作「工具」(导航、筛选、目录),用户需要频繁往返切换。后台界面、文档站的常见选择。
- 三栏:中间是主内容,两侧承担不同职能(左=导航/目录,右=辅助信息)。信息容量最大,代价是主内容容易被压窄,窄屏降级也更麻烦。
圣杯布局要解决的到底是什么
「圣杯」的名字来自它当年的难度。需求有三条:三栏 + 通栏页头页脚 + 主内容在 DOM 里排在最前。第三条是关键 —— 为什么主内容要排在 DOM 最前?因为屏幕阅读器、键盘用户、搜索引擎都按 DOM 顺序处理页面,正文应当第一个被遇到;而在窄屏上,正文也应当先于侧栏出现。
换句话说,圣杯布局的本质是让视觉顺序与 DOM 顺序解耦。三种实现方式在这一点上的代价完全不同:
| 实现 | 做法 | 代价 |
|---|---|---|
| float + 负边距 | 三栏全部浮动,用负边距把两侧拉回原位 | 脆弱:要清浮动、算百分比,一处改动牵动全身。今天只应作为历史理解。 |
| Flex + order | 一维排列,用 order 把主内容排到视觉中间 | order 只改视觉顺序,键盘 Tab 仍按 DOM 走 —— 视觉与焦点顺序不一致,会伤无障碍。 |
| Grid + areas | 用 grid-template-areas 直接描述版式 | 几乎没有代价:声明即版式,DOM 顺序可以完全按内容优先级写。 |
不要为了「看起来高级」而上三栏。每多一栏,主内容的可用宽度就少一块,窄屏降级就多一处断点。判断标准很简单:侧栏里的内容,读者是否需要同时看到?如果需要(文档目录、筛选器),就给它一栏;如果只是「顺便放一下」(标签云、订阅入口),一栏都嫌多 —— 收进页脚更干净。
关键代码
/* HTML 顺序 = 内容优先级:正文 → 导航 → 侧栏 */
/* <main> <nav> <aside> */
.page {
display: grid;
gap: 24px;
}
.body {
display: grid;
gap: 24px;
grid-template-columns: 160px minmax(0, 1fr) 200px;
/* 版式在这里被完整声明出来,一眼可读 */
grid-template-areas: "nav main aside";
}
.body > main { grid-area: main; } /* 正文占据中列 */
.body > nav { grid-area: nav; }
.body > aside { grid-area: aside; }
/* 窄屏降级:一个断点把三栏折成一栏,顺序自动变回 DOM 顺序 */
@media (max-width: 900px) {
.body {
grid-template-columns: minmax(0, 1fr);
grid-template-areas: "main" "nav" "aside";
}
}
- 页头与页脚不需要任何特殊处理 —— 它们不在
.body里,因此天生通栏。 grid-template-areas让版式变成「可以画出来」的声明,这是它比order更适合布局的原因。- 降级时把 areas 改成一列,视觉顺序就回到 DOM 顺序(正文在先)—— 前后一致,不会出现「手机上先看到侧栏」的怪事。
动态演示
切换实现方式,观察下面「实时输出」里 CSS 的变化 —— 效果相同,代价不同。
注意「DOM 顺序:main → nav → aside」这一行在所有模式下都不变 —— 变化的只是视觉位置。切到 Flex 实现,阅读输出的最后一条注释:order 带来的无障碍风险。
F 形与 Z 形:读者默认会怎么扫
这两种模式描述的是「页面没有明确视觉引导时」的默认行为,而不是你必须遵守的定律。
讲解
F 形:内容密集型页面
在搜索结果、文章列表、长文这类页面上,眼动研究反复观察到同一种模式:视线先沿顶部横向扫一遍,下移后再横向扫一遍(通常更短),此后主要沿左侧纵向扫读,右侧大片区域被忽略 —— 轨迹形似字母 F。它带来三条可操作的结论:
- 重要信息放在左侧与上部,不要指望读者会读到右侧中下部;
- 每段开头的几个词承担最重要的识别功能(纵向扫读时,眼睛主要抓段落起始),因此「结论先行」不只是写作建议,也是排版策略;
- 列表比整段文字更容易被扫读 —— 列表天然贴着左侧对齐线。
Z 形:信息稀疏的落地页
当页面元素少、有明确的主视觉时,视线走的是:左上(品牌)→ 右上(导航/主视觉)→ 沿对角线落到左下 → 横向到右下。轨迹形似字母 Z。它的实践含义是把行动按钮放在视线路径的终点(右下),并让对角线上的元素彼此呼应,帮助视线顺畅滑落。
关键限定:这两种模式是「引导缺席」时的兜底行为。一旦你用视觉层次和留白建立了明确的视线引导,读者就会跟着引导走 —— 这也是「排版良好的页面不遵循 F 形」的原因。所以正确的用法是:先做引导,再用 F/Z 检查有没有把重要内容放到视线死角。
三条容易被忽略的限制
- 语言方向:F 形建立在从左到右的书写系统上;在阿拉伯语等从右到左(RTL)的语言里,模式会镜像。
- 移动端:屏幕窄到一栏时,横向扫描消失,F 形退化为一维的纵向序列 —— 此时内容排序比横纵位置重要得多。
- 它不是测量结论的万灵药:眼动实验的样本、任务、页面内容都会影响结果,把它当作启发式规则,而不是物理定律。
关键代码
/* F 形场景:文章列表 / 搜索结果 —— 强化左侧对齐与段落起点 */
.result-item {
display: grid;
grid-template-columns: minmax(0, 1fr) 120px; /* 主信息占左侧大块 */
gap: 8px 16px;
text-align: left; /* 左对齐线是所有扫读的锚 */
}
.result-item__title {
font-weight: 650; /* 标题加粗:纵向扫读时第一个被抓住 */
margin-bottom: 2px; /* 标题与摘要贴紧 = 同一组 */
}
/* Z 形场景:落地页 —— 主视觉与 CTA 构成对角线 */
.landing {
display: grid;
justify-items: center;
gap: 24px;
text-align: center; /* 少量文本可以居中,形成对称的落点 */
padding-block: 64px;
}
.landing__cta {
justify-self: end; /* 按钮落在视线路径的终点:右下 */
}
- 注意两种场景对
text-align的用法完全相反:F 形靠左对齐建立扫读锚点,Z 形靠居中建立对称落点 —— 居中的前提是文本很短。 - F 形场景里,把摘要与标题靠紧(
2px)、与下一条拉开(组间间距),复用的正是 1.2 的接近性原则。 - 这些规则都只是布局上的「顺着视线」;真正的引导仍然来自层次与留白。
动态演示
切换模式时,上面那个线框页面的内容排布也会跟着变:F 形把标题与列表压到左侧并对齐成列,Z 形则把主视觉居中、行动按钮推到右下角 —— 这就是「顺着视线排版」的具体样子。