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.
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 toggleColumns() {
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!
will-change for better performance on complex
grids, but remove it after the 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 (
<>
<button onClick={() => setColumns(columns === 3 ? 4 : 3)}>
Toggle Columns
</button>
<div style={gridStyle}>
{items.map((item, i) => (
<div
key={item.id}
style={{
transition: 'all 0.3s ease',
transitionDelay: `${i * 0.05}s`
}}
>
{item.name}
</div>
))}
</div>
</>
);
}
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);
- 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)';
});
});