纯css即可实现,无需js:左侧设resize: horizontal、overflow: auto、min/max-width及flex-shrink: 0,父容器display: flex,右侧用flex: 1自适应;safari 16.4+支持,ie需降级为js方案。

用 resize + flex 实现可拖拽的固定左栏
直接上结论:纯 CSS 就能实现,不需要 JS 监听鼠标事件。关键不是“固定宽度”,而是让左侧容器支持用户拖拽缩放,同时保持布局稳定。
核心是利用 resize CSS 属性 + overflow: auto 触发可调整行为,再用 flex 布局约束右侧自适应。浏览器原生支持,兼容 Chrome/Firefox/Edge(Safari 16.4+ 支持,旧版需降级处理)。
-
resize: horizontal只能加在有overflow且非visible的块级元素上,所以左侧必须设overflow: auto(哪怕内容不溢出) - 左侧设
min-width和max-width防止拖到过窄或过宽,比如min-width: 200px; max-width: 500px; - 右侧用
flex: 1占满剩余空间,不设宽,避免和拖拽冲突 - 别给左侧设
width: 200px—— 这会锁死初始尺寸,拖拽后可能被 flex 重置;改用flex-basis: 200px更稳妥
resize 不生效?检查这三处
常见现象:拖拽手柄没出现、点了没反应、拖完布局错乱。基本都卡在这几个点:
- 左侧元素没设
overflow: auto或overflow: hidden(visible不触发 resize) - 父容器没设
display: flex,或左侧没设flex-shrink: 0,导致拖宽后被压缩回默认值 - 用了
width覆盖了flex-basis,优先级问题导致拖拽尺寸被覆盖(查 computed style 就能看到)
需要 IE 兼容?只能换 JS 方案
IE 完全不支持 resize,也没 flex 的可靠实现。这时候得退回到 JS 手动计算:
- 监听
mousedown在分隔条上,用document.addEventListener('mousemove')实时更新左侧width内联样式 - 分隔条必须是独立元素(比如
<div class="resizer"></div>),设user-select: none防止误选文本 - 右侧不能靠
flex,得用calc(100% - 左侧宽度)动态算宽,注意单位统一(px vs %) - 务必加
will-change: width提升拖拽流畅度,尤其内容多时
拖拽后状态要持久化?存 localStorage 很简单
用户拖完关页面,下次打开还是默认宽度,体验断层。存一下就行:
- 监听
resize事件(只在左侧元素上,不是 window) - 事件回调里读
element.offsetWidth,写入localStorage.setItem('leftPanelWidth', width) - 初始化时先读
localStorage.getItem('leftPanelWidth'),有值就设为flex-basis或内联width - 注意:
resize事件在 Firefox 中仅对textarea和带overflow的元素触发,Chrome 支持所有块级元素
复杂点在于 Safari 对 resize 的触发时机不一致,有时拖完松手才发事件,有时拖动中连续发。如果要做实时预览(比如显示当前宽度数字),得加防抖,不然频繁读写 DOM 影响性能。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











