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

如何实现康威生命游戏网页中自适应的正方形单元格表格?

实现康威生命游戏的自适应正方形单元格

我明白你的需求——不管网格有多少行多少列,每个单元格都要保持正方形,并且自适应容器的大小。咱们直接来修改你的代码,解决这个问题:

问题分析

你当前的CSS里,表格设置了70%的宽高,但单元格(td)没有设置保持正方形的规则,所以它们会随着表格的宽高拉伸成矩形,而不是正方形。我们需要给单元格添加固定宽高比的约束,同时让网格整体自适应可用空间。

解决方案

1. 核心CSS修改(实现正方形单元格)

现代浏览器可以直接用aspect-ratio: 1/1强制单元格为正方形;如果需要兼容旧浏览器,可以用padding-top: 100%的技巧(配合相对定位的容器)。这里我们用现代方案,同时保证网格自适应。

2. 调整表格布局

让表格占满可用空间,单元格自动均分宽度,同时保持正方形。

修改后的完整代码

HTML(无需改动,保持原结构)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Conway's Game of Life</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.8.10/brython.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/brython/3.8.10/brython_stdlib.min.js"></script>
<script src="index.js" defer></script>
<link rel="stylesheet" href="index.css">
</head>
<body onload="brython(1)">
<h1 id=test>Conway's Game of Life</h1>
<p>The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970. It is a zero-player game, meaning that its evolution is determined by its initial state, requiring no further input. One interacts with the Game of Life by creating an initial configuration and observing how it evolves. It is Turing complete and can simulate a universal constructor or any other Turing machine. </p>
<table id="board">
</table>
<h2>Rules</h2>
<p>
<ul>
<li>Any live cell with two or three live neighbours survives.</li>
<li>Any dead cell with three live neighbours becomes a live cell.</li>
<li>All other live cells die in the next generation. Similarly, all other dead cells stay dead.</li>
</ul>
</p>
<h2>Patterns</h2>
<h3>Still life</h3>
<h3>Oscillators</h3>
<h3>Spaceships</h3>
</body>
</html>

JavaScript(微调鼠标事件逻辑,避免状态冲突)

function createBoard(height, width){
 console.log("Executing function");
 const table = document.getElementById("board");
 // 先清空表格,避免重复创建
 table.innerHTML = "";
 for (let i=0; i<height;i++){
  const row = document.createElement("tr");
  for (let j=0;j<width;j++){
   const cell = document.createElement("td")
   cell.id = `cell-${i}-${j}`;
   cell.classList.add("cell","death")
   // 绑定点击事件,直接通过class判断当前状态
   cell.onclick = function() {
    const currentClass = this.classList.contains("death") ? "death" : "live";
    changeCellClass(this, currentClass);
   };
   // 统一鼠标悬停/离开逻辑,无需重复绑定
   cell.addEventListener("mouseover", function() {
    this.style.backgroundColor = this.classList.contains("death") ? "yellowgreen" : "darkcyan";
   });
   cell.addEventListener("mouseleave", function() {
    this.style.backgroundColor = this.classList.contains("death") ? "darkcyan" : "yellowgreen";
   });
   row.appendChild(cell);
  }
  table.appendChild(row)
 }
}
function changeCellClass(cell, currentClass){
 console.log(cell.id, currentClass);
 cell.classList.remove(currentClass);
 if(currentClass === "death"){
  cell.classList.add("live");
  cell.style.backgroundColor = "yellowgreen";
  console.log(`${cell.id} has changed to live`);
 }else{
  cell.classList.add("death");
  cell.style.backgroundColor = "darkcyan";
  console.log(`${cell.id} has changed to death`);
 }
}
// 可随意修改行列数,单元格都会保持正方形
createBoard(50,50);

CSS(关键修改:实现自适应正方形单元格)

/* 确保页面根元素占满视口,给表格提供可用空间 */
html, body {
 height: 100%;
 margin: 0;
 padding: 0 1rem;
 box-sizing: border-box;
}

table{
 /* 表格占满可用宽度,高度由单元格正方形比例自动决定 */
 width: 100%;
 max-width: 90vh; /* 限制最大高度,避免超出视口 */
 margin: 2rem auto;
 border-collapse: collapse;
 /* 让列宽自动均分,保证单元格大小一致 */
 table-layout: fixed;
}

td {
 border: 1px solid black;
 /* 核心:强制单元格为正方形 */
 aspect-ratio: 1/1;
 padding: 0;
 /* 状态切换添加平滑过渡 */
 transition: background-color 0.2s ease;
}

.death{
 background-color: darkcyan;
}
.live{
 background-color: yellowgreen;
}

p{
 text-align: justify;
 max-width: 800px;
 margin: 1rem auto;
}

h1, h2, h3 {
 text-align: center;
}

关键修改说明

  1. CSS部分:
    • aspect-ratio: 1/1是实现正方形的核心,强制单元格宽高比为1:1,无论网格行列数多少都能保持正方形。
    • table-layout: fixed让表格列宽自动均分,确保所有单元格大小一致。
    • max-width: 90vh避免网格过高超出视口,同时保持自适应宽度。
  2. JavaScript部分:
    • 优化了状态判断逻辑,直接通过classList.contains获取当前状态,避免闭包变量问题。
    • 统一鼠标事件逻辑,减少重复绑定的冗余代码,让状态切换更稳定。

现在你可以尝试修改createBoard的参数(比如改成20x20或者100x100),所有单元格都会自动调整为正方形,并且自适应页面空间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:01:06