It's Christmas, get a 30% OFF. Apply code XMAS at checkout.
Good Monday everyone! Today, we’re going to learn how to create a masonry grid layout using Tailwind CSS and JavaScript.
A masonry grid layout is a type of grid layout where items are arranged in a two-dimensional grid, but unlike a standard grid where items are placed in strict rows and columns, a masonry grid places items in a staggered fashion. This helps fill in the vertical gaps and makes the layout look more fluid and dynamic.
This technique is widely used for presenting image galleries or content-heavy websites because it provides a visually engaging, organized layout without wasting space. You’ll often see it on popular websites like Pinterest, Dribbble, and Behance.
You might be wondering: why not just use CSS for this? Well, CSS does have a property for this layout, display: masonry;
, which aims to solve this exact problem. However, as of now, it’s still an experimental feature. It is not fully supported across all browsers and lacks consistent performance, especially in responsive designs where content needs to adapt dynamically.
Since native CSS display: masonry;
is experimental, using JavaScript ensures that the grid layout works consistently across all browsers…
As you can see below, the HTML structure is simple. Instead of manually adding all the images, we’ll use a component to pass the images dynamically as props.
ID’s
<div
id="masonry-grid">
{
heroImages.map((imagePath) => (
<img
src={imagePath}
class="rounded-2xl"
alt="#_"
/>
))
}
</div>
Now that we have the HTML ridiculously simple structure ready, let’s start writing the JavaScript part.
const masonryGrid = document.getElementById("masonry-grid");
: This is the variable that will be used to target the masonry grid container.const columnWidth = 300;
: This is the variable that will be used to set the column width of the masonry grid.const gap = 18;
: This is the variable that will be used to set the gap between the images in the masonry grid.const masonryGrid = document.getElementById("masonry-grid");
const columnWidth = 300;
const gap = 18;
function createMasonryGrid()
: This is the function that will be used to create the masonry grid.const gridWidth = masonryGrid.offsetWidth;
: This is the variable that will be used to get the width of the masonry grid.const columns = Math.floor(gridWidth / columnWidth) || 1;
: This is the variable that will be used to calculate the number of columns in the masonry grid.masonryGrid.style.columnCount = columns.toString();
: This is the line that will be used to set the column count of the masonry grid.masonryGrid.style.columnGap =
${gap}px;
: This is the line that will be used to set the column gap of the masonry grid.masonryGrid.style.display = "block";
: This is the line that will be used to set the display of the masonry grid.masonryGrid.style.gridTemplateColumns = "";
: This is the line that will be used to clear the grid template columns of the masonry grid.masonryGrid.style.gridTemplateRows = "";
: This is the line that will be used to clear the grid template rows of the masonry grid.const items = Array.from(masonryGrid.children);
: This is the line that will be used to get the children of the masonry grid.items.forEach((item) => {
: This is the line that will be used to iterate over the children of the masonry grid.item.style.gridRowStart = "";
: This is the line that will be used to clear the grid row start of the masonry grid.item.style.gridColumnStart = "";
: This is the line that will be used to clear the grid column start of the masonry grid.item.style.breakInside = "avoid";
: This is the line that will be used to set the break inside property of the masonry grid.item.style.marginBottom =
${gap}px;
: This is the line that will be used to set the margin bottom of the masonry grid.createMasonryGrid();
: This is the line that will be used to call the createMasonryGrid function.window.addEventListener("resize", createMasonryGrid);
: This is the line that will be used to add a resize event listener to the window.window.addEventListener("load", createMasonryGrid);
: This is the line that will be used to add a load event listener to the window.window.addEventListener("resize", createMasonryGrid);
window.addEventListener("load", createMasonryGrid);
const observer = new MutationObserver(createMasonryGrid);
: This is the line that will be used to create a new MutationObserver object.observer.observe(masonryGrid, {childList: true, subtree: true});
: This is the line that will be used to observe the masonry grid.const observer = new MutationObserver(createMasonryGrid);
observer.observe(masonryGrid, {
childList: true,
subtree: true
});
function createMasonryGrid() {
const gridWidth = masonryGrid.offsetWidth;
const columns = Math.floor(gridWidth / columnWidth) || 1;
masonryGrid.style.columnCount = columns.toString();
masonryGrid.style.columnGap = `${gap}px`;
masonryGrid.style.display = "block";
masonryGrid.style.gridTemplateColumns = "";
masonryGrid.style.gridTemplateRows = "";
const items = Array.from(masonryGrid.children);
items.forEach((item) => {
item.style.gridRowStart = "";
item.style.gridColumnStart = "";
item.style.breakInside = "avoid";
item.style.marginBottom = `${gap}px`;
});
}
const masonryGrid = document.getElementById("masonry-grid");
const columnWidth = 300;
const gap = 18;
function createMasonryGrid() {
const gridWidth = masonryGrid.offsetWidth;
const columns = Math.floor(gridWidth / columnWidth) || 1;
masonryGrid.style.columnCount = columns.toString();
masonryGrid.style.columnGap = `${gap}px`;
masonryGrid.style.display = "block";
masonryGrid.style.gridTemplateColumns = "";
masonryGrid.style.gridTemplateRows = "";
const items = Array.from(masonryGrid.children);
items.forEach((item) => {
item.style.gridRowStart = "";
item.style.gridColumnStart = "";
item.style.breakInside = "avoid";
item.style.marginBottom = `${gap}px`;
});
}
createMasonryGrid();
window.addEventListener("resize", createMasonryGrid);
window.addEventListener("load", createMasonryGrid);
const observer = new MutationObserver(createMasonryGrid);
observer.observe(masonryGrid, {
childList: true,
subtree: true
});
While we can’t create a masonry grid layout with CSS or Tailwind CSS alone, we can use JavaScript to create one, for now until have have green light to use CSS.
Hope you enjoyed this tutorial and have a great day!
/Michael Andreuzza
Unlock all themes for $199 for forever! Includes lifetime updates, new
themes, unlimited projects, and support. No subscription needed.
— No subscription required!