You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现三列等宽且仅相邻列可拖拽调整宽度的模块化界面?

三列可拖拽分隔布局实现方案

核心思路

解决你问题的关键是固定列的伸缩行为,同时兼顾默认均分和拖拽时仅修改相邻列宽度:

  • 初始状态下,通过calc(100%/3)设置三列宽度均分,同时禁用flex-grow和flex-shrink,避免布局自动调整影响非目标列
  • 拖拽分隔线时,仅修改相邻两列的宽度值,第三列保持初始宽度不变

实现代码

HTML结构

<div class="column-container">
  <div class="column column-1">第一列</div>
  <div class="resizer resizer-1"></div>
  <div class="column column-2">第二列</div>
  <div class="resizer resizer-2"></div>
  <div class="column column-3">第三列</div>
</div>

CSS样式

.column-container {
  display: flex;
  width: 100%;
  height: 400px;
  gap: 0; /* 消除列间默认间隙 */
}

.column {
  flex: 0 0 calc(100%/3); /* flex-grow:0, flex-shrink:0, 初始宽度均分 */
  padding: 10px;
  box-sizing: border-box;
  overflow: auto;
}

.resizer {
  width: 5px;
  background-color: #ddd;
  cursor: col-resize;
  user-select: none; /* 防止拖拽时选中分隔线 */
}

/* 示例列背景色,匹配你的可视化图 */
.column-1 { background-color: #a855f7; }
.column-2 { background-color: #3b82f6; }
.column-3 { background-color: #10b981; }

JavaScript拖拽逻辑

// 通用拖拽处理函数
function setupResizer(resizer, leftColumn, rightColumn) {
  let startX, startLeftWidth, startRightWidth;

  resizer.addEventListener('mousedown', (e) => {
    startX = e.clientX;
    startLeftWidth = leftColumn.offsetWidth;
    startRightWidth = rightColumn.offsetWidth;
    document.addEventListener('mousemove', handleResize);
    document.addEventListener('mouseup', stopResize);
    e.preventDefault(); // 阻止默认行为,避免文本选中
  });

  function handleResize(e) {
    const deltaX = e.clientX - startX;
    // 限制最小宽度,避免列被拖到完全不可见
    const newLeftWidth = Math.max(100, startLeftWidth + deltaX);
    const newRightWidth = Math.max(100, startRightWidth - deltaX);

    leftColumn.style.width = `${newLeftWidth}px`;
    rightColumn.style.width = `${newRightWidth}px`;
  }

  function stopResize() {
    document.removeEventListener('mousemove', handleResize);
    document.removeEventListener('mouseup', stopResize);
  }
}

// 初始化两个分隔线的拖拽功能
setupResizer(
  document.querySelector('.resizer-1'),
  document.querySelector('.column-1'),
  document.querySelector('.column-2')
);

setupResizer(
  document.querySelector('.resizer-2'),
  document.querySelector('.column-2'),
  document.querySelector('.column-3')
);

问题原因说明

  • 使用flex:1时,flex-grow:1会让所有列在空间变化时自动分配剩余宽度,修改某一列的flex-basis会触发整体重排,导致第三列宽度变化
  • 直接用width但未实现默认均分,是因为没有利用calc(100%/3)实现自动适配容器宽度的均分效果

内容的提问来源于stack exchange,提问作者Jonas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 01:40:02