javascript - Merge a single CSS property in Emotion - Stack Overflow

I'm trying to create reusable animations in Emotion but have run into some issues. I've defin

I'm trying to create reusable animations in Emotion but have run into some issues. I've defined an animation for a fadeUp effect which works fine.

export const animatedFadeUp = css`
  opacity: 1;
  transform: translateY(0);
`;

export const fadeUp = css`
  opacity: 0;
  transform: translateY(var(--spacing-medium));
  transition: opacity 0.5s ease-in-out,
    transform 0.5s ease-in-out;

  html.no-js & {
    ${animatedFadeUp}
  }
`;

But when i try to apply the fadeUp animation to an element that already has the transition defined it gets overruled. For example the button below. The transition will be overruled by the button.

const Button = styled.button`
  ${fadeUp}
  background: orange;
  transition: background-color 0.5s ease-in-out;

  &:hover,
  &:focus {
    background: gold;
  }
`;

Is there a solution to bine only a single property? Something like:

const Button = styled.button`
  ${fadeUp}
  background: orange;
  transition: ${fadeUp.transition},
    background-color 0.5s ease-in-out;

  &:hover,
  &:focus {
    background: gold;
  }
`;

I'm trying to create reusable animations in Emotion but have run into some issues. I've defined an animation for a fadeUp effect which works fine.

export const animatedFadeUp = css`
  opacity: 1;
  transform: translateY(0);
`;

export const fadeUp = css`
  opacity: 0;
  transform: translateY(var(--spacing-medium));
  transition: opacity 0.5s ease-in-out,
    transform 0.5s ease-in-out;

  html.no-js & {
    ${animatedFadeUp}
  }
`;

But when i try to apply the fadeUp animation to an element that already has the transition defined it gets overruled. For example the button below. The transition will be overruled by the button.

const Button = styled.button`
  ${fadeUp}
  background: orange;
  transition: background-color 0.5s ease-in-out;

  &:hover,
  &:focus {
    background: gold;
  }
`;

Is there a solution to bine only a single property? Something like:

const Button = styled.button`
  ${fadeUp}
  background: orange;
  transition: ${fadeUp.transition},
    background-color 0.5s ease-in-out;

  &:hover,
  &:focus {
    background: gold;
  }
`;
Share Improve this question edited Mar 2, 2021 at 8:10 StackByMe asked Feb 27, 2021 at 15:58 StackByMeStackByMe 6,54521 silver badges30 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4 +50

Instead of passing it as a CSS tagged template literals or using styled ponents, you may use it as CSS object. By using as such, it would be more flexible and easier to refer their properties.

<p
  css={{
    color: 'red'
 }}
>Hello World</p>

So your code would bee

export const animatedFadeUp = {
  opacity: 1,
  transform: 'translateY(0)',
};

export const fadeUp = {
  opacity: 0,
  transform: 'translateY(var(--spacing-medium))',
  transition: `opacity 0.5s ease-in-out,
    transform 0.5s ease-in-out`,

  ['html.no-js &']: {
    ...animatedFadeUp
  }
};

const App = () => (
  <button
    css={{
      ...fadeUp,
      background: 'orange',
      transition: `${fadeUp.transition},
        background-color 0.5s ease-in-out`,

      ['&:hover']: {
        background: 'gold',
      },
      ['&:focus']: {
        background: 'gold',
      }
    }}
  >Click Me</button>
)

Not quite familiar with the Emotion library, maybe there is an API that exposes style value access like you tried with ${fadeUp.transition}. But I won't be surprised if there is no such API as it increases the plexity of the library. However, hope is not lost, without knowing much of the API, we can still solve this problem using language features supported by javascript. Below is an example:

import React, { useState } from 'react';
import styled from '@emotion/styled';
import { css } from '@emotion/react';

export const animatedFadeUp = css`
  opacity: 1;
  transform: translateY(0);
`;

// Notice that the annoymous function is invoked immediately to get back an object
// with properties of `css` and `transition`, so that we can access them later
export const fadeUp = (() => {
  // By defining the transition value here, we can update the transition value in one
  // place instead of updating in multiple places, including the downstream consumers
  // of the returned object
  const transition = 'opacity 0.5s ease-in-out, transform 0.5s ease-in-out';

  return {
    css: css`
      opacity: 0;
      transform: translateY(25px);
      transition: ${transition};

      &.active {
        ${animatedFadeUp}
      }
    `,
    transition,
  };
})();

// Note that we need to access the `css` property explicitly here
// like this - ${fadeUp.css}
const Button = styled.button`
  ${fadeUp.css}
  background: green;
  transition: ${fadeUp.transition}, background-color 0.5s ease-in-out;

  &:hover,
  &:focus,
  &.active {
    background: gold;
  }
`;

function App() {
  const [className, setClassName] = useState('');

  return (
    <div className="App">
      <Button className={className}>This my button ponent.</Button>

      <button onClick={() => setClassName(className ? '' : 'active')}>
        Toggle
      </button>
    </div>
  );
}

export default App;

In short, we create an object that holds the information of the css and transition so that we can use it later. The downside of this approach is that we need to remember that when using fadeUp, we have to treat it differently by explicitly accessing fadeUp.css, unlike other emotion created css.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745545242a4632307.html

相关推荐

  • javascript - Merge a single CSS property in Emotion - Stack Overflow

    I'm trying to create reusable animations in Emotion but have run into some issues. I've defin

    23小时前
    30

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信