resize 属性需同时满足 display 为块级/弹性/网格布局且 overflow 为 auto/scroll/hidden 才生效;textarea 虽原生支持但不适合作为布局容器;整边拖拽需借助 webkit 滚动条 hack;resize 不触发 css 变量更新,须监听 mouseup 并手动同步。

resize 属性本身不能直接让 div 自由拖拽改变大小——它只在满足特定渲染条件时才生效,否则浏览器会静默忽略。
为什么给 div 直接写 resize: both 没反应
根本原因是:浏览器只对「能产生滚动框」的块级元素启用 resize,且必须同时满足两个硬性条件:
-
display值为block、inline-block、flex、grid等(不能是inline或table) -
overflow值为auto、scroll或hidden(visible无效)
常见错误是只加 resize: horizontal 却漏了 overflow: auto,结果右下角手柄根本不出现。推荐起步组合:overflow: auto; resize: both; —— 它最稳妥,内容溢出即自动触发滚动,手柄立刻可见。
textarea 能直接用,但别拿来当布局容器
textarea 是少数开箱即用支持 resize 的元素,默认就是 resize: both。但它不是布局解决方案:
- 它默认可聚焦、可输入、有换行逻辑,需额外加
readonly、user-select: none、border: none掩盖,代码更重 - 拖拽过程中连续触发
input事件,容易引发重绘抖动 - 无法可靠限制方向(比如
resize: horizontal在 Safari 中仍可能被垂直触发) - 后续想加边界约束、等比缩放或拖动移动功能时,必须重写,扩展性差
除非是极简内部工具且仅作占位器,否则不建议用 textarea 替代 div 做布局拖拽。
如何让整条边都可拖拽(比如左右分栏)
原生 resize 手柄固定在右下角,无法移动或放大。但可以利用 WebKit 下 ::-webkit-scrollbar 与 resize 共享底层机制的特点,间接扩大拖拽区域:
- 把一个透明的
div设为resize: horizontal,并设overflow: scroll - 用
::-webkit-scrollbar把它的滚动条宽度拉大到 200px,这样整个右侧 200px 区域都变成可拖拽区 - 将该
div绝对定位在左右栏交界处,左半部分遮住,右半部分透出作为“拖拽线” - 配合
cursor: ew-resize和伪元素画一条视觉分隔线,提升可用性
注意:Firefox 不支持 ::-webkit-scrollbar,需用 @supports (-moz-user-select: none) 提供降级样式,否则只有右下角小三角可用。
resize 改了尺寸,但 CSS 变量没更新怎么办
resize 是纯渲染层行为,它直接改的是元素的内联 style="width: 320px",不会触发任何事件,也不会同步到自定义属性(如 --panel-width)。所以如果你用 calc(100% - var(--panel-width)) 布局右侧区域,它不会响应变化。
正确做法是在用户松手那一刻(mouseup)读取并写入:
- 监听目标
div的mouseup事件(不是window.resize,那是窗口事件) - 用
element.offsetWidth读取当前宽度(比getBoundingClientRect().width更快、无四舍五入误差) - 用
element.style.setProperty('--panel-width', w + 'px')写入变量,确保作用域局部 - 如有
min-width/max-width,先通过getComputedStyle校验合法范围,避免变量值越界
真正容易被忽略的点是:你看到的“拖拽中实时变化”,其实只是浏览器渲染层在改内联样式;所有依赖 CSS 变量的响应式布局,都必须靠这一步 JS 同步才能生效。没有这一步,resize 就只是个视觉玩具。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











