Module 31 : CSS Grid Masonry Layouts – Creating Pinterest-style Layouts
Learning Objectives
By the end of this module, students will:
Understand what a Masonry layout is and its use cases.
Learn how to build a Pinterest-style layout using CSS Grid.
Use JavaScript to enhance CSS Grid for true masonry behavior.
Create responsive layouts using auto-placement and grid-template-columns.
Implement a complete example with images and dynamic content.
Section 1: Introduction to Masonry Layout
What is a Masonry Layout?
A masonry layout positions elements vertically in columns.
Items are placed based on available vertical space, like a brick wall.
Unlike traditional grids, masonry does not force equal row heights.
Commonly seen in Pinterest, Behance, or photo galleries.
Use Cases
Image galleries
Blog post grids
Portfolio showcases
E-commerce product displays
Section 2: CSS Grid Basics Review
Before jumping into masonry, you must understand:
css code
.grid-container { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; }
Explanation:
auto-fill or auto-fit: automatically fill the container with columns.
minmax(250px, 1fr): ensures responsiveness.
gap: spacing between items.
But this creates equal-height rows. Masonry requires uneven rows.
Section 3: Methods to Create CSS Grid masonry
Method 1: Masonry with grid-auto-rows and grid-row-end: span
html code
<div class="grid"> <div class="grid-item">Content</div> ... </div>
css code
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-auto-rows: 10px; gap: 10px; } .grid-item { background: #ccc; padding: 10px; border-radius: 8px; grid-row-end: span 30; /* This will be overridden by JS */ }
Enhancing with JavaScript
js code
const grid = document.querySelector('.grid'); const allItems = grid.querySelectorAll('.grid-item'); allItems.forEach(item => { const rowHeight = parseInt(getComputedStyle(grid).getPropertyValue('grid-auto-rows')); const rowGap = parseInt(getComputedStyle(grid).getPropertyValue('gap')); const itemHeight = item.getBoundingClientRect().height; const span = Math.ceil((itemHeight + rowGap) / (rowHeight + rowGap)); item.style.gridRowEnd = `span ${span}`; });
Explanation:
We calculate the height of each item and set the grid-row-end value.
This lets items span the correct number of rows, achieving masonry layout.
The layout is responsive and adjusts automatically.
Section 4: Practical Exercise
Task: Create a masonry layout with 10 different-sized image cards.
HTML:
html code
<div class="grid"> <div class="grid-item"><img src="https://picsum.photos/id/1015/300/200"></div> <div class="grid-item"><img src="https://picsum.photos/id/1016/300/400"></div> ... </div>
CSS:
css code
.grid-item img { width: 100%; display: block; border-radius: 8px; }
JS:
Add the dynamic span calculation after images are loaded:
js code
window.addEventListener("load", () => { const grid = document.querySelector('.grid'); const allItems = grid.querySelectorAll('.grid-item'); allItems.forEach(item => { const rowHeight = parseInt(getComputedStyle(grid).getPropertyValue('grid-auto-rows')); const rowGap = parseInt(getComputedStyle(grid).getPropertyValue('gap')); const itemHeight = item.getBoundingClientRect().height; const span = Math.ceil((itemHeight + rowGap) / (rowHeight + rowGap)); item.style.gridRowEnd = `span ${span}`; }); });
Section 5: Building a Pinterest Clone Gallery
Objective:
Create a responsive Pinterest-style gallery with dynamically loaded content.
Steps:
1. HTML Structure:
html code
<div class="grid"> <!-- Cards will be dynamically loaded --> </div>
2. JavaScript for Dynamic Content:
js code
const imageUrls = [ 'https://picsum.photos/300/300', 'https://picsum.photos/300/400', 'https://picsum.photos/300/250', 'https://picsum.photos/300/350', 'https://picsum.photos/300/450' ]; const grid = document.querySelector('.grid'); imageUrls.forEach(url => { const item = document.createElement('div'); item.className = 'grid-item'; const img = document.createElement('img'); img.src = url; item.appendChild(img); grid.appendChild(item); });
3. After Loading Images, Apply Masonry:
js code
window.addEventListener('load', () => { const grid = document.querySelector('.grid'); const items = document.querySelectorAll('.grid-item'); items.forEach(item => { const rowHeight = parseInt(getComputedStyle(grid).getPropertyValue('grid-auto-rows')); const rowGap = parseInt(getComputedStyle(grid).getPropertyValue('gap')); const height = item.getBoundingClientRect().height; const span = Math.ceil((height + rowGap) / (rowHeight + rowGap)); item.style.gridRowEnd = `span ${span}`; }); });
Outcome:
Students will see a responsive gallery with variable-height cards that flow like Pinterest.
They'll learn to combine CSS Grid with JavaScript for dynamic layout control.
Section 6: Additional Tips
1. Responsive Enhancements
Use media queries to adjust grid layout for mobile and tablet views.
css code
@media (max-width: 768px) { .grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); } }
2. Animation on Load
Add subtle transitions:
css code
.grid-item { transition: all 0.3s ease; opacity: 0; } .grid-item.loaded { opacity: 1; }
Add class in JS after load.
Section 7: Summary
Masonry layouts arrange elements like bricks in a wall.
CSS Grid allows flexible column control but not variable row height natively.
JavaScript is used to span items to the correct row height dynamically.
The result is a clean, Pinterest-style responsive layout.
Section 8: Assignment
Task:
Build a 3-column blog layout with variable-height article cards using a CSS Grid masonry layout. Include at least:
A featured image
A title
A short paragraph
Bonus: Add a button that loads more cards dynamically and triggers masonry reflow.





No comments:
Post a Comment