【问题标题】:Merge a single CSS property in Emotion在 Emotion 中合并单个 CSS 属性
【发布时间】:2021-05-29 16:59:55
【问题描述】:

我正在尝试在 Emotion 中创建可重复使用的动画,但遇到了一些问题。我为 fadeUp 效果定义了一个动画,效果很好。

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}
  }
`;

但是当我尝试将fadeUp 动画应用于已经定义了过渡的元素时,它会被否决。例如下面的按钮。 transition 将被 button 否决。

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

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

有没有只组合一个属性的解决方案?比如:

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

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

【问题讨论】:

    标签: javascript css reactjs emotion


    【解决方案1】:

    Emotion 库不太熟悉,也许有一个API 可以公开样式值访问,就像您尝试使用${fadeUp.transition} 一样。但如果没有这样的 API,我不会感到惊讶,因为它会增加库的复杂性。但是,希望没有落空,在不了解太多 API 的情况下,我们仍然可以使用 javascript 支持的语言特性来解决这个问题。下面是一个例子:

    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 component.</Button>
    
          <button onClick={() => setClassName(className ? '' : 'active')}>
            Toggle
          </button>
        </div>
      );
    }
    
    export default App;
    

    简而言之,我们创建一个对象来保存csstransition 的信息,以便我们以后使用。这种方法的缺点是我们需要记住,在使用fadeUp时,我们必须通过显式访问fadeUp.css来区别对待,不像其他emotion创建的css。

    【讨论】:

      【解决方案2】:

      您可以将其用作 CSS 对象,而不是将其作为 CSS 标记的模板文字或使用样式组件传递。通过这样使用,它会更灵活,更容易引用它们的属性。

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

      所以你的代码会变成

      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>
      )
      

      【讨论】:

      • 虽然我做了一些小调整,但使用对象而不是模板文字就可以了,ty!
      猜你喜欢
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-17
      相关资源
      最近更新 更多