开头:一个"对不齐"的小问题
决定把个人博客正式升级成求职作品集之后,我做的第一件事,是在桌面端把首页从头到尾看了一遍。这一看就看出问题:右上角的 🌙 深色模式按钮,没有和内容区右缘对齐,被挤到了中间。
做前端十年,这种"差几个像素"的问题我修过太多。按惯性,我打开样式表,开始调 padding、调 margin、调 flex 的 gap——十分钟过去,按钮纹丝不动。数值怎么改都无效,这通常意味着:问题不在我改的地方。
排查:把每个子元素标出来
我调整策略,先看结构。开发者工具里把导航栏的每个子元素都标注出来,这时一个奇怪的东西跳了出来:一个宽度为 0 的空 div,占着 justify-content: space-between 布局的最右位置。
它叫 .nav-overlay。这是移动端菜单的全屏遮罩——点开菜单时,一个盖住整个屏幕、带半透明背景的层,用来承接"点击空白处关闭菜单"的交互。它的样式长这样:
/* 原实现 */
.nav-overlay { display: none; }
@media (max-width: 768px) {
.nav-overlay { display: block; position: fixed; inset: 0; z-index: 999; }
}
问题一目了然:position: fixed 只写在媒体查询里。桌面端它没有 fixed,就是 flex 里的一个普通子项——零宽、透明、但真实存在,稳稳地占住 space-between 的最右锚点,把导航整体往左顶。
这是我自己半年前写的代码。写的时候只想着"移动端要 fixed",忘了问一句:桌面端呢?
根因:媒体查询不是样式隔离
这次 bug 真正的价值,是逼我重新想清楚一件事:@media 到底在做什么?
它做的是"在特定断点下,替换或追加一组规则",而不是"给元素贴一个'只在手机上有样式'的标签"。所以:
- 桌面端
.nav-overlay的display: none没生效(因为我在媒体查询里才写display: block,桌面端实际是默认值) - 它作为 flex 子项参与桌面端布局——零宽也占锚点
position: fixed只在手机宽度下生效,桌面端它是个"普通流内元素"
响应式样式的作用域,比你想象的要宽。 凡是在媒体查询里写下的 position、display、width,都要多想一步:它在其他断点下,会以什么默认值参与布局?
修复:全局基础样式 + 断点显隐分离
修复本身很简单,但思路值得记录——把"定位"和"显隐"分开管:
/* 修复后:position 是元素的基础属性,显隐交给断点 */
.nav-overlay { position: fixed; inset: 0; z-index: 999; display: none; }
@media (max-width: 768px) {
.nav-overlay { display: block; }
}
桌面端遮罩脱离文档流,不再占位;移动端行为不变。同时删掉了媒体查询里那条重复规则,避免两处定义以后再次分叉。同批还处理了两个小细节:.nav-inner 加 padding-bottom: 1.25rem(避免底边框贴住导航文字);header 底边框从通栏的 .site-header 迁移到 960px 约束内的 .nav-inner,让分隔线宽度和内容区一致。
作品集改造:首页做减法,详情页做加法
既然是奔着"求职作品集"去的,光修 bug 不够。借着这次改版:
- hero 区砍掉「📝 博客」和「了解更多 →」两个链接——作品集首页信息越聚焦越好
- 「下载简历」从按钮样式改成和 Email / GitHub 一致的纯文字链接,一行三个入口,干净
- 新增
projects/blog-system.html详情页(返回链接 → 标题+在线版 → 简介 → 技术栈 tags → 核心能力 5 条),首页卡片改为跳详情页
首页只留"我是谁、怎么联系、看什么项目"三件事,剩下的交给详情页承接。
部署与意外发现
部署流程走的是:commit → push Gitee → 服务器 git pull → pm2 restart blog(pm2 装在项目 node_modules/.bin,不是全局)。线上验证:hero 只剩 Email / GitHub / 下载简历,详情页 200,遮罩修复生效。
顺手检查基础设施时发现一个更隐蔽的问题:blog.alleria.cn 没有配置 HTTPS。nginx 只有 80 端口的配置,443 端口落到了别的证书上,curl 直接提示证书域名不匹配。这件事已记录在案,等用户决策是否补证书——在求职阶段,简历上挂的域名没有 HTTPS,观感是很伤的。
另外把 .workbuddy/(含服务器密码的 memory 文件)加进了 .gitignore,这类带敏感信息的目录绝不能进仓库。
方法论沉淀
- 媒体查询 ≠ 样式隔离。断点外的规则会以默认值参与布局,写
position/display/width前多想一步它在其他断点的形态 - 布局问题先看结构,再调数值。把 flex 子项逐一标注,透明元素、零宽元素都是"幽灵钉子"
- 部署即验证。每次上线顺手过一遍线上表现和 HTTPS/证书,隐性风险往往藏在"以为早就配好了"的地方
这次改版前后花了大半天,表面上是修了一个对不齐的按钮,实际上是把"响应式作用域"这个欠账还清了,顺便给作品集补上了详情页。如果你也在打磨自己的求职作品集,建议从桌面端、手机端各过一遍首页——你可能会发现,坑早就埋在那里了。