直接给 .col 加 position: sticky 会失效,因为 bootstrap 的 .row 是 flex 容器,而 sticky 在 flex 子项中需满足父容器无 overflow: hidden/transform、且设置 top/left 等值,但 ios safari 15.4 前不支持 left: 0。

为什么直接给 .col 加 position: sticky 会失效
因为 Bootstrap 4/5 的 .row 是 flex 容器,而 position: sticky 在 flex 子项中触发条件极苛刻:父容器不能有 overflow: hidden、transform 或 will-change,且必须设置 left 或 right 值——但浏览器对水平方向 sticky 支持差,尤其 iOS Safari 15.4 前基本不认 left: 0。
常见现象:.col-md-3 加了 position: sticky; left: 0; 后,侧边栏要么消失,要么随页面滚动,根本“粘”不住。
- 别把
sticky写在.col上,它不是为侧边栏设计的 - 确保侧边栏的**直接父容器**(通常是
.row)没有overflow: hidden或transform - 如果用了
navbar或offcanvas,它们自带transform,会创建新层叠上下文,直接让sticky失效
用 position: sticky 实现轻量侧边栏的可行路径
能用 sticky 就别上 fixed——它不触发重排、不破坏文档流、省 JS。但前提是结构干净、样式克制。
- 给侧边栏内部容器加类(如
<div class="sidebar-inner">),而不是 <code>.col本身 - CSS 写成:
.sidebar-inner { position: -webkit-sticky; position: sticky; top: 1rem; }(top是为了避开顶部导航栏) - 必须保证该容器是块级元素,且其父容器(
.col)未设display: flex或height: 0等干扰尺寸的样式 - 移动端要加
@supports (position: sticky)降级,iOS 真机测试比模拟器更可靠 - 固定目标必须是侧边栏内部容器(如
.sidebar-inner),而非.col;否则宽度归零、位置错乱 - 必写四要素:
top: 0、left: 0、width: 250px、height: 100vh(100%会塌,100vh才撑满) - 主内容区必须配
margin-left: 250px(值严格等于侧边栏宽度),padding-left不行,它不阻止内容穿透 - 侧边栏内必须加
overflow-y: auto,否则长菜单无法滚动;同时设max-height: calc(100vh - 2rem)防溢出 - 在
@media (max-width: 768px)中,必须移除position: fixed和margin-left,还原为普通流式布局;别用display: none,保留 DOM 供 JS 控制抽屉开关 -
z-index必须显式设高:默认navbar是 1030,offcanvas是 1140,侧边栏至少z-index: 1150 - 如果侧边栏和
offcanvas共存,千万别把侧边栏放在offcanvas内部——transform会让它的定位相对 offcanvas 而非视口 - 移动端软键盘弹出时,
fixed元素会被顶起,iOS Safari 尤其明显;此时只能靠 JS 监听focusin/focusout动态调整位置
position: fixed 是唯一兜底方案,但必须手动补全所有参数
一旦 sticky 失效或需要兼容旧版 Safari,fixed 就是唯一选择。但它不是加个类就完事——漏掉任意一项,侧边栏就会塌缩、遮挡、滚动失灵。
响应式断点和 z-index 冲突是最容易被忽略的崩坏点
桌面端跑通不代表上线没问题。小屏错位、菜单被遮、滚动卡死,90% 出在断点处理和层叠顺序上。











