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

如何避免窄屏上Flexbox六边形网格元素溢出?

窄屏(手机分辨率)下Flexbox六边形网格无法居中且溢出容器的解决问题

问题描述

在窄屏(手机分辨率)下,Flexbox布局的六边形元素无法居中,且会溢出Flex容器。希望整个六边形网格能自动缩小适配窄屏,而非从屏幕侧边溢出。

  • 当前效果:六边形网格在手机屏幕上横向溢出,无法完全显示,也未居中
  • 预期效果:六边形网格完整适配手机屏幕宽度,居中显示,所有六边形均在可视范围内

代码片段

JavaScript

function renderHexGrid() {
  let hexArray = [
    ['v', 'v', 'v', '_', '_', '_', 'v', 'v', 'v'],
    ['v', '_', '_', '_', '_', '_', '_', '_', 'v'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['v', 'v', '_', '_', '_', '_', '_', 'v', 'v'],
    ['v', 'v', 'v', 'v', '_', 'v', 'v', 'v', 'v']
  ]
  const hexWidth = 7
  const hexHeight = 6
  const hexGrid = document.getElementById("hex-grid")
  for (let i = 0; i < hexArray.length; i++) {
    let hexRow = document.createElement("div")
    hexRow.style.display = "flex"
    hexRow.style.justifyContent = "center"
    for (let j = 0; j < hexArray[i].length; j++) {
      if (hexArray[i][j] != 'v') {
        let hex = document.createElement("div")
        hex.style.display = "flex";
        hex.style.justifyContent = "center"
        hex.style.alignItems = "center"
        if (j % 2 == 0) {
          hex.style.transform = "translateY(-" + hexHeight / 2 + "vh)"
          hex.style.backgroundColor = "red"
        } else {
          hex.style.backgroundColor = "blue"
        }
        if (i % 2 == 0) {
          hex.style.opacity = 0.5
        }
        hex.style.height = hexHeight + "vh"
        hex.style.width = hexWidth + "vh"
        hex.textContent = i + ";" + j
        hex.color = "black"
        hex.style.marginLeft = "-" + hexWidth / 8 + "vh"
        hex.style.marginRight = "-" + hexWidth / 8 + "vh"
        hex.style.clipPath = "polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%)"
        hexRow.appendChild(hex);
      }
    }
    hexGrid.appendChild(hexRow);
  }
}
renderHexGrid()

CSS

* {
  margin: 0;
  padding: 0;
}

body {
  margin: 5%;
  width: 90%;
  min-height: 90vh;
  background-color: rgb(255, 255, 255);
  display: flex;
  align-items: center;
  justify-content: center;
}

HTML

<div id="hex-grid"></div>

解决方案

问题根源

当前使用vh(视口高度)作为六边形尺寸单位,窄屏场景下横向宽度无法自动适配视口宽度,导致总宽度溢出;同时未给网格容器设置约束,也缺乏响应式缩放逻辑。

具体修改步骤

1. 优化容器约束(CSS)

给网格容器添加宽度限制,确保不会溢出视口,同时修正盒模型计算逻辑:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box; /* 确保margin/padding不额外占用宽度 */
}

body {
  min-height: 100vh;
  padding: 5%; /* 用padding替代margin,避免容器偏移 */
  background-color: rgb(255, 255, 255);
  display: flex;
  align-items: center;
  justify-content: center;
}

#hex-grid {
  width: 100%;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--hex-height) / 2); /* 匹配六边形垂直偏移间距 */
}

2. 动态计算响应式尺寸(JavaScript)

改用vw(视口宽度)作为尺寸单位,根据每行六边形数量自动计算大小,添加窗口 resize 监听保证适配性:

function renderHexGrid() {
  let hexArray = [
    ['v', 'v', 'v', '_', '_', '_', 'v', 'v', 'v'],
    ['v', '_', '_', '_', '_', '_', '_', '_', 'v'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['_', '_', '_', '_', '_', '_', '_', '_', '_'],
    ['v', 'v', '_', '_', '_', '_', '_', 'v', 'v'],
    ['v', 'v', 'v', 'v', '_', 'v', 'v', 'v', 'v']
  ];

  // 计算每行最多的六边形数量
  const maxHexPerRow = Math.max(...hexArray.map(row => row.filter(item => item !== 'v').length));
  // 基于视口宽度动态计算六边形尺寸,留出间隙
  const hexWidth = Math.floor((90 / maxHexPerRow) * 0.8);
  const hexHeight = Math.floor(hexWidth * 0.857); // 保持6:7的六边形宽高比

  // 设置CSS变量统一管理尺寸
  document.documentElement.style.setProperty('--hex-width', `${hexWidth}vw`);
  document.documentElement.style.setProperty('--hex-height', `${hexHeight}vw`);

  const hexGrid = document.getElementById("hex-grid");
  hexGrid.innerHTML = ''; // 清空容器避免重复渲染

  for (let i = 0; i < hexArray.length; i++) {
    let hexRow = document.createElement("div");
    hexRow.style.display = "flex";
    hexRow.style.justifyContent = "center";
    hexRow.style.width = "100%"; // 约束行宽度不超过父容器

    for (let j = 0; j < hexArray[i].length; j++) {
      if (hexArray[i][j] != 'v') {
        let hex = document.createElement("div");
        hex.style.display = "flex";
        hex.style.justifyContent = "center";
        hex.style.alignItems = "center";
        hex.style.color = "black"; // 修正原代码无效的color设置

        if (j % 2 == 0) {
          hex.style.transform = `translateY(-${hexHeight / 2}vw)`;
          hex.style.backgroundColor = "red";
        } else {
          hex.style.backgroundColor = "blue";
        }
        if (i % 2 == 0) {
          hex.style.opacity = 0.5;
        }

        hex.style.height = `var(--hex-height)`;
        hex.style.width = `var(--hex-width)`;
        hex.textContent = `${i};${j}`;
        // 基于当前宽度比例设置重叠margin
        hex.style.marginLeft = `-${hexWidth * 0.125}vw`;
        hex.style.marginRight = `-${hexWidth * 0.125}vw`;
        hex.style.clipPath = "polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%)";
        
        hexRow.appendChild(hex);
      }
    }
    hexGrid.appendChild(hexRow);
  }
}

// 监听窗口大小变化,重新渲染适配
window.addEventListener('resize', renderHexGrid);
renderHexGrid();

3. 关键修改说明

  • 单位切换:从vh改为vw,优先适配横向视口宽度,避免窄屏溢出;
  • 动态尺寸:根据每行六边形数量自动计算尺寸,确保总宽度不超过屏幕;
  • 容器约束:给#hex-grid设置宽度限制,保证网格不会超出父容器;
  • 响应式适配:添加窗口 resize 监听,屏幕尺寸变化时自动重新渲染;
  • 样式修复:修正原代码中无效的文字颜色设置。

内容的提问来源于stack exchange,提问作者Snakučipi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 16:15:15