I am excited to share my recent experiment with dynamically changing CSS grid layouts using JavaScript. Today, I’m walking you through a simple project that modifies the grid-template-columns
property on the fly. This project not only helped me understand how CSS grids work but also taught me how to interact with DOM elements more effectively. Let’s dive in!
Code Explanation
HTML Structure
I started by creating an HTML structure with a container <div>
that has the class grid-squares
. Inside this container, I placed several child <div>
elements, each with the class grid_item
. One of these items even includes a button with the ID firstButton
—this button is our trigger to change the grid layout.
<div class="grid-squares">
<div class="grid_item">
<h2>Lorem Ipsum</h2>
<button id="firstButton">Learn More</button>
</div>
<div class="grid_item">
<h2>Lorem Ipsum</h2>
</div>
<div class="grid_item">
<h2>Lorem Ipsum</h2>
</div>
<div class="grid_item">
<h2>Lorem Ipsum</h2>
</div>
</div>
CSS Grid Layout
Next, I styled the grid container. The CSS uses display: grid
to define a grid and sets up two columns using grid-template-columns: 1fr 1fr;
. Each grid item is given a fixed height of 300px using grid-auto-rows
, which ensures a consistent look for all items.
.grid-squares {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 300px;
}
JavaScript Functionality
My goal was to change the grid layout when the button is clicked. Initially, I attempted to use the following code:
firstButton = document.getElementById("firstButton")
firstButton.onclick = function(){
squaresGrid = document.getElementsByClassName("grid-squares");
squaresGrid.style.gridTemplateColumns = "1000px";
}
However, I quickly discovered that this throws an error:
“Uncaught TypeError: Cannot set property ‘gridTemplateColumns’ of undefined”
The problem is that document.getElementsByClassName("grid-squares")
returns a collection of elements, not a single element. To fix this, I either accessed the first element in the collection or used document.querySelector
.
Correct Approach using getElementsByClassName:
const firstButton = document.getElementById("firstButton");
firstButton.onclick = function() {
const squaresGrid = document.getElementsByClassName("grid-squares")[0];
squaresGrid.style.gridTemplateColumns = "1000px";
}
Or using querySelector:
const firstButton = document.getElementById("firstButton");
firstButton.onclick = function() {
const squaresGrid = document.querySelector(".grid-squares");
squaresGrid.style.gridTemplateColumns = "1000px";
}
Enhanced Version with Additional Practice Functionality
I decided to expand the project further by adding a few more features to practice with JavaScript and CSS grids. Here’s what I added:
- New Buttons: Two extra buttons to change the grid layout to three or four columns.
- Input Field: An input field for entering a custom grid layout value.
- Display Current Layout: A function that displays the current
grid-template-columns
value on the page.
Complete HTML
<div class="grid-squares">
<div class="grid_item">
<h2>Lorem Ipsum</h2>
<button id="firstButton">Set to 1000px</button>
</div>
<div class="grid_item">
<h2>Lorem Ipsum</h2>
</div>
<div class="grid_item">
<h2>Lorem Ipsum</h2>
</div>
<div class="grid_item">
<h2>Lorem Ipsum</h2>
</div>
</div>
<div class="controls">
<button id="threeColsButton">Three Columns</button>
<button id="fourColsButton">Four Columns</button>
<input type="text" id="customTemplate" placeholder="e.g., 1fr 2fr 1fr" />
<button id="customButton">Apply Custom Layout</button>
<p>Current grid-template-columns: <span id="currentLayout">1fr 1fr</span></p>
</div>
Complete CSS
.grid-squares {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 300px;
gap: 10px;
margin-bottom: 20px;
}
.grid_item {
background-color: #f0f0f0;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #ccc;
}
.controls {
margin-top: 20px;
}
Complete JavaScript
// Function to update the grid layout and display the current setting
function updateGridLayout(newLayout) {
const squaresGrid = document.querySelector(".grid-squares");
squaresGrid.style.gridTemplateColumns = newLayout;
document.getElementById("currentLayout").textContent = newLayout;
}
// Event for the initial button (set a fixed layout)
document.getElementById("firstButton").onclick = function() {
updateGridLayout("1000px");
}
// Event for three columns button
document.getElementById("threeColsButton").onclick = function() {
updateGridLayout("1fr 1fr 1fr");
}
// Event for four columns button
document.getElementById("fourColsButton").onclick = function() {
updateGridLayout("1fr 1fr 1fr 1fr");
}
// Event for applying custom layout from input
document.getElementById("customButton").onclick = function() {
const customValue = document.getElementById("customTemplate").value;
if(customValue.trim() !== "") {
updateGridLayout(customValue);
} else {
alert("Please enter a valid grid template value.");
}
}
How It Works
- updateGridLayout Function:
This helper function takes a string value (like"1fr 1fr 1fr"
) and updates the grid container’sgridTemplateColumns
style accordingly. It also updates the display element to show the current layout. - Event Listeners:
Each button has an event listener that calls theupdateGridLayout
function with a specific layout value. For example, clicking the “Three Columns” button changes the layout to"1fr 1fr 1fr"
. The custom layout button allows you to experiment by typing any valid CSS grid layout value.
This enhanced version not only fixes the original error by ensuring that I’m targeting the right element in the DOM, but it also adds interactive features that make it fun to experiment with different grid layouts.
Final Thoughts
I am thrilled with how this project turned out. It’s a simple yet effective way to see the power of JavaScript and CSS working together. Modifying grid layouts dynamically opens up so many creative possibilities from responsive designs to interactive interfaces. I encourage you to take this code, tweak it, and build upon it. Maybe try adding animations or integrating it with other dynamic content!