博客的视觉定制有一条底线:不改主题源码。所有样式集中写在 source/css/code-enhance.css,脚本放 source/js/,通过主题配置的 inject 机制注入页面。node_modules 里的主题文件升级即被冲掉,永远不直接改。
配套两条规则。注入链接带版本号 ?v=YYYYMMDDx,每次改动递增,不然 CDN 和浏览器吃旧缓存——ech0 说说的样式表吃过这个亏。覆盖主题样式时经常要用 !important,因为同名选择器特异性常常打平,注入层先加载会输,用 !important 保证加载顺序不稳定时也生效。
这篇按时间顺序记录两个月的视觉迭代。
code-enhance.css 的第一笔:代码块
6 月 28 日建文件,先改代码块:右下硬边阴影加同色系淡渐变,复制按钮的文字换成图标。
硬边阴影的关键是 blur 为 0:box-shadow: 4px 4px 0 rgba(0,0,0,0.35),无模糊才有层叠的立体感。阴影颜色最初用主题变量,实测计算值透明度太低,看不出立体,换成固定值。
复制按钮没动 JS。主题的复制脚本会动态写入 “Copy” / “Copied” 文字并切换类名,纯 CSS 就能接管:font-size: 0 藏掉文字,::before 伪元素用 CSS mask 画图标。mask 的好处是图标颜色由 background-color 决定,默认态跟着主题文字色走,暗色模式自动反转,不用写两套。
背景图与导航栏透明化
整页背景图是主题的官方配置点,不是 hack:style.site 块配背景图加模糊参数。侧边栏有自己的背景层,不受影响;正文区透明,背景透出来。
配完背景,顶部导航栏变成了突兀的白色胶囊。排查主题的源码,发现导航的毛玻璃效果是四层叠加:
::before白色半透明底加模糊;::after饱和度滤镜加白色内阴影;- 元素自身三层白色 text-shadow 光晕;
- 未选中链接叠白色 drop-shadow。
试错走了四轮:先把伪元素白底从 0.3 降到 0.12,还突兀;再降到 0.05 加内阴影,和之前没区别;把两个伪元素直接 display: none,未选中项的文字还是像每个字都有白底。最后查到是 text-shadow 和 filter 这两层。
教训记下来了:文字看着有底色,先查 text-shadow 和 filter: drop-shadow,不要只盯着 background。
卡片:从渐变毛玻璃到透明
卡片的样式改过三轮。第一轮 6 月底,默认半透明白底在彩色背景上偏白,换成紫粉渐变加 backdrop-filter 毛玻璃,暗色模式透明度整体调高,不然黑底上看不出渐变。
8 月 20 日整体改版,方向反转:去掉渐变,卡片扁平化;第二天再进一步,无封面的文章卡直接透明底加实色边框,有封面的卡片保留实底,封面图需要不透明容器。说说页卡片走同一条路。
改版那天的主题是「安静」:主题色从青色系换成松绿族,整站渐变、日历、微动效里的颜色全部精确串替换;默认改深色模式,切换按钮挪进左栏社交行。
深色模式的一个经典坑
改版后发现深色下左栏越往上越发白。根因不在我这层:配置里注释掉左栏背景图,只停了覆盖层,主题默认配置里的彩虹背景还在生效,主题据此编译了一层白色渐变遮罩。修复是在注入层把左栏背景图和对应伪元素一起移除。
配置层注释掉一个值,不等于主题回到无值状态,主题默认配置还有一份。这类坑查起来要先分清「我改的」和「主题默认的」。
字体与置顶徽章
7 月 24 日两项。正文换思源宋体,走 jsdelivr 的 @fontsource 分包,只加载 300 和 700 两个字重控制体积,总共约 3MB。字重匹配规则:正文 400 向下落到 300,标题的 500 和 700 向上落到 700。左栏的欢迎便签单独保留楷体,其余组件跟随正文。
置顶徽章本来想改模板实现,踩了两个坑才绕回 JS 方案:
- 建
themes/stellar/覆盖目录只放了一个模板文件,hexo 检测到目录存在就把整个主题解析切过去,标签插件全丢,构建直接失败。覆盖目录只查存在,不查完整性。 - 直接改 node_modules 被编辑工具拦下。
最后用注入脚本:找到置顶文章的标题,插入一个渐变徽章,删掉原来的图钉图标。不改模板不改主题,升级无损。
三处科技感点睛
7 月 28 日从一份参考设计里挑了三项:全屏极淡点阵底纹、卡片 hover 上浮加顶部流光、欢迎便签的打字机效果。
打字机用 IntersectionObserver,进视口才触发;尊重 prefers-reduced-motion,系统要求减少动效就直接显示全文。颜色统一用主题色变量,没有引入参考稿的电青色。
同期也划掉了三项:电青辉光与现有主题色太近;等宽字体点缀会和思源宋体冲突;参考稿的主题切换按钮和左栏已有实现是两套,不混用。取舍的标准就一条:和已有的视觉系统是否兼容。
背景图换到山景
8 月 20 日背景从模糊色块换成整图山景。遮罩改了两轮:先是「下半部分文字看不清」,均匀遮罩换成方向性渐变,顶部保通透、底部压暗保证页脚可读;再是「背景向上淡出有割裂」,整图不裁断。
9 月初做了一次图片资产盘点:四个页面的 banner 换图,删了 12 张无引用的死图,相册重建。删图前全树 grep 确认零引用,部署后逐张 curl 验证 404。
收尾
两个月的视觉迭代沉淀成一套固定流程:改注入层样式 → 版本号加一 → 本地预览 → 部署 → 线上查计算样式验证。
技术上用过的手段:CSS mask 画图标、:has() 父选择器、毛玻璃、点阵底纹、字重匹配、!important 裁决特异性平手。每一项背后都有一次排查过程,这篇里记的都是第一次踩到的样子。