博客菜单栏的问题其实困扰我很久了。随着菜单项越来越多,又加入了开往(Travelling)友链按钮和搜索框,首页和内页的导航栏开始出现各种不协调:有的页面菜单被挤到第二行,有的页面加载时会从左往右晃一下。趁着今天把这些问题一次性梳理并修掉,记录一下原因和改法,方便以后回看。
问题一:内页菜单把搜索挤到第二行
内页(存档、目录、标签等)使用的是 header-post.ejs,原先所有菜单项、开往按钮、搜索框都挤在同一个 <ul> 里,用 Bootstrap 默认的 float 布局排列。
菜单项变多之后,总宽度超出了导航容器(主题里 Bootstrap 的 .container 最大宽度只有 940px),搜索框就被挤到了第二行。
另外,_config.yml 里菜单名是双语格式,例如 主页|Home、存档|Archives,模板里却用 __(i.toLowerCase()) 去翻译,找不到对应 key 时会把整段 主页|home 原样显示,文字比预期长一截,进一步加剧了换行。
问题二:首页和内页菜单样式不一致
首页用的是 header.ejs 底部的 intro-navigate 导航,内页用的是顶部 navbar。两处原先各自一套样式:
- 首页菜单字号是
1.2em,内页是固定像素值,视觉大小不一致 - 首页没有搜索按钮,内页有
- 开往按钮图片写死了
width="100",在窄导航里占空间过大
最终布局方案
统一改成「菜单靠左,开往 + 搜索靠右」的 Flex 布局。
内页(header-post.ejs)拆成两组:
1 | <div class="navbar-collapse collapse hnav-bar"> |
首页(header.ejs)同样拆成 navigater-menu 和 navigater-actions 两组,并在开往右侧补上搜索组件:
1 | <%- partial('search/index') %> |
关键 CSS(header-post.css / home.css):
1 | .hnav-bar / .navigater-bar { |
其他细节调整:
- 菜单双语显示:直接读取配置键名
i.trim(),保留主页|Home格式 - 菜单字号统一为
16px - 开往图标改为
height: 22px; width: auto,去掉 hover 底边特效 - 导航容器加宽到
max-width: 1200px,左侧留出140px给头像
问题三:切换页面时菜单栏抖动
这个问题更隐蔽。点击除主页以外的菜单跳转后,导航栏会短暂地从左往右「晃」一下,看起来像布局没站稳。
排查下来有两个原因:
1. #wrap 的 transition 写得太宽
style.styl 里原来是:
1 | #wrap { |
没有指定属性名,等于所有可动画属性都会过渡。页面加载后一旦出现滚动条,容器宽度发生变化,这个宽度变化也会被动画化,肉眼看到的就是导航栏横向晃动。
修复:只过渡移动端侧栏需要的 left:
1 | #wrap { |
2. 菜单 hover 时 border-bottom 撑开布局
主题默认在 hover/focus 时加 border-bottom: 5px solid,但默认状态没有底边框,5px 突然出现会导致元素高度变化,引发布局偏移。
修复:默认加透明底边框,hover 时只改颜色:
1 | .navbar-nav > li > a { |
另外加了 scrollbar-gutter: stable,提前为滚动条预留空间,减少滚动条出现/消失带来的横向位移。
涉及的文件
| 文件 | 改动内容 |
|---|---|
themes/hiker/layout/_partial/header-post.ejs |
内页导航拆分为菜单区 + 操作区,修复 </ul> 闭合 |
themes/hiker/layout/_partial/header.ejs |
首页导航同样拆分,补充搜索按钮 |
themes/hiker/source/css/header-post.css |
内页 Flex 布局、抖动修复 |
themes/hiker/source/css/home.css |
首页样式与内页对齐 |
themes/hiker/source/css/_partial/header-post.styl |
菜单 hover、开往按钮样式 |
themes/hiker/source/css/_partial/header.styl |
首页开往按钮 hover 样式 |
themes/hiker/source/css/style.styl |
收窄 #wrap 的 transition 范围 |
小结
这类问题表面看是「菜单挤不下」或「页面抖一下」,实际上往往是布局方式、样式加载顺序和细微 CSS 副作用叠加的结果。把首页和内页当成两套导航分别维护,很容易越改越乱;统一成 Flex 左右分区之后,后续再加菜单项或按钮也更好扩展。
如果以后菜单项继续增加,优先考虑缩短双语标签的文字长度,或者把部分入口收进下拉菜单,而不是继续硬挤一行。