Animating Grid Properties
You can animate grid column and row changes using CSS transitions! Set the transition once, then any grid property changes will animate smoothly.
💡 What Animates:
gridTemplateColumns, gridTemplateRows, gap, and
gridTemplateAreas can all be animated!
Basic Grid Animation
Animate column count changes:
const container = document.getElementById('grid');
// Enable transitions
container.style.transition = 'grid-template-columns 0.3s ease';
// Now changes animate!
function toggle Columns() {
const current = container.style.gridTemplateColumns;
if (current.includes('3')) {
container.style.gridTemplateColumns = 'repeat(4, 1fr)';
} else {
container.style.gridTemplateColumns = 'repeat(3, 1fr)';
}
}
// Call this on button click - it animates!
toggleColumns();
Animating Gap
Smooth gap transitions:
container.style.transition = 'gap 0.3s ease';
// Gap changes smoothly
function setCompact() {
container.style.gap = '0.5rem';
}
function setSpacious() {
container.style.gap = '2rem';
}
Multiple Properties
Animate several grid properties at once:
container.style.transition = 'all 0.4s ease-in-out';
function setMobileLayout() {
container.style.gridTemplateColumns = '1fr';
container.style.gap = '0.5rem';
}
function setDesktopLayout() {
container.style.gridTemplateColumns = 'repeat(4, 1fr)';
container.style.gap = '2rem';
}
// Both properties animate together!
⚡ Performance Note:
Grid animations can be intensive. Use will-change for better performance on complex
grids, but remove it after animation completes!
Staggered Item Animations
Animate grid items appearing one by one:
function animateIn(items) {
const container = document.getElementById('grid');
items.forEach((item, index) => {
const div = document.createElement('div');
div.textContent = item.name;
// Start invisible and scaled down
div.style.opacity = '0';
div.style.transform = 'scale(0.8)';
div.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
container.appendChild(div);
// Animate in with delay
setTimeout(() => {
div.style.opacity = '1';
div.style.transform = 'scale(1)';
}, index * 50); // 50ms stagger
});
}
React Animated Grid
Animate layout changes in React:
function AnimatedGrid({ items }) {
const [columns, setColumns] = useState(3);
const gridStyle = {
display: 'grid',
gridTemplateColumns: `repeat(${columns}, 1fr)`,
gap: '1rem',
transition: 'grid-template-columns 0.3s ease'
};
return (
<>
{items.map((item, i) => (
{item.name}
))}
>
);
}
Expanding Grid Item
Click to expand an item to full width:
function setupExpandable() {
const items = document.querySelectorAll('.grid-item');
items.forEach(item => {
item.style.transition = 'grid-column 0.3s ease';
item.addEventListener('click', () => {
const isExpanded = item.style.gridColumn === '1 / -1';
if (isExpanded) {
item.style.gridColumn = 'span 1';
} else {
item.style.gridColumn = '1 / -1'; // Full width
}
});
});
}
Smooth Layout Reordering
Change grid order with smooth transitions:
function reorderGrid(newOrder) {
const container = document.getElementById('grid');
const items = Array.from(container.children);
// Enable transitions
items.forEach(item => {
item.style.transition = 'all 0.3s ease';
});
// Reorder based on new order array
newOrder.forEach((index, position) => {
items[index].style.order = position;
});
}
Entrance Animation
Grid fades in when page loads:
function animateGridIn() {
const container = document.getElementById('grid');
container.style.opacity = '0';
container.style.transform = 'translateY(20px)';
container.style.transition = 'opacity 0.5s ease, transform 0.5s ease';
// Trigger animation
setTimeout(() => {
container.style.opacity = '1';
container.style.transform = 'translateY(0)';
}, 100);
}
// Call on page load
window.addEventListener('DOMContentLoaded', animateGridIn);
✅ Best Practices:
- • Keep animations under 400ms for responsiveness
- • Use
ease-in-outfor natural motion - • Test on slower devices
- • Provide reduced-motion alternatives
Respecting Reduced Motion
Disable animations for users who prefer reduced motion:
const prefersReducedMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
).matches;
if (!prefersReducedMotion) {
container.style.transition = 'all 0.3s ease';
} else {
container.style.transition = 'none';
}
Combining with Transform
Use transform for performant animations:
items.forEach(item => {
item.style.transition = 'transform 0.3s ease, opacity 0.3s ease';
item.addEventListener('mouseenter', () => {
item.style.transform = 'scale(1.05)';
});
item.addEventListener('mouseleave', () => {
item.style.transform = 'scale(1)';
});
});