What are Dynamic Grids?
Dynamic grids adapt to your data. Instead of hardcoding 3 columns, you calculate columns based on array length, user preferences, or application state. This is where JavaScript Grid shines.
Grid Based on Data Length
Create columns based on how much data you have:
const products = [
{ name: 'Laptop', price: 999 },
{ name: 'Mouse', price: 29 },
{ name: 'Keyboard', price: 79 }
];
const container = document.getElementById('grid');
const numColumns = products.length;
container.style.display = 'grid';
container.style.gridTemplateColumns = `repeat(${numColumns}, 1fr)`;
container.style.gap = '1rem';
// Add items to grid
products.forEach(product => {
const div = document.createElement('div');
div.textContent = product.name;
container.appendChild(div);
});
User-Controlled Layouts
Let users choose their view:
function setGridLayout(layout) {
const container = document.getElementById('gallery');
const layouts = {
'list': '1fr',
'two': 'repeat(2, 1fr)',
'three': 'repeat(3, 1fr)',
'four': 'repeat(4, 1fr)'
};
container.style.gridTemplateColumns = layouts[layout];
}
// Buttons trigger layout changes
document.getElementById('btn-list').onclick = () => setGridLayout('list');
document.getElementById('btn-two').onclick = () => setGridLayout('two');
document.getElementById('btn-three').onclick = () => setGridLayout('three');
document.getElementById('btn-four').onclick = () => setGridLayout('four');
State-Based Grids
Change grid based on application state:
let viewMode = 'compact'; // or 'comfortable' or 'spacious'
function updateGrid() {
const container = document.getElementById('grid');
if (viewMode === 'compact') {
container.style.gridTemplateColumns = 'repeat(6, 1fr)';
container.style.gap = '0.5rem';
} else if (viewMode === 'comfortable') {
container.style.gridTemplateColumns = 'repeat(4, 1fr)';
container.style.gap = '1rem';
} else if (viewMode === 'spacious') {
container.style.gridTemplateColumns = 'repeat(2, 1fr)';
container.style.gap = '2rem';
}
}
// Change state
viewMode = 'comfortable';
updateGrid();
Adaptive Column Count
Calculate optimal columns based on item count:
function getOptimalColumns(itemCount) {
if (itemCount <= 2) return 1;
if (itemCount <= 4) return 2;
if (itemCount <= 9) return 3;
return 4;
}
const items = [/* your data */];
const cols = getOptimalColumns(items.length);
container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
Building a Dashboard Builder
Let users drag widgets and the grid adapts:
const widgets = [
{ id: 1, span: 2 }, // takes 2 columns
{ id: 2, span: 1 },
{ id: 3, span: 1 },
{ id: 4, span: 3 }
];
// Calculate total columns needed
const totalSpan = widgets.reduce((sum, w) => sum + w.span, 0);
const cols = Math.min(totalSpan, 12); // max 12 columns
container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
// Set each widget's span
widgets.forEach(widget => {
const element = document.getElementById(`widget-${widget.id}`);
element.style.gridColumn = `span ${widget.span}`;
});
React Dynamic Grid Example
In React, state drives grid layout:
function Gallery({ images }) {
const [columns, setColumns] = useState(3);
return (
<>
<div>
<button onClick={() => setColumns(2)}>2 Columns</button>
<button onClick={() => setColumns(3)}>3 Columns</button>
<button onClick={() => setColumns(4)}>4 Columns</button>
</div>
<div style={{
display: 'grid',
gridTemplateColumns: `repeat(${columns}, 1fr)`,
gap: '1rem'
}}>
{images.map(img => (
<img key={img.id} src={img.url} />
))}
</div>
</>
);
}
Filtering and Grid Updates
Update grid when filtered data changes:
let allProducts = [/* all products */];
let filteredProducts = [];
function filterProducts(category) {
if (category === 'all') {
filteredProducts = allProducts;
} else {
filteredProducts = allProducts.filter(p => p.category === category);
}
renderGrid();
}
function renderGrid() {
const container = document.getElementById('grid');
// Clear existing
container.innerHTML = '';
// Update columns based on filtered count
const cols = Math.min(filteredProducts.length, 4);
container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
// Add filtered items
filteredProducts.forEach(product => {
const div = document.createElement('div');
div.textContent = product.name;
container.appendChild(div);
});
}
Saving User Preferences
function saveLayout(layout) {
localStorage.setItem('preferred-layout', layout);
setGridLayout(layout);
}
function loadLayout() {
const saved = localStorage.getItem('preferred-layout') || 'three';
setGridLayout(saved);
}
// On page load
window.addEventListener('DOMContentLoaded', loadLayout);
Animation Between Layouts
Smooth transitions when grid changes:
container.style.transition = 'grid-template-columns 0.3s ease';
container.style.gridTemplateColumns = 'repeat(4, 1fr)';
The grid will smoothly animate to the new column count.