如何在 React 应用中 CSS 的许多属性中使用 JS 变量

How to use JS variable in many properties of CSS in a React app

我已经为提示气泡创建了一个组件。 这是我的 HintBubble 组件:

import React from 'react';

const HintBubble = ({ text, pointerDirection = "top", color = "#f7b049" }) => {
    return (
        <section id="hint-bubble" className={`hint-bubble-${pointerDirection}`}>
            {text}
        </section>
    );
};

export default HintBubble;

这些是 Stylus 编写的这个组件的不同样式:

// Top side
.hint-bubble-top {
    position: relative;
    background: #800040;
    border-radius: .4em;
}

.hint-bubble-top::after {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    width: 0;
    height: 0;
    border: 42px solid transparent;
    border-bottom-color: #800040;
    border-top: 0;
    border-left: 0;
    margin-left: -21px;
    margin-top: -42px;
}

// Right Side
.hint-bubble-right {
    position: relative;
    background: #800040;
    border-radius: .4em;
}

.hint-bubble-right::after {
    content: '';
    position: absolute;
    right: 0;
    top: 50%;
    width: 0;
    height: 0;
    border: 42px solid transparent;
    border-left-color: #800040;
    border-right: 0;
    border-bottom: 0;
    margin-top: -21px;
    margin-right: -42px;
}

// Bottom side
.hint-bubble-bottom {
    position: relative;
    background: #800040;
    border-radius: .4em;
}

.hint-bubble-bottom::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    width: 0;
    height: 0;
    border: 42px solid transparent;
    border-top-color: #800040;
    border-bottom: 0;
    border-left: 0;
    margin-left: -21px;
    margin-bottom: -42px;
}

// Left Side
.hint-bubble-left {
    position: relative;
    background: #800040;
    border-radius: .4em;
}

.hint-bubble-left::after {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    width: 0;
    height: 0;
    border: 42px solid transparent;
    border-right-color: #800040;
    border-left: 0;
    border-bottom: 0;
    margin-top: -21px;
    margin-left: -42px;
}

为了创建 this 中显示的所有状态,我必须设置 background-colorborder-bottom-colorborder-left-color、... 不同的属性类.

我知道我可以通过 document.queryselector('.hint-bubble-top').style.backgroundColor 更改 background-color 属性,但我想将 props 中的 color 全部替换掉background-colorborder-bottom-colorborder-left-color、... 我的 Stylus 文件中的属性。

您可以将颜色设置为 css 变量并在您的组件中更新它:

  import React, {createRef, useEffect} from 'react';

  const HintBubble = ({text, pointerDirection = 'top', color = '#f7b049'}) => {
    const hint = createRef();

    useEffect(() => hint.current.style.setProperty('--hint-color', color), [
      color,
    ]);

    return (
      <section
        ref={hint}
        id="hint-bubble"
        className={`hint-bubble hint-bubble-${pointerDirection}`}
      >
        {text}
      </section>
    );
  };

  export default HintBubble;

CSS 将如下所示:

  *,
  *:before,
  *:after {
    box-sizing: border-box;
  }

  .hint-bubble {
    --hint-color: #800040;
  }
  // Top side
  .hint-bubble-top {
    position: relative;
    background: var(--hint-color);
    border-radius: 0.4em;
  }

  .hint-bubble-top::after {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    width: 0;
    height: 0;
    border: 42px solid transparent;
    border-bottom-color: var(--hint-color);
    border-top: 0;
    border-left: 0;
    margin-left: -21px;
    margin-top: -42px;
  }

  // Right Side
  .hint-bubble-right {
    position: relative;
    background: var(--hint-color);
    border-radius: 0.4em;
  }

  .hint-bubble-right::after {
    content: '';
    position: absolute;
    right: 0;
    top: 50%;
    width: 0;
    height: 0;
    border: 42px solid transparent;
    border-left-color: var(--hint-color);
    border-right: 0;
    border-bottom: 0;
    margin-top: -21px;
    margin-right: -42px;
  }

  // Bottom side
  .hint-bubble-bottom {
    position: relative;
    background: var(--hint-color);
    border-radius: 0.4em;
  }

  .hint-bubble-bottom::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    width: 0;
    height: 0;
    border: 42px solid transparent;
    border-top-color: var(--hint-color);
    border-bottom: 0;
    border-left: 0;
    margin-left: -21px;
    margin-bottom: -42px;
  }

  // Left Side
  .hint-bubble-left {
    position: relative;
    background: var(--hint-color);
    border-radius: 0.4em;
  }

  .hint-bubble-left::after {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    width: 0;
    height: 0;
    border: 42px solid transparent;
    border-right-color: var(--hint-color);
    border-left: 0;
    border-bottom: 0;
    margin-top: -21px;
    margin-left: -42px;
  }