
本文详细介绍了如何使用CSS Grid技术,结合JavaScript动态创建并管理一个可变尺寸的方格网格,以适应用户输入。通过利用CSS自定义属性和Grid布局的`repeat()`函数,我们能够轻松实现一个响应式的`N x N`正方形网格,避免了Flexbox在处理二维布局时可能遇到的复杂性,特别适用于“Etch A Sketch”类应用。
在Web开发中,创建动态且响应式的网格布局是一个常见需求,尤其是在构建交互式应用如“Etch A Sketch”时。当需要根据用户输入生成一个N x N的方格网格,并且每个方格都能自动调整大小以填充容器时,CSS Grid提供了一种强大而简洁的解决方案。
最初尝试使用Flexbox来创建N x N的方格网格时,开发者可能会遇到一些挑战。例如,如果将容器设置为display: flex并给子元素设置flex-basis: 100%,即使开启flex-wrap: wrap,每个子元素也会占据容器的全部宽度,导致生成的是一列列的矩形,而非期望中的正方形网格。这是因为Flexbox主要设计用于一维布局(行或列),虽然可以通过一些技巧模拟二维布局,但对于严格的N x N方格布局,CSS Grid无疑是更直接和高效的选择。
CSS Grid专为二维布局而生,能够同时控制行和列。结合CSS自定义属性(CSS Custom Properties)和JavaScript,我们可以轻松实现动态的方格网格。
立即学习“前端免费学习笔记(深入)”;
首先,我们需要一个容器来承载我们的网格,以及一个用户输入表单来获取网格尺寸。
<div class="header">
<h1>Etch A Sketch</h1>
<div class="buttons">
<button class="clear">清除</button>
<form id="inputForm">
<input type="number" class="number" min="1" max="64" placeholder="输入一个数字 1-64">
<input type="submit" value="生成网格">
</form>
</div>
</div>
<div id="gridContainer">
<!-- 网格单元将由JavaScript动态生成 -->
</div>这里,#gridContainer将作为我们的CSS Grid容器,其内部的网格单元(div)将由JavaScript根据用户输入动态创建。
核心的CSS样式在于#gridContainer。我们将利用CSS自定义属性--num来存储网格的边长,并通过JavaScript动态更新它。
body {
background-color: #f0f0f0;
min-height: 100vh;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
margin: 0;
}
h1 {
margin: 0;
color: #333;
}
#gridContainer {
/* 定义一个CSS自定义属性,默认值为1,用于控制网格的行列数 */
--num: 1;
width: 50vw; /* 网格容器宽度 */
height: 50vw; /* 网格容器高度,保持与宽度一致以确保方格 */
background-color: white;
border: 1px solid #ccc;
display: grid; /* 启用CSS Grid布局 */
/* 动态创建网格列:repeat(var(--num), 1fr) 表示创建var(--num)列,每列等宽 */
grid-template-columns: repeat(var(--num), 1fr);
/* 动态创建网格行:repeat(var(--num), 1fr) 表示创建var(--num)行,每行等高 */
grid-template-rows: repeat(var(--num), 1fr);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.grid {
/* 网格单元样式 */
border: 1px solid #eee; /* 用于区分每个方格的边框 */
box-sizing: border-box; /* 确保边框不增加元素总尺寸 */
/* 调试时可开启以下样式,方便观察网格单元 */
/* outline: 1px solid blue; */
}
.header {
display: flex;
flex-direction: column;
margin-bottom: 20px;
width: clamp(300px, 80%, 800px); /* 响应式宽度 */
text-align: center;
font-size: 20px;
}
.buttons {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
.buttons button, .buttons input[type="submit"] {
padding: 8px 15px;
border: none;
border-radius: 5px;
background-color: #007bff;
color: white;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s ease;
}
.buttons button:hover, .buttons input[type="submit"]:hover {
background-color: #0056b3;
}
.buttons input[type="number"] {
padding: 8px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
width: 120px;
}关键点在于#gridContainer的display: grid;以及grid-template-columns和grid-template-rows属性。repeat(var(--num), 1fr)表示创建一个由--num个等宽(1fr)列和等高行组成的网格。1fr单位会根据可用空间自动分配,确保所有网格单元在各自维度上大小相等。
JavaScript负责处理用户输入,动态设置CSS自定义属性,并生成相应数量的网格单元。
var form = document.getElementById("inputForm");
var gridContainer = document.getElementById("gridContainer");
var clearButton = document.querySelector(".clear");
// 初始化网格(可选,可以在页面加载时生成一个默认网格)
// createGrid(16); // 例如,默认生成一个16x16的网格
form.addEventListener("submit", function(e) {
e.preventDefault(); // 阻止表单默认提交行为
var inputElement = form.querySelector("input[type='number']");
var num = inputElement.valueAsNumber; // 获取数字类型的输入值
// 验证输入值是否在有效范围内
if (isNaN(num) || num < 1 || num > 64) {
alert("请输入一个介于1到64之间的有效数字!");
return;
}
createGrid(num);
});
clearButton.addEventListener("click", function() {
// 清除所有网格单元,但不改变网格大小
var gridCells = gridContainer.querySelectorAll(".grid");
gridCells.forEach(cell => cell.style.backgroundColor = ''); // 或者设置为初始背景色
});
function createGrid(num) {
// 清空现有网格内容
gridContainer.innerHTML = "";
// 计算总的方格数量
var totalBoxes = num * num;
// 通过JavaScript更新CSS自定义属性--num
gridContainer.style.setProperty('--num', num);
// 动态创建并添加网格单元
for (var i = 0; i < totalBoxes; i++) {
var div = document.createElement("div");
div.className = "grid";
// 添加交互,例如鼠标悬停改变背景色
div.addEventListener("mouseover", function() {
this.style.backgroundColor = "black";
});
gridContainer.appendChild(div);
}
}
// 页面加载时生成一个默认网格,例如16x16
document.addEventListener("DOMContentLoaded", () => {
createGrid(16);
});这段JavaScript代码的核心功能包括:
将上述HTML、CSS和JavaScript代码组合在一起,即可实现一个功能完整的动态方格网格。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动态CSS Grid方格布局</title>
<style>
body {
background-color: #f0f0f0;
min-height: 100vh;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
margin: 0;
}
h1 {
margin: 0;
color: #333;
}
#gridContainer {
--num: 1; /* 定义一个CSS自定义属性,默认值为1 */
width: 50vw; /* 网格容器宽度 */
height: 50vw; /* 网格容器高度,保持与宽度一致以确保方格 */
background-color: white;
border: 1px solid #ccc;
display: grid; /* 启用CSS Grid布局 */
grid-template-columns: repeat(var(--num), 1fr); /* 动态创建网格列 */
grid-template-rows: repeat(var(--num), 1fr); /* 动态创建网格行 */
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.grid {
border: 1px solid #eee; /* 用于区分每个方格的边框 */
box-sizing: border-box; /* 确保边框不增加元素总尺寸 */
/* outline: 1px solid blue; */ /* 调试时可开启 */
}
.header {
display: flex;
flex-direction: column;
margin-bottom: 20px;
width: clamp(300px, 80%, 800px);
text-align: center;
font-size: 20px;
}
.buttons {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
.buttons button, .buttons input[type="submit"] {
padding: 8px 15px;
border: none;
border-radius: 5px;
background-color: #007bff;
color: white;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s ease;
}
.buttons button:hover, .buttons input[type="submit"]:hover {
background-color: #0056b3;
}
.buttons input[type="number"] {
padding: 8px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
width: 120px;
}
</style>
</head>
<body>
<div class="header">
<h1>Etch A Sketch</h1>
<div class="buttons">
<button class="clear">清除</button>
<form id="inputForm">
<input type="number" class="number" min="1" max="64" placeholder="输入一个数字 1-64">
<input type="submit" value="生成网格">
</form>
</div>
</div>
<div id="gridContainer">
<!-- 网格单元将由JavaScript动态生成 -->
</div>
<script>
var form = document.getElementById("inputForm");
var gridContainer = document.getElementById("gridContainer");
var clearButton = document.querySelector(".clear");
form.addEventListener("submit", function(e) {
e.preventDefault(); // 阻止表单默认提交行为
var inputElement = form.querySelector("input[type='number']");
var num = inputElement.valueAsNumber; // 获取数字类型的输入值
// 验证输入值是否在有效范围内
if (isNaN(num) || num < 1 || num > 64) {
alert("请输入一个介于1到64之间的有效数字!");
return;
}
createGrid(num);
});
clearButton.addEventListener("click", function() {
// 清除所有网格单元的背景色
var gridCells = gridContainer.querySelectorAll(".grid");
gridCells.forEach(cell => cell.style.backgroundColor = '');
});
function createGrid(num) {
// 清空现有网格内容
gridContainer.innerHTML = "";
// 计算总的方格数量
var totalBoxes = num * num;
// 通过JavaScript更新CSS自定义属性--num
gridContainer.style.setProperty('--num', num);
// 动态创建并添加网格单元
for (var i = 0; i < totalBoxes; i++) {
var div = document.createElement("div");
div.className = "grid";
// 添加交互:鼠标悬停时改变背景色
div.addEventListener("mouseover", function() {
this.style.backgroundColor = "black";
});
gridContainer.appendChild(div);
}
}
// 页面加载时生成一个默认网格,例如16x16
document.addEventListener("DOMContentLoaded", () => {
createGrid(16);
});
</script>
</body>
</html>通过本教程,您应该能够掌握如何利用CSS Grid和JavaScript的强大组合,创建出高度动态且响应式的方格网格布局,这在许多Web应用开发场景中都非常实用。
以上就是利用CSS Grid实现动态可变尺寸的网格布局的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号