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

CSS Grid实现Etch-A-Sketch:列可调整但行数不变问题求助

问题:Etch-A-Sketch网格行数量不随输入变化,单元格呈矩形

正在完成The Odin Project基础课程的Etch-A-Sketch项目,初始为16×16网格,预期网格单元格数量随用户输入变化,但当前列数会更新,行数始终固定为16(比如输入32时变成32列×16行),导致单元格为矩形而非正方形。尝试修改#container的CSS Grid属性未解决问题,求排查修复。


现有代码

HTML

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1"> 
        <title>Etch-A-Sketch.</title>
        <link rel="stylesheet" href="style.css">
    </head>

    <body>
     
        <div id="title">
            <h1>Etch-A-Sketch. &#128397</h1>
        </div>
        

        <div id="buttons">
            <button id="gridsize">Size</button>
            <button id="rainbow">Rainbow</button>
        </div>
        

        <div id="container"></div>

        <div id="tipmessage">
            <h3><em>'We don't make mistakes, just happy little accidents' - Bob Ross</em></h3>
        </div>

    </body>

    <script src="script.js" defer></script>

</html>

CSS

#container {
    margin-top: 25px;
    display: inline-grid;
    grid-template-columns: repeat(16, 1fr);
    grid-template-rows: auto;
    border: 7.5px solid black;
    border-radius: 10px;
    height: 575px;
    width: 575px;
    box-sizing: border-box;
}

.cell {
   border: 1px solid black;
   box-sizing: border-box;
}

#title {
    display: flex;
    background-color: crimson;
    justify-content: center;
    width: 270px;
    height: 72px;
    margin-left: 815px;
    margin-top: 50px;
    border-style: solid aqua;
    border-radius: 35px;
    font-size: small;
}

#buttons {
    display: flex;
    justify-content: center;
    gap: 75px;
    margin-top: 40px;
}

#gridsize {
    background: black;
    color: white;
    border: none;
    width: 100px;
    height: 30px;
    font-size: large;
    border-radius: 20px;
    font-weight: bold;
}

#rainbow {
    background: black;
    color: white;
    border: none;
    width: 100px;
    font-size: large;
    font-weight: bold;
    border-radius: 20px;
}

#tipmessage {
    text-align: center;
    margin-top: 40px;
}

html {
    background-color: snow;
    text-align: center;
    font-family: Arial, Helvetica, sans-serif;
}

JavaScript

const container = document.querySelector("#container");
const buttonSize = document.querySelector("#gridsize");
const buttonRainbow = document.querySelector("#gridsize");
let cell = document.querySelectorAll('.cell');
let cellAmount = 16;
window.onload = createGrid(cellAmount);
cell.onmouseover = mouseOver();

// creates a 16x16 grid
function createGrid(e){
    for (let i = 0; i < e*e; i++){
        const div = document.createElement("div");
        div.classList.add("cell");
        container.appendChild(div);
    }
}

// changes cell colors to black on mouseover
function mouseOver(){
    let cell = document.querySelectorAll('.cell');
    cell.forEach((cell) => {
        cell.addEventListener('mouseover', function(){
            cell.style.background = "black";
        })
    })
}

// resizes the grid and resets sketch
buttonSize.addEventListener('click', () => {
    for (i = 0; i < cell.length; i++){
        cell[i].style.removeProperty("black")
    } 
        let userAmount = prompt("Select your pixel size (Default: 16)");
        if (userAmount == ""){
            userAmount == 16;
        }
        while (parseInt(userAmount) < 4 || parseInt(userAmount) > 100){
            userAmount = prompt("Sorry, please enter a number between 4 and 100.");
        }
        cellAmount = parseInt(userAmount);
        while (container.hasChildNodes()){
            container.removeChild(container.firstChild);
        }
        createGrid(cellAmount);
        mouseOver();
});

问题根源与修复方案

1. 核心问题:CSS网格配置固定

#container的grid-template-columns写死为repeat(16, 1fr),grid-template-rows设为auto,导致行数不会随单元格数量动态调整。必须通过JavaScript同步更新网格的行列配置。

2. 次要代码问题

  • buttonRainbow错误绑定到#gridsize按钮,应改为document.querySelector("#rainbow")
  • window.onload = createGrid(cellAmount)会直接执行函数并赋值返回值,需改为箭头函数延迟执行
  • cell.onmouseover = mouseOver()同理,且初始cell为空,无需这行代码
  • 重置颜色时style.removeProperty("black")语法错误,应清空背景色样式

修改后的代码

JavaScript
const container = document.querySelector("#container");
const buttonSize = document.querySelector("#gridsize");
const buttonRainbow = document.querySelector("#rainbow");
let cellAmount = 16;

window.onload = () => createGrid(cellAmount);

// 创建对应尺寸的网格
function createGrid(size){
    // 动态更新网格行列配置
    container.style.gridTemplateColumns = `repeat(${size}, 1fr)`;
    container.style.gridTemplateRows = `repeat(${size}, 1fr)`;
    
    for (let i = 0; i < size * size; i++){
        const div = document.createElement("div");
        div.classList.add("cell");
        container.appendChild(div);
    }
    mouseOver();
}

// 鼠标悬停事件绑定
function mouseOver(){
    let cells = document.querySelectorAll('.cell');
    cells.forEach((cell) => {
        cell.removeEventListener('mouseover', handleMouseOver);
        cell.addEventListener('mouseover', handleMouseOver);
    })
}

// 单独抽离事件处理函数,避免重复绑定
function handleMouseOver(){
    this.style.background = "black";
}

// 调整网格尺寸逻辑
buttonSize.addEventListener('click', () => {
    // 清空所有单元格背景色
    let cells = document.querySelectorAll('.cell');
    cells.forEach(cell => {
        cell.style.backgroundColor = "";
    });
    
    let userAmount = prompt("Select your pixel size (Default: 16)");
    if (userAmount === ""){
        userAmount = 16;
    }
    while (parseInt(userAmount) < 4 || parseInt(userAmount) > 100){
        userAmount = prompt("Sorry, please enter a number between 4 and 100.");
    }
    cellAmount = parseInt(userAmount);
    
    // 清空容器
    while (container.hasChildNodes()){
        container.removeChild(container.firstChild);
    }
    createGrid(cellAmount);
});
CSS(仅修改#container部分)
#container {
    margin-top: 25px;
    display: inline-grid;
    border: 7.5px solid black;
    border-radius: 10px;
    height: 575px;
    width: 575px;
    box-sizing: border-box;
}

修改后,用户输入任意合法数值时,网格会同步设置对应行列数,单元格保持正方形,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:55:35