admin管理员组文章数量:1399910
I've been searching Stack Overflow and the whole internet for this and couldn't find the right answer, so sorry if this is a duplicate question.
I've got a list:
How do I apply CSS transition to the list of elements, one by one, only on page load in React?
I was able to use ReactCSSTransitionGroup
, and it works fine, but it applies the transition to the entire list at the same time.
React:
<ul className="item-list">
<ReactCSSTransitionGroup transitionName="fade" transitionAppear={true}
transitionAppearTimeout={2000}>
{props.items.map((item, i) => (<li><someComponent/></li>)}
</ReactCSSTransitionGroup>
</ul>
...
CSS:
.fade-appear{
opacity: 0;
}
.fade-appear-active{
opacity: 1;
transition: opacity 500ms ease-out;
}
As I previously mentioned, I need to apply the above transition to the list of items one after another.
I've been searching Stack Overflow and the whole internet for this and couldn't find the right answer, so sorry if this is a duplicate question.
I've got a list:
How do I apply CSS transition to the list of elements, one by one, only on page load in React?
I was able to use ReactCSSTransitionGroup
, and it works fine, but it applies the transition to the entire list at the same time.
React:
<ul className="item-list">
<ReactCSSTransitionGroup transitionName="fade" transitionAppear={true}
transitionAppearTimeout={2000}>
{props.items.map((item, i) => (<li><someComponent/></li>)}
</ReactCSSTransitionGroup>
</ul>
...
CSS:
.fade-appear{
opacity: 0;
}
.fade-appear-active{
opacity: 1;
transition: opacity 500ms ease-out;
}
As I previously mentioned, I need to apply the above transition to the list of items one after another.
Share Improve this question edited Aug 27, 2021 at 11:26 Aaron Sarnat 1,2351 gold badge8 silver badges16 bronze badges asked Aug 26, 2021 at 22:34 Khaled RakhisiKhaled Rakhisi 3251 gold badge5 silver badges19 bronze badges 3-
Maybe you can wrap each item into a ReactCSSTransitionGroup and use the index to set different AppearTimeout values? like
transitionAppeartimeout={2000 + 500*i}
– arieljuod Commented Aug 26, 2021 at 22:38 - @arieljuod transitionAppeartimeout determines the transition duration not the delay before transition i guess – Khaled Rakhisi Commented Aug 26, 2021 at 23:08
-
Not sure if this affects the issue you're having, but I think you may be using an old implementation of CSSTransitionGroup. Per the react docs, this is now part of github./reactjs/react-transition-group/tree/v1-stable which has a slightly different syntax. Also you should be aware that as-is, this is injecting a
<span>
as a direct child of<ul>
which is not valid. You can specify aponent
andclassName
attribute on< ReactCSSTransitionGroup>
and effectively bine it with the<ul className="item-list">
so they are one and the same. – Aaron Sarnat Commented Aug 27, 2021 at 2:39
3 Answers
Reset to default 4I think the effect is usually referred to as “staggered,” “cascading,” or “sequenced.”
Rather than using ReactCSSTransitionGroup
, you could do this mostly with CSS.
First, I'd animate your cards using animation
property and @keyframes
instead of transition
property. So to start, you could add something like this to your CSS:
CSS
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Javascript
The crux of the solution is to set an animation
CSS style on each list item, and use the item index as a multiplier for a specified delay
value.
I started by creating an array of objects called items
, where each object contains a title
and a text
field (mainly just needed an array to map for the example).
I also created a couple of constants for abstracting the two numerical values for the animation, duration
and delay
(note we're only doing math with delay
in the example to follow, but it looked cleaner to me to pull out duration
as well):
const duration = 1000; // ms
const delay = 500; // ms
Made a template that returns a formatted string to be used as the value of each transition element's animation
CSS property:
const animStr = (i) => `fadeIn ${duration}ms ease-out ${delay * i}ms forwards`;
Mapping the data during render time, and setting the CSS animation
style based on the index value (i
) via animStr
:
{items.map((item, i) => (
<li key={i} style={{ animation: animStr(i) }}>
<SomeComponent item={item} />
</li>
))}
The animation will bee active as soon as that element is injected into the DOM (as per the CSS animation spec). Syntax is based on the css animation shorthand. Note that the default behavior for the animation is to run once. Adding forwards
to the rule causes the animation to retain the properties of the last keyframe when it stops (fully visible).
Edit: Personally, I think it looks better to start the delay index at 1
instead of 0
, so you could set your animation
value to this:
`fadeIn ${duration}ms ease-out ${delay * (i + 1)}ms forwards`
Working CodeSandbox
Here's a working codesandbox.
Screen Recording
This is what the above code looks like in action. It's a screen recording of the page being reloaded on CodeSandbox.
Another way to solve this would be to use a library. Both of the following libraries can achieve this effect with some added features:
react-drizzle
react-awesome-reveal
If you're mitted to keeping ReactCSSTransitionGroup
then you could probably just add a custom transition-delay
property on each item, similar to the solution in my other answer.
const delay = 500;
And do something like this:
{props.items.map((item, i) => (
<li style={{ transitionDelay: `${delay * i}ms` }}>
<SomeComponent item={item} />
</li>
)}
本文标签:
版权声明:本文标题:javascript - How do I apply CSS transitions (e.g. fade-ins) to a list of items in React so their animations are sequenced one af 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744164605a2593492.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论