使用 styled-components 反转 props 变化的转换

发布于 2025-01-12 14:29:46 字数 1711 浏览 0 评论 0原文

我对道具更改上的两个元素进行动画处理:容器 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

許願樹丅啲祈禱 2025-01-19 14:29:46

我通过使用 $showBanner 属性控制 transition-delay 属性来对此进行排序。不过,我是通过 transition 简写完成的:

export const StyledCookieBanner = 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 ${(props) => !props.$showBanner && "0.5s"}; // here

    @media ${device.tablet} {
      border-radius: 0 0 2px 20px;
    }

    * {
      opacity: ${(props) => (props.$showBanner ? "100%" : "0%")};
      transition: opacity 0.5s ${(props) => props.$showBanner && "0.5s"}; // here
    }
  }
`;

这会反转两个转换的延迟,从而有效地反转转换。

I sorted this by controlling the transition-delay property with the $showBanner prop. I did it via the transition shorthand, though:

export const StyledCookieBanner = 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 ${(props) => !props.$showBanner && "0.5s"}; // here

    @media ${device.tablet} {
      border-radius: 0 0 2px 20px;
    }

    * {
      opacity: ${(props) => (props.$showBanner ? "100%" : "0%")};
      transition: opacity 0.5s ${(props) => props.$showBanner && "0.5s"}; // here
    }
  }
`;

This reverses the delays for the two transitions, effectively reversing the transition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文