Bootstrap 5 中如何让菜单栏与主内容区保持等高?
把 nav 和 main 放进同一个 Flexbox 容器,去掉菜单的固定高度,让两列沿交叉轴拉伸,就能自动等高。typed.js 写入文字或窗口宽度变化导致内容换行时,浏览器会重新计算布局,不必用 JavaScript 同步高度。
为什么当前两列不能自动等高?
现有代码中,nav 使用 height: 600px,main 使用 min-height: 600px。主内容超过 600px 时,main 可以继续增高,nav 却仍然只有 600px。
另外,nav 位于包裹 main 的 .row 外面。即使 .row 使用 Flexbox,也只能影响它的直接子元素,外面的菜单无法参与等高布局。float: left 本身也不会让相邻元素自动等高。
调整 HTML,让两列成为直接兄弟元素
在 header 后新增 .page-columns,把现有的整个 nav 和整个 main 移进去。删除原来仅包裹 main 的那层 .row,并移除外层 nav 上的 sticky-top。
下面只展示需要调整的结构,注释位置保留原有内容:
<div id="container" class="container">
<header>
<!-- 保留原有页头内容 -->
</header>
<div class="page-columns">
<nav class="navbar navbar-expand-lg">
<div class="container-fluid">
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div
class="collapse navbar-collapse"
id="navbarSupportedContent"
>
<menu class="navbar-nav">
<!-- 保留原有菜单项 -->
</menu>
</div>
</div>
</nav>
<main>
<!-- 保留原有 article、图片和 typed.js 文本容器 -->
</main>
</div>
<footer>
<!-- 保留原有页脚内容 -->
</footer>
</div>
折叠按钮的 data-bs-target 与折叠容器的 id 保持一致,原有 Bootstrap 导航折叠结构可以继续使用。
添加两列布局样式
将以下规则放在 index.css 末尾,覆盖原有的宽度、高度和布局声明:
.page-columns {
display: flex;
align-items: stretch;
}
.page-columns > nav {
display: block;
position: static;
float: none;
flex: 0 0 130px;
width: auto;
height: auto;
align-self: stretch;
background-color: #C0C0C0;
}
.page-columns > main {
position: relative;
float: none;
flex: 1 1 0;
min-width: 0;
width: auto;
min-height: 600px;
background-color: #E0E0E0;
}
@media screen and (max-width: 991.98px) {
.page-columns > nav {
flex-basis: 80px;
}
}
flex: 0 0 130px 为菜单保留 130px 宽度,小屏幕下改为 80px。main 占据剩余空间,min-width: 0 允许它随容器收窄。
菜单高度为 auto 时,align-items: stretch 会把它拉伸到与主内容区相同的高度。如果展开后的菜单更高,菜单会撑高这一行,主内容区也会随之拉伸。两列最终以较高的一侧为准。
main 的 min-height: 600px 可以保留,作为页面的最低内容高度。文字超过这个高度时,两列会一起增高;如果不需要最低高度,可以删除该声明。
这里使用 991.98px,让菜单宽度变化与 navbar-expand-lg 在 992px 处的切换衔接。原来的 max-width: 990px 与 min-width: 992px 之间有一个未覆盖区间。
需要滚动吸顶时,把 sticky 放到菜单内部
外层 nav 承担整列的高度和背景。如果它已经与整行等高,再设置 sticky-top,通常没有足够空间产生预期的吸顶移动。
可以让内部的 .container-fluid 吸顶,并取消原来 menu 自己的 sticky 设置:
.page-columns > nav > .container-fluid {
position: sticky;
top: 0;
}
.page-columns > nav menu {
position: static;
}
这样,外层菜单栏仍与 main 等高,内部导航内容会在允许的滚动范围内吸顶。如果菜单本身高于视口,还需根据页面需求处理内部滚动。
typed.js 和图片有哪些注意事项?
示例中的 #typed 位于普通文档流中。只要没有额外样式把它或其祖先设置为绝对定位、固定高度或限制溢出,文字新增和换行就会自然撑高 main。不需要在 onComplete 中测量两列高度,也不需要增加窗口缩放监听器。
但 #start_chrystus 使用了 position: absolute,图片不会参与父元素高度计算。目前的 min-height: 600px 可以提供最低显示空间。如果希望图片本身也撑开主内容区,需要让图片容器回到普通文档流,例如:
#start_chrystus {
position: static;
transform: none;
max-width: 808px;
margin: 0 auto;
}
这个修改会让图片占据布局空间,文字排在它之后。如果需要保留图片覆盖文字、悬停后显示文字的效果,就保留原来的绝对定位,并按实际展示需求设置主内容区的最低高度。
原页面同时加载了本地和 CDN 的 Bootstrap CSS、JavaScript,以及两份 typed.js。建议每个库只保留一套来源明确的文件,避免重复加载影响样式和交互排查。页头、页脚也有固定宽度设置;如果窄屏下仍有溢出,需要另行调整这些区域。
备注:内容仅供参考。
