如何在 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;
<div class="radio__radio"></div>
当从 API 获取品牌颜色时,创建一个样式标签并更新 :root
品牌颜色。
注意:最后一个 :root 变量将覆盖任何之前的 :root 变量,因此您需要确保在初始 CSS 文件之后使用品牌颜色创建 <style>
。
: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);
<button class="buttonElement">See the Color of this button</button>
总结一下:
该函数从 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 颜色名
如何使用类似于 SASS 的 darken() 的 CSS 变量创建颜色阴影?