三栏布局是怎么组成的

页面主体是「左栏 / 正文 / 右栏」的弹性布局:

1
2
3
4
5
6
┌──────────┬────────────────────┬──────────┐
│ 左栏 │ 正文 │ 右栏 │
│ 个人名片 │ 文章 / 资源列表 │ 统计 │
│ 音乐 │ │ 目录 │
│ 分类/标签 │ │ 日历 │
└──────────┴────────────────────┴──────────┘

用 flex 而不是 grid,好处是任意一栏隐藏时,正文会自动补位,
不需要为每种组合单独写一套布局规则。

宽度相关的四个参数

都在主题 _config.yml 的「外观」区块:

1
2
3
4
5
6
7
8
# 三栏总宽度
layout_width: 1440px
# 三栏之间的间距
layout_gap: 36px
# 中栏最大宽度
main_width: 820px
# 左右侧栏宽度
rail_width: 240px

它们的关系是:

1
layout_width ≥ 左栏宽 + 右栏宽 + main_width + layout_gap × 2

以默认值为例:260 + 260 + 820 + 36 × 2 = 1412,小于 1440,留了一点余量。

如果你把 main_width 调得比可用空间还大,正文会被压缩而不是溢出——这是刻意的,
保证小屏下不会出现横向滚动条。

想给正文更大空间

两种做法,任选其一:

1
2
3
4
5
6
# 做法一:加大总宽度(屏幕够宽时推荐)
layout_width: 1600px
main_width: 900px

# 做法二:收窄侧栏
rail_width: 220px

单独设置左右栏宽度

rail_width 是全局值,也可以在 rail 区块里分开设置:

1
2
3
4
5
rail:
left:
width: 280px
right:
width: 240px

响应式收栏顺序

窗口变窄时,主题按「先收右栏,再收左栏」的顺序处理:

视口宽度 布局
> 1280px 三栏完整显示
1024 ~ 1280px 隐藏右栏,左栏 + 正文
≤ 1024px 隐藏左栏,单栏
≤ 640px 单栏 + 更紧凑的内边距

右栏先收起是因为它承载的是辅助信息(统计、日历、站点信息),
而左栏的个人名片和分类导航对站点辨识度更重要。

这两个断点写在 themes/echo/source/css/echo.css 里:

1
2
3
4
5
6
7
8
9
/* 先收起右栏 */
@media (max-width: 1280px) {
.rail-right { display: none; }
.layout-main { max-width: none; }
}
/* 更窄后再收起左栏 */
@media (max-width: 1024px) {
.rail-left { display: none; }
}

右栏收起后,文章目录不会丢:正文顶部会出现一个可折叠的内嵌目录。

侧栏组件开关

rail 区块是总开关,各组件可以独立关闭:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
rail:
enable: true # 总开关,false 则左右栏都不渲染
left:
enable: true
right:
enable: true

profile:
enable: true # 个人名片
music:
enable: false # 音乐播放器
category:
enable: true # 分类
tags:
enable: true # 标签
stats:
enable: true # 站点统计
calendar:
enable: true # 日历
siteinfo:
enable: true # 站点信息

关掉组件后,同一栏里剩下的组件会自动上移,不会留下空白。

侧栏分类按页面自动过滤

侧栏的「分类」组件会根据当前页面自动切换分类范围,不用手动配置:

所在页面 显示的分类
首页 全部分类(文章 + 资源)
文章页、文章总页、文章分类页 仅文章分类
资源库总页、资源类型页 仅资源分类

这样在资源库里不会再看到一堆跟资源无关的文章分类,侧栏始终和当前内容相关。

深色模式

配色模式三选一:

1
2
# auto 跟随系统 / dark 强制深色 / light 强制浅色
color_scheme: auto

选 auto 时,导航栏右侧会出现一个太阳/月亮按钮,访客可以手动切换,
选择会记在 localStorage 里,下次访问保持。

改主题配色

配色统一写在 themes/echo/_config.yml 的 colors 段里。
只填你真正想改的项,其余全部由 accent 自动派生:

1
2
3
colors:
accent: '#5b8cff'
# secondary: '#8f6bff'

改 accent 一个值,下面这些会一起变:

派生变量 用途
--accent 按钮、选中态、链接、角标、进度条
--accent-soft 主色浅底(选中项背景、资源角标底色)
--accent-strong 深色模式正文里的主色,保证对比度
--accent-text 暗色模式的行内代码色
--accent-glow 主色发光阴影(卡片、按钮的彩色投影)
--secondary 渐变辅色,留空则由 accent 自动提亮
--brand-gradient 导航栏品牌方块的渐变

也就是说,不需要去 CSS 里逐个替换颜色。

想更精细地微调,就显式覆盖对应变量(值写任意合法 CSS 颜色):

1
2
3
4
colors:
accent: '#e0454f'
secondary: '#ff8a5c' # 渐变第二色
accent-glow: 'rgba(224, 69, 79, .35)'

colors 里出现过的任何键都会输出成同名 CSS 变量,
所以自定义变量(如 warn: '#f59e0b')也能在这里配。

兼容性:老写法 accent: '#5b8cff' 仍然有效,等价于 colors.accent。

首页顶部大图(Hero)

首页顶部是一块整幅大图,导航透明悬浮在图上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
hero:
enable: true
# 背景图:相对 source 的路径,或完整 URL
image: /images/hero.svg
# 高度,可写 520px / 60vh
height: 520px
# 暗色遮罩,越大文字越清晰
overlay: 0.42
title: ''
subtitle: ''
buttons:
- text: 进入资源库
url: /resources/
icon: layers
primary: true
- text: 浏览归档
url: /archives/
icon: archive
primary: false

几点说明:

  • image 留空会回退到 header.banner,方便你复用同一张图。
  • title / subtitle 留空时,自动取 index.banner_title 与 index.banner_subtitle。

内页横幅(page-banner)

/articles/、/archives/、分类页、标签页、资源库、独立页面顶部共用同一套横幅,
直接复用 header.banner 的图和遮罩:

1
2
3
header:
banner: /images/covers/hexo-theme.svg
overlay: 0.72

横幅图通常比页面底色深,主题会在横幅底部铺一段渐隐,
让它溶进正文底色,避免浅色主题下出现「上深下浅」的硬边。

渐隐高度通过 CSS 变量调节(写在 head.ejs 注入的自定义样式里,或直接改主题 CSS):

1
:root { --banner-fade: 104px; }

值越大过渡越长。不想让横幅图片参与配色时,把 header.banner 留空即可——
横幅会退化成主色浅底渐变,与页面自然一体。

浅色主题下横幅自动换色

深色大图和深色蒙层压在浅色页面上会又闷又割裂,所以浅色主题下横幅不使用大图,
改用明亮的浅蓝配色:

位置 浅色主题下的表现
顶部导航横幅 浅蓝渐变底,导航文字与图标为高对比深色
内页横幅 浅蓝渐变底 + 纯白卡片,标题/描述为深色

想换成别的浅色(如薄荷绿、浅粉),改 colors.banner_light 即可:

1
2
3
4
colors:
banner_light: '#dbeafe' # 浅蓝(默认)
# banner_light: '#d1fae5' # 浅绿
# banner_light: '#fce7f3' # 浅粉

主题会自动派生描边色与渐变尾色,所以只填一个色值即可。
文字颜色固定为深色系,在任何浅底上都能看清。

深色主题不受影响,仍使用完整大图 + 蒙层。
想让浅色主题也保留大图,把 header.banner 保持不变的同时,
在 source/css/echo.css 里删掉 [data-theme='light'] .site-header-bg 与
[data-theme='light'] .page-banner 的 background-image: none !important; 这两行即可。

浅色样式同时挂在 [data-theme='light'] 和 [data-theme-hint='light'] 两个选择器上。
后者是 layout.ejs 直接输出到 <html> 的配置值(color_scheme 为 light/dark 时生效),
目的是让配色在 JS 执行前就正确,避免深色大图先闪一下再变浅蓝。
改动浅色专属样式时,两个选择器都要一起改,否则手动切换主题时会出现闪帧。

首页大图上的导航栏(例外说明)

首页 Hero 是唯一「大图 + 透明导航」的状态,导航文字必须是白色才能在深色大图上看清,
所以浅色主题的换色规则会主动排除它:

1
[data-theme='light'] .site-header:not(.has-hero):not(.is-scrolled) .nav-link { ... }

也就是说浅色规则只在「导航有实底」时生效。两种情况对照:

首页导航状态 表现
顶部悬浮(在 Hero 大图上) 透明底 + 白字白图标,无分隔线
向下滚动后(is-scrolled) 实底 + 模糊 + 跟随当前主题的文字色

这也是为什么浅色主题下首页顶部看不到那条浅蓝描边——它本来就该是”无边框悬浮”。

如果你把 header.banner 或 hero 关掉,导航变成常驻实底,
此时浅色规则会重新生效,导航自动变为深色文字,这是预期行为。

横幅标题图标的颜色

横幅标题(.page-banner-title)里的图标跟随标题文字色(currentColor),
不使用主色蓝,这样标题整体是一个视觉单元。
想单独给图标上色,改 echo.css 里的 .page-banner-title .icon 即可。

换一张自己的图

把图片放进 source/images/,然后:

1
2
hero:
image: /images/your-banner.jpg

建议尺寸 1920×1080 以上、横向构图,主体内容尽量偏中间,
这样在窄屏下裁切时不会把重点切掉。

  • 按钮上可以放 icon,取值见第四篇的图标清单。
  • enable: false 时首页会退回原来的「简介卡片 + 按钮」样式。

导航的固定行为

首页导航是固定在顶部的:在顶部时透明悬浮在大图上(白字),
向下滚动过大图后自动变成实底并恢复当前主题的文字色,保证在任何位置都清晰可读。
这一点在浅色主题下同样成立——首页大图始终是深色的,所以悬浮时始终用白字。

内页(文章、归档、资源库)的导航则是吸顶显示,配一条细横幅背景。

内页横幅

内页顶部的横幅共用同一个背景图配置:

1
2
3
header:
banner: /images/covers/hexo-theme.svg
overlay: 0.72 # 遮罩透明度 0~1

留空 banner 则不显示图片,只保留纯色渐变背景。

下一篇

下一篇讲资源板块:resource 字段的完整写法、网盘链接、提取码与配色。