Animating Elements on the Same Page using @view-transition in a Next.js 14 Application
Fri Oct 11 2024Overview
This guide details how to animate elements within the same route or page in a Next.js 14 application using the @view-transition
API. By animating elements on the same page, you can provide a smoother and more engaging user experience when content is updated or elements are manipulated.
Prerequisites
Before you get started, ensure the following prerequisites are met:
- Familiarity with Next.js 14 and React.
- Basic understanding of modern JavaScript and CSS animations.
- A Next.js 14 application set up and running locally.
Getting Started with @view-transition for Same-Page Animations
The @view-transition
API is typically used for transitioning between pages, but it can also be leveraged to animate elements within the same page. This is particularly useful for cases where you want to update or replace parts of the page's content while maintaining a fluid, visually appealing user experience.
1. Triggering Element Transitions
Below is an example of how to create a color filter that triggers element transitions on the same page:
"use client";
import React, { useState, useEffect } from "react";
interface Item {
id: string;
name: string;
color: string;
}
interface Props {
items: Item[];
selectedFilter: string | null;
}
const FilteredItems = ({ items, selectedFilter }: Props) => {
useEffect(() => {
const elements = document.querySelectorAll(".item");
document.startViewTransition(() => {
elements.forEach((element) => {
const itemId = element.getAttribute("data-item");
if (selectedFilter === null || selectedFilter === itemId) {
element.classList.remove("hidden");
} else {
element.classList.add("hidden");
}
});
});
}, [selectedFilter]);
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mt-4">
{items.map((item) => (
<div
key={item.id}
data-item={item.id}
className="item transition-all duration-300 ease-in-out p-4 bg-white shadow-lg rounded-lg flex flex-col items-center justify-center"
style={{ viewTransitionName: `item-${item.id}` }}
>
<div
className="w-20 h-20 mb-2 rounded-md"
style={{ backgroundColor: item.color }}
></div>
<h3 className="text-lg font-semibold">{item.name}</h3>
</div>
))}
</div>
);
};
export default FilteredItems;
In this example, document.startViewTransition()
is used to apply transitions when the filter is updated. Each item is assigned a unique viewTransitionName
to ensure that the transitions track and animate the elements smoothly when their visibility changes.
2. Adding Custom Animations
To further enhance the animations, you can use the ::view-transition-group
pseudo-element. For example, to apply custom styles to all elements during the transition, use:
::view-transition-group(*) {
animation-duration: 0.9s;
}
This applies a 0.9s animation to all items during the transition. You can also target specific animations using viewTransitionName
if needed.
Conclusion
The @view-transition
API is a powerful tool for animating elements within the same page, allowing for seamless and engaging user experiences. By using JavaScript to trigger transitions and CSS to style them, you can significantly improve the visual quality of interactions in your Next.js 14 application.
Instead of relying on conditional rendering, modifying styles while leveraging view transitions provides a smoother and more appealing way to filter and animate elements. This approach enhances the overall experience, making animations feel polished and natural.
Be sure to consider fallback options for browsers that don't support the @view-transition
API and ensure your animations are both visually appealing and performant.
Further Reading
For more information, refer to the MDN documentation on the View-Transition API.