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

使用CSS Grid实现棋盘游戏的均匀分布正方形单元格

解决CSS Grid棋盘UI的自适应与比例问题

问题描述

我尝试用CSS Grid创建简单棋盘游戏UI,原本以为这是理想工具,但无法实现以下预期效果:

  • 单元格自动调整尺寸填充父容器
  • 单元格保持1:1宽高比
  • 页面内容不超出浏览器可视窗口范围

试过的方案要么导致内容溢出,要么单元格过高时页面横向扩展,或单元格过宽时页面纵向扩展。

原代码示例

CSS

:root
{
    --col_and_row_count: 10;
}

.main 
{
    display: grid;
    grid-template-rows: 60px 1fr 60px; 
    gap: 1em;
    height: 100vh;
}

.wrapper 
{
    display: grid;
    grid-template-columns: 200px 1fr;
}

.board 
{
    display: flex;
    align-items: center;
}

.tiles 
{
    margin: auto;
    display: grid;
    grid-template-columns: repeat(var(--col_and_row_count), 1fr);
    gap: 12px;
    aspect-ratio: 1; 
}

.tiles > div 
{
    background: green;
       
}

HTML

<div class="main">
    <div>
        Some heading text goes here
    </div>
    <div class="wrapper">
        <div>
            The side bar goes here
        </div>
        <div class="board">
            <div class="tiles">
                <div data-tile-index="0"></div>
                <div data-tile-index="1"></div>
                <div data-tile-index="2"></div>
                <div data-tile-index="3"></div>
                <div data-tile-index="4"></div>
                <div data-tile-index="5"></div>
                <div data-tile-index="6"></div>
                <div data-tile-index="7"></div>
                <div data-tile-index="8"></div>
                <div data-tile-index="9"></div>
                <div data-tile-index="10"></div>
                <div data-tile-index="11"></div>
                <div data-tile-index="12"></div>
                <div data-tile-index="13"></div>
                <div data-tile-index="14"></div>
                <div data-tile-index="15"></div>
                <div data-tile-index="16"></div>
                <div data-tile-index="17"></div>
                <div data-tile-index="18"></div>
                <div data-tile-index="19"></div>
                <div data-tile-index="20"></div>
                <div data-tile-index="21"></div>
                <div data-tile-index="22"></div>
                <div data-tile-index="23"></div>
                <div data-tile-index="24"></div>
                <div data-tile-index="25"></div>
                <div data-tile-index="26"></div>
                <div data-tile-index="27"></div>
                <div data-tile-index="28"></div>
                <div data-tile-index="29"></div>
                <div data-tile-index="30"></div>
                <div data-tile-index="31"></div>
                <div data-tile-index="32"></div>
                <div data-tile-index="33"></div>
                <div data-tile-index="34"></div>
                <div data-tile-index="35"></div>
                <div data-tile-index="36"></div>
                <div data-tile-index="37"></div>
                <div data-tile-index="38"></div>
                <div data-tile-index="39"></div>
                <div data-tile-index="40"></div>
                <div data-tile-index="41"></div>
                <div data-tile-index="42"></div>
                <div data-tile-index="43"></div>
                <div data-tile-index="44"></div>
                <div data-tile-index="45"></div>
                <div data-tile-index="46"></div>
                <div data-tile-index="47"></div>
                <div data-tile-index="48"></div>
                <div data-tile-index="49"></div>
                <div data-tile-index="50"></div>
                <div data-tile-index="51"></div>
                <div data-tile-index="52"></div>
                <div data-tile-index="53"></div>
                <div data-tile-index="54"></div>
                <div data-tile-index="55"></div>
                <div data-tile-index="56"></div>
                <div data-tile-index="57"></div>
                <div data-tile-index="58"></div>
                <div data-tile-index="59"></div>
                <div data-tile-index="60"></div>
                <div data-tile-index="61"></div>
                <div data-tile-index="62"></div>
                <div data-tile-index="63"></div>
                <div data-tile-index="64"></div>
                <div data-tile-index="65"></div>
                <div data-tile-index="66"></div>
                <div data-tile-index="67"></div>
                <div data-tile-index="68"></div>
                <div data-tile-index="69"></div>
                <div data-tile-index="70"></div>
                <div data-tile-index="71"></div>
                <div data-tile-index="72"></div>
                <div data-tile-index="73"></div>
                <div data-tile-index="74"></div>
                <div data-tile-index="75"></div>
                <div data-tile-index="76"></div>
                <div data-tile-index="77"></div>
                <div data-tile-index="78"></div>
                <div data-tile-index="79"></div>
                <div data-tile-index="80"></div>
                <div data-tile-index="81"></div>
                <div data-tile-index="82"></div>
                <div data-tile-index="83"></div>
                <div data-tile-index="84"></div>
                <div data-tile-index="85"></div>
                <div data-tile-index="86"></div>
                <div data-tile-index="87"></div>
                <div data-tile-index="88"></div>
                <div data-tile-index="89"></div>
                <div data-tile-index="90"></div>
                <div data-tile-index="91"></div>
                <div data-tile-index="92"></div>
                <div data-tile-index="93"></div>
                <div data-tile-index="94"></div>
                <div data-tile-index="95"></div>
                <div data-tile-index="96"></div>
                <div data-tile-index="97"></div>
                <div data-tile-index="98"></div>
                <div data-tile-index="99"></div>
            </div>
        </div>
    </div>
    <div>
        This is the footer
    </div>
</div>

解决方案

调整CSS代码,解决溢出、比例和自适应问题:

修改后的CSS

:root {
  --col_and_row_count: 10;
  --tile-gap: 12px;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.main {
  display: grid;
  grid-template-rows: 60px 1fr 60px; 
  gap: 1em;
  height: 100vh;
  overflow: hidden; /* 阻止整体内容超出视口 */
}

.wrapper {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 1em; /* 避免侧边栏与棋盘容器挤压 */
}

.board {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1em; /* 防止棋盘贴边 */
  overflow: hidden; /* 限制棋盘在容器内 */
}

.tiles {
  display: grid;
  grid-template-columns: repeat(var(--col_and_row_count), 1fr);
  gap: var(--tile-gap);
  width: 100%;
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: 1; /* 保持棋盘整体正方形比例 */
}

.tiles > div {
  background: green;
  aspect-ratio: 1; /* 强制每个单元格1:1比例 */
}

关键修改说明

  1. 全局盒模型重置:*选择器设置box-sizing: border-box,确保内边距、边框不会额外增加元素尺寸,从根源避免溢出。
  2. 限制整体视口范围:给.main加overflow: hidden,确保页面内容不会超出浏览器可视窗口。
  3. 优化棋盘容器布局:.board添加justify-content: center让棋盘水平居中,padding防止棋盘贴边,overflow: hidden限制棋盘不会超出容器。
  4. 棋盘自适应与比例控制:.tiles设置width: 100%和max-width/max-height: 100%,让它填充父容器但不超出;保留aspect-ratio:1确保棋盘始终是正方形。
  5. 单元格比例锁定:给每个单元格设置aspect-ratio:1,强制保持1:1宽高比,无论父容器尺寸如何变化都不会变形。

调整后即可实现:单元格自动填充父容器、保持1:1比例、页面内容完全在可视窗口内的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 22:52:05