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

基于display:grid的可拖拽滚动元素:适配可变可见项数量

Grid布局无法左右滚动的原因及修复方案

问题原因

  • Grid列自适应收缩:.bottom容器用grid-template: auto / auto auto auto auto auto auto auto定义列,Grid默认会收缩列宽以适配容器的100vw宽度,导致子元素设置的宽度被覆盖,容器不会产生横向溢出,无法触发左右滚动。
  • Overflow属性错误:.bottom设置overflow:hidden,既隐藏了溢出内容,也未明确开启横向滚动支持。
  • 拖拽逻辑冗余:JS中对event.movementX正负值的判断重复,代码可以简化。

修复步骤

1. 调整Grid容器配置,允许横向溢出

修改.bottom的CSS,强制列宽不收缩,并开启滚动:

.bottom {
  width: 100vw;
  height: 100vh;
  display: grid;
  /* 用repeat+minmax强制列宽为计算值,禁止收缩 */
  grid-template-columns: repeat(7, minmax(calc(100vw / 7), auto));
  /* 允许横向、纵向滚动 */
  overflow: auto;
  user-select: none;
}

2. 修正媒体查询的布局逻辑

在窄屏(宽高比<1)时切换为6列布局,无需单独设置子元素宽度:

@media (max-aspect-ratio: 1/1) {
  .bottom {
    grid-template-columns: repeat(6, minmax(calc(100vw / 6), auto));
  }
}

3. 简化拖拽交互逻辑

合并重复判断,优化代码:

var element = document.getElementById('bottom');

element.addEventListener("mousemove", function(event) {
  if (event.buttons !== 1) return;
  
  if (Math.abs(event.movementX) > Math.abs(event.movementY)) {
    element.scrollLeft -= event.movementX;
  } else {
    element.scrollTop -= event.movementY;
  }
});

4. 移除冗余的子元素宽度

删除.div类中的width:25vw,避免与Grid列定义冲突:

.div {
  height: 25vh;
}

完整修复代码

HTML

<body>
  <div class="bottom" id="bottom">
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>

    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>

    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>

    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>

    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>

    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
    <div class="div yellow"></div>
    <div class="div white"></div>
  </div>
</body>

CSS

body {
  background: #046;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.bottom {
  width: 100vw;
  height: 100vh;
  display: grid;
  grid-template-columns: repeat(7, minmax(calc(100vw / 7), auto));
  overflow: auto;
  user-select: none;
}

.yellow {
  background: yellow;
}

.white {
  background: white;
}

.div {
  height: 25vh;
}

@media (max-aspect-ratio: 1/1) {
  .bottom {
    grid-template-columns: repeat(6, minmax(calc(100vw / 6), auto));
  }
}

JS

var element = document.getElementById('bottom');

element.addEventListener("mousemove", function(event) {
  if (event.buttons !== 1) return;
  
  if (Math.abs(event.movementX) > Math.abs(event.movementY)) {
    element.scrollLeft -= event.movementX;
  } else {
    element.scrollTop -= event.movementY;
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 05:35:11