使用 styled-components 反转 props 变化的转换
我对道具更改上的两个元素进行动画处理:容器 div 以 max-height
滑入/滑出,div 的内容以 opacity
淡入/淡出。
问题是,我希望容器在“out”动画的内容之后进行动画处理,但我希望它出现在“in”动画的内容之前。目前,元素始终按相同的顺序进行:内容首先转换,然后是容器。这意味着内容会在容器滑入“in”动画之前出现。
我尝试过使用 styled-components 中的 reverse
属性和 keyframes
,但老实说,我对 CSS 动画很差,以至于我无法开始理解我需要什么改变。
这是当前代码:
Component.tsx
export default function Component() {
const [showBanner, setShowBanner] = useState(true);
const handleAccept = () => {
setShowBanner(false);
};
const handleReject = () => {
setShowBanner(false);
};
return (
<StyledComponent $showBanner={showBanner}>
<StyledText>
// some text
</StyledText>
<StyledButtonsContainer>
// some buttons
</StyledButtonsContainer>
</StyledComponent>
);
}
Component.styles.tsx
export const StyledComponent = styled.div<{ $showBanner: boolean }>`
&&& {
position: absolute;
z-index: ${zIndex("overlay")};
display: flex;
flex-direction: column;
max-height: ${(props) => (props.$showBanner ? "100%" : "0")};
height: 100%;
width: 100%;
background: ${(props) => props.theme.secondary};
color: ${(props) => props.theme.white};
transition: max-height 0.5s 0.5s ease;
@media ${device.tablet} {
border-radius: 0 0 2px 20px;
}
* { // targeting everything all of the contents
opacity: ${(props) => (props.$showBanner ? "100%" : "0%")};
transition: opacity 0.5s ease;
}
}
`;
I am animation two elements on a props change: a container div slides in/out with max-height
, and the contents of the div fades in/out with opacity
.
Trouble is, I want the container to animate after the contents on the "out" animation, but I want it to appear before the contents on the "in" animation. Currently, the elements always go in the same order: contents transition first, then the container. This means that the contents appear before the container has slid in on the "in" animation.
I've tried using the reverse
attribute and keyframes
from styled-components, but honestly I'm so bad at CSS animations that I can't begin to understand what I need to change.
Here's the current code:
Component.tsx
export default function Component() {
const [showBanner, setShowBanner] = useState(true);
const handleAccept = () => {
setShowBanner(false);
};
const handleReject = () => {
setShowBanner(false);
};
return (
<StyledComponent $showBanner={showBanner}>
<StyledText>
// some text
</StyledText>
<StyledButtonsContainer>
// some buttons
</StyledButtonsContainer>
</StyledComponent>
);
}
Component.styles.tsx
export const StyledComponent = styled.div<{ $showBanner: boolean }>`
&&& {
position: absolute;
z-index: ${zIndex("overlay")};
display: flex;
flex-direction: column;
max-height: ${(props) => (props.$showBanner ? "100%" : "0")};
height: 100%;
width: 100%;
background: ${(props) => props.theme.secondary};
color: ${(props) => props.theme.white};
transition: max-height 0.5s 0.5s ease;
@media ${device.tablet} {
border-radius: 0 0 2px 20px;
}
* { // targeting everything all of the contents
opacity: ${(props) => (props.$showBanner ? "100%" : "0%")};
transition: opacity 0.5s ease;
}
}
`;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我通过使用
$showBanner
属性控制transition-delay
属性来对此进行排序。不过,我是通过transition
简写完成的:这会反转两个转换的延迟,从而有效地反转转换。
I sorted this by controlling the
transition-delay
property with the$showBanner
prop. I did it via thetransition
shorthand, though:This reverses the delays for the two transitions, effectively reversing the transition.