如何在 css 文件中使用 API 颜色变量?

Posted

技术标签:

【中文标题】如何在 css 文件中使用 API 颜色变量?【英文标题】:How to use API color variable in css file? 【发布时间】:2021-10-19 02:23:33 【问题描述】:

我从 API 获得了一个 background-color,变量名称为 settings.brand_color。 我想在 html 元素中使用该变量。我不能使用style 属性,因为我在我的应用程序中使用:before 选择器。 我想在我的 css 文件中传递那个 API 变量,并在我的 :before 伪选择器中使用它。

JSX

      <input
        id=languageLabel
        type="radio"
        name="language-select"
        value=languageLabel
        // defaultChecked=index === 0
        onChange=() => 
          onLanguageChange(language, languageLabel);
        
        className="focus:ring-0  mr-5 my-18p default-style radio__input"
      />
      <div className="radio__radio"></div>

CSS

.radio__radio 
  width: 24px;
  height: 24px;
  background-color: #d8d8d8;
  border-radius: 50%;
  box-sizing: border-box;
  padding: 6px;
  margin-right: 20px;
  z-index: 1;


.radio__radio::after 
  content: "";
  width: 100%;
  height: 100%;
  display: block;
  background: #f28b46;
  border-radius: 50%;
  transform: scale(0);
  z-index: 9;


【问题讨论】:

你可以使用 CSS-in-Js 库,例如styled-components ***.com/questions/21032481/… @fullstack 谢谢,我会检查一下。让我知道您是否有任何解决方案可以用纯 css 做到这一点? 【参考方案1】:

虽然您不能直接在 JS 中设置伪元素的样式,但您可以设置一个 CSS 变量,这可以通过伪元素的类设置来获取。

.radio__radio 
  width: 24px;
  height: 24px;
  background-color: #d8d8d8;
  border-radius: 50%;
  box-sizing: border-box;
  padding: 6px;
  margin-right: 20px;
  z-index: 1;
  --bg: #f28b46; /* ADDED for initial condition */


.radio__radio::after 
  content: "";
  width: 100%;
  height: 100%;
  display: block;
  background: var(--bg);
  border-radius: 50%;
  transform: scale(0);
  z-index: 9;

然后在你的 javascript 中获得新的背景颜色:

document.querySelector('.radio__radio').style.setProperty('--bg', newvalue);

或者当然选择所有这些单选按钮,如果需要的话,为每个按钮进行更改。

【讨论】:

这里的元素. radio__radio是未定义的。我正在使用反应顺便说一句。 DOM 没有加载,我猜这只是意味着。 我明白了(我认为!) - 显然,在加载之前您无法访问该元素,当某些 API 为您提供新的颜色以供使用时,我假设您正在访问它。也许您需要向我们展示相关的 JS。 它是相关的。问题很清楚,我从 API 获得了一个名为 brand_color 的变量。它给出了十六进制颜色,我想在我的 CSS 中使用该十六进制颜色。 你能展示一下 JS - 获得品牌颜色的位吗?您是否在等待 DOM 加载(或至少是创建元素的位)? 我得到的数据来自getSettings 一个动作调用并在页面加载时在useEffect() 中调度。真的很抱歉我的回复迟了【参考方案2】:

问题是你不能在 javascript 中操作伪元素;但是,仍然有几个选项可以通过连锁效应来操纵它们。

选项 1:按照 A Haworth 的建议,使用 CSS 变量。

选项 2:如果您知道只有几种不同的颜色;然后你可以切换一个类,指示它应该是哪种颜色。例如,如果您将 CSS 设置为与此类似的结构:

.radio__radio 
  width: 24px;
  height: 24px;
  background-color: #d8d8d8;
  border-radius: 50%;
  box-sizing: border-box;
  padding: 6px;
  margin-right: 20px;
  z-index: 1;


.radio__radio::after 
  content: "";
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 50%;
  transform: scale(0);
  z-index: 9;


.radio__radio.green::after
   background-color: #000066 /* Silly colour as an example */

.radio__radio.blue::after
   background-color: #006600 /* Silly colour as an example */

.radio__radio.red::after
   background-color: #660000 /* Silly colour as an example */

然后你的javascript

var d = document.getElementsByClassName("radio__radio"); /* This way supports older browsers */
d.className += " otherclass";

或者如果使用 jQuery

$('.radio__radio').addClass('green').removeClass('red').removeClass('blue');

如果不使用 javascript 作为中间人,我不知道您无法直接从您的 API 注入运行时变量 - 可能有一种方法可以使用 Blazor,但我还没有遇到它。

【讨论】:

【参考方案3】:

您可以使用 CSS 自定义属性作为颜色的变量,使用 :root 类:

:root 
  --brand-color: #f28b46;


.radio__radio 
  width: 24px;
  height: 24px;
  background-color: #d8d8d8;
  border-radius: 50%;
  box-sizing: border-box;
  padding: 6px;
  margin-right: 20px;
  z-index: 1;


.radio__radio::after 
  content: "";
  width: 100%;
  height: 100%;
  display: block;
  background: var(--brand-color);
  border-radius: 50%;
  // transform: scale(0);
  z-index: 9;
&lt;div class="radio__radio"&gt;&lt;/div&gt;

当从 API 获取品牌颜色时,创建一个样式标签并更新 :root 品牌颜色。

注意:最后一个 :root 变量将覆盖任何之前的 :root 变量,因此您需要确保在初始 CSS 文件之后使用品牌颜色创建 &lt;style&gt;

:root 
  --brand-color: yellow; // will be overridden

:root 
  --brand-color: red; // that's the color that will show

我知道你正在使用 react,所以你可以这样做:

const [brandColor, setBrandColor] = useState();

useEffect( () => 
    fetchBrandColorFromAPI().then(brandColor => setBrandColor(brandColor));
, [])

然后在渲染器中:

brandColor && <style dangerouslySetInnerHTML= __html: ` :root 
    --brand-color: $brandColor
` /> 

【讨论】:

【参考方案4】:

<!DOCTYPE html>
<html>

<head>
    <title>
        How to define colors as variables in CSS?
    </title>
    <style>
        :root 
            --primary-color: rgb(15, 157, 88);
            --secondary-color: rgb(255, 255, 255);
        

        .first 
            width: 50%;
            padding: 40px 0px;
            margin: 10px 0px;
            text-align: center;

            /* Apply color using CSS var */
            background-color: var(--primary-color);
            color: var(--secondary-color);
        

        .second 

            width: 50%;
            padding: 40px 0px;
            text-align: center;

            /* Apply color using CSS var */
            background-color: var(--primary-color);
            color: var(--secondary-color);
        
    </style>
</head>

<body>
    <div class="first">
        <h1>***</h1>
    </div>

    <div class="second">
        <h1>gyan-js</h1>
    </div>
</body>

</html>

【讨论】:

【参考方案5】:

我是 React 新手,所以我将使用 Vannila JS 提供答案。

颜色变化可以通过以下步骤完成:

设置一个根css变量:root --myColor: #545454; 将 DOM 元素的颜色设置为在根中声明的 css 变量,如 color: var(--myColor); 由于您提到该元素尚未加载,因此myColor 具有什么颜色没有意义,因为它除了变量本身之外没有影响,因为我们将在 JS 中使用它来更改它。 在 JS 中,从 API 响应中获取颜色并将其存储在变量中 使用document.documentElement将css变量myColor的颜色设置为我们从API获取的颜色 所有具有 CSS 变量颜色的元素也会发生变化。 此时被加载的元素将具有颜色。

// I couldn't find a fake API response giving a Color, so this function mocks the API which gives the color string after 2 seconds.
let getColorFromAPI = new Promise((resolve) => 
    setTimeout(function() 
        resolve('#FFFFFF')
    , 2000)
);


async function main() 
    console.log("The Existing Color is: ", getComputedStyle(document.documentElement).getPropertyValue('--mainColor'))
    console.log('Getting the Color from the API... ')
    let newColor = await getColorFromAPI // Get the color from API
    console.log('The New Color is: ', newColor)
    document.documentElement.style.setProperty('--mainColor', newColor) // Changing the color of the CSS variable


main()
:root 
    --mainColor: #545454;


.buttonElement 
    background-color: var(--mainColor);
&lt;button class="buttonElement"&gt;See the Color of this button&lt;/button&gt;

总结一下:

该函数从 API 获取颜色,我们使用document.documentElement.style.setProperty 设置颜色

您也可以只使用背景颜色创建一个虚拟类并将其附加到元素上,因为浏览器会使用最新的 CSS 样式声明来计算样式。

希望这会有所帮助。

【讨论】:

【参考方案6】:

有一次我遇到了类似的问题,我实际上是通过使用另一个 div 元素而不是伪元素来解决的。如果这不适用于您的特定用例,我深表歉意,因为您说您想使用伪元素。但是,由于您似乎可以访问 JS、JSX 和 CSS,因此您可以考虑这样做。

before 和 after 伪元素几乎等同于作为父元素的第一个或最后一个子元素放置的 div 元素,因此像这样添加另一个 div

<div className="radio__radio">
   <div 
      className="radio__radio__after"
      style= backgroundColor: apiColor || '#f28b46' 
   ></div>
</div>

并像这样更改您的第二个 CSS 选择器

.radio__radio__after 
  content: "";
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 50%;
  transform: scale(0);
  z-index: 9;

允许由 style 属性控制背景颜色应该可以工作 - 尽管您可能需要对 CSS 或 JSX 进行一些细微的调整。

【讨论】:

【参考方案7】:

最好和最简单的方法是在 JSX 代码中添加样式。

<input
id=languageLabel
type="radio"
name="language-select"
value=languageLabel
// defaultChecked=index === 0
onChange=() => 
  onLanguageChange(language, languageLabel);

className="focus:ring-0  mr-5 my-18p default-style radio__input"
/>

只需将此部分添加到您的 JSX 文件中

<style>
    `
        .radio__radio::before 
        background-color: $settings.brand_color
        
    `
</style>

【讨论】:

以上是关于如何在 css 文件中使用 API 颜色变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 css 类名中使用 javascript 变量并在 Rails 中通过 jquery 获取 css 颜色名

如何将引导颜色作为css中的变量引用?

less样式如何使用cssmodule

如何使用类似于 SASS 的 darken() 的 CSS 变量创建颜色阴影?

如何使用类似于 SASS 的 darken() 的 CSS 变量创建颜色阴影?

如何将不透明度应用于 CSS 颜色变量?