admin管理员组

文章数量:1023018

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.

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.

本文标签: javascriptMerge a single CSS property in EmotionStack Overflow