如何将不透明度应用于 CSS 颜色变量?
How do I apply opacity to a CSS color variable?
我正在用 electron 设计一个应用程序,所以我可以访问 CSS 个变量。我在 vars.css
:
中定义了一个颜色变量
:root {
--color: #f0f0f0;
}
我想在 main.css
中使用这种颜色,但应用了一些不透明度:
#element {
background: (somehow use var(--color) at some opacity);
}
我该怎么做?我没有使用任何预处理器,只使用 CSS。我更喜欢全 CSS 的答案,但我会接受 JavaScript/jQuery.
我不能使用 opacity
因为我使用的背景图片不应该是透明的。
在 CSS 中,您应该可以使用 rgba 值:
#element {
background: rgba(240, 240, 240, 0.5);
}
或者只设置不透明度:
#element {
background: #f0f0f0;
opacity: 0.5;
}
您可以为每种颜色设置特定的 variable/value - 原始颜色和不透明度:
:root {
--color: #F00;
--color-opacity: rgba(255, 0, 0, 0.5);
}
#a1 {
background: var(--color);
}
#a2 {
background: var(--color-opacity);
}
<div id="a1">asdf</div>
<div id="a2">asdf</div>
如果你不能使用这个并且你可以使用 javascript 解决方案,你可以使用这个:
$(function() {
$('button').click(function() {
bgcolor = $('#a2').css('backgroundColor');
rgb_value = bgcolor.match(/\d+,\s?\d+,\s?\d+/)[0]
$('#a2').css('backgroundColor', 'rgba(' + rgb_value + ', 0.5)');
});
});
:root {
--color: #F00;
}
#a1 {
background: var(--color);
}
#a2 {
background: var(--color);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a1">asdf</div>
<div id="a2">asdf</div>
<button>Click to change opacity</button>
这个确实可以用CSS实现。它只是有点脏,你必须使用渐变。我编写了一个小片段作为示例,请注意,对于深色背景,您应该使用黑色不透明度,至于光 - 白色。:
:root {
--red: rgba(255, 0, 0, 1);
--white-low-opacity: rgba(255, 255, 255, .3);
--white-high-opacity: rgba(255, 255, 255, .7);
--black-low-opacity: rgba(0, 0, 0, .3);
--black-high-opacity: rgba(0, 0, 0, .7);
}
div {
width: 100px;
height: 100px;
margin: 10px;
}
.element1 {
background:
linear-gradient(var(--white-low-opacity), var(--white-low-opacity)) no-repeat,
linear-gradient(var(--red), var(--red)) no-repeat;
}
.element2 {
background:
linear-gradient(var(--white-high-opacity), var(--white-high-opacity)) no-repeat,
linear-gradient(var(--red), var(--red)) no-repeat;
}
.element3 {
background:
linear-gradient(var(--black-low-opacity), var(--black-low-opacity)) no-repeat,
linear-gradient(var(--red), var(--red)) no-repeat;
}
.element4 {
background:
linear-gradient(var(--black-high-opacity), var(--black-high-opacity)) no-repeat,
linear-gradient(var(--red), var(--red)) no-repeat;
}
<div class="element1">hello world</div>
<div class="element2">hello world</div>
<div class="element3">hello world</div>
<div class="element4">hello world</div>
您不能采用现有颜色值并对其应用 Alpha 通道。也就是说,您不能采用现有的十六进制值,例如 #f0f0f0
,给它一个 alpha 分量,然后将结果值与另一个 属性.
一起使用
但是,自定义属性允许您将十六进制值转换为 RGB 三元组以用于 rgba()
,将该值存储在自定义 属性 中(包括逗号!),替换该值将 var()
用于具有所需 alpha 值的 rgba()
函数,它将正常工作:
:root {
/* #f0f0f0 in decimal RGB */
--color: 240, 240, 240;
}
body {
color: #000;
background-color: #000;
}
#element {
background-color: rgba(var(--color), 0.8);
}
<p id="element">If you can see this, your browser supports custom properties.</p>
这似乎好得令人难以置信。1它是如何工作的?
神奇之处在于,当替换 属性 值中的 var()
引用时,自定义属性的值被 原样替换 ,在之前属性的值被计算出来。这意味着就自定义属性而言,示例中 --color
的值根本不是颜色值 直到 某处出现 var(--color)
表达式期望颜色值(并且仅在该上下文中)。来自 css 变量规范的 section 2.1:
The allowed syntax for custom properties is extremely permissive. The <declaration-value> production matches any sequence of one or more tokens, so long as the sequence does not contain <bad-string-token>, <bad-url-token>, unmatched <)-token>, <]-token>, or <}-token>, or top-level <semicolon-token> tokens or <delim-token> tokens with a value of "!".
For example, the following is a valid custom property:
--foo: if(x > 5) this.width = 10;
While this value is obviously useless as a variable, as it would be invalid in any normal property, it might be read and acted on by JavaScript.
If a property contains one or more var() functions, and those functions are syntactically valid, the entire property’s grammar must be assumed to be valid at parse time. It is only syntax-checked at computed-value time, after var() functions have been substituted.
这意味着您在上面看到的 240, 240, 240
值直接代入 rgba()
函数 在 声明被计算之前。所以这个:
#element {
background-color: rgba(var(--color), 0.8);
}
起初似乎无效 CSS 因为 rgba()
期望不少于四个以逗号分隔的数值,变成这样:
#element {
background-color: rgba(240, 240, 240, 0.8);
}
这当然是完全正确的 CSS。
更进一步,您可以将 alpha 分量存储在它自己的自定义中 属性:
:root {
--color: 240, 240, 240;
--alpha: 0.8;
}
并替换它,结果相同:
#element {
background-color: rgba(var(--color), var(--alpha));
}
这允许您拥有不同的 alpha 值,您可以随时交换这些值。
1 好吧,如果您 运行 浏览器中的代码片段不支持自定义属性。
:root{
--color: 255, 0, 0;
}
#element{
background-color: rgba(var(--color), opacity);
}
用 0 到 1 之间的任何值替换不透明度
我知道 OP 没有使用预处理器,但如果以下信息是此处答案的一部分,我会得到帮助(我还不能发表评论,否则我会评论@BoltClock 答案。
如果您正在使用,例如scss,上面的答案将失败,因为 scss 尝试使用 scss 特定的 rgba()/hsla() 函数编译样式,该函数需要 4 个参数。不过rgba()/hsla()也是原生的css函数,所以可以使用字符串插值来绕过scss函数
示例(在 sass 3.5.0+ 中有效):
:root {
--color_rgb: 250, 250, 250;
--color_hsl: 250, 50%, 50%;
}
div {
/* This is valid CSS, but will fail in a scss compilation */
background-color: rgba(var(--color_rgb), 0.5);
/* This is valid scss, and will generate the CSS above */
background-color: #{'rgba(var(--color_rgb), 0.5)'};
}
<div></div>
请注意,字符串插值不适用于非 CSS scss 函数,例如 lighten()
,因为生成的代码将无法运行 CSS。它仍然是有效的 scss,所以你在编译时不会收到任何错误。
如果你像我一样喜欢十六进制颜色,还有另一种解决方案。
十六进制值是 6 位数字,之后是 alpha 值。
00 是 100% 透明度 99 大约是 75% 然后它使用字母表 'a1-af' 然后 'b1-bf' 以 'ff' 结尾,这是 100% 不透明。
:root {
--color: #F00;
}
#element {
background: var(--color)f6;
}
我遇到了类似的情况,但不幸的是,给定的解决方案对我不起作用,因为变量可以是从 rgb
到 hsl
到 hex
甚至颜色的任何东西名字。
我现在通过将 background-color
和 opacity
应用于伪 :after
或 :before
元素解决了这个问题:
.container {
position: relative;
}
.container::before {
content: "";
width: 100%;
height: 100%;
position: absolute;
left: 0;
background-color: var(--color);
opacity: 0.3;
}
样式可能需要稍微更改,具体取决于应用背景的元素。
此外,它可能不适用于所有情况,但希望它在某些情况下有所帮助,因为其他解决方案无法使用。
编辑:
我刚刚注意到,这个解决方案显然也会影响文本颜色,因为它会在目标元素前面创建一个元素并为其应用透明背景色。
在某些情况下这可能是个问题。
要将 rgba() 与一般 css 变量一起使用,试试这个:
- 在 :root 中声明你的颜色,但不要像其他答案那样使用 rgb() 。只写值
:root{
--color : 255,0,0;
}
- 使用 --color 变量使用 var() 作为其他答案
#some-element {
color : rgba(var(--color),0.5);
}
SCSS / SASS
优点:您可以只使用十六进制颜色值,而不是为每个通道 (0-255) 使用 8 位。
这就是我最初的想法:https://codyhouse.co/blog/post/how-to-combine-sass-color-functions-and-css-variables
编辑: 您还可以修改 alpha 函数以仅使用 #{$color-name}-rgb
并省略生成的 *-r、*-g、*-b CSS变量。
结果
body {
--main-color: rgb(170, 68, 204);
--main-color-rgb: 170,68,204;
--main-color-r: 170;
--main-color-g: 68;
--main-color-b: 204;
}
.button-test {
// Generated from the alpha function
color: rgba(var(--main-color-r), var(--main-color-g), var(--main-color-b), 0.5);
// OR (you wrote this yourself, see usage)
color: rgba(var(--main-color-rgb), 0.5);
}
用法:
body {
@include defineColorRGB(--main-color, #aa44cc);
}
.button-test {
// With alpha function:
color: alpha(var(--main-color), 0.5);
// OR just using the generated variable directly
color: rgba(var(--main-color-rgb), 0.5);
}
Mixin 和函数
@mixin defineColorRGB($color-name, $value) {
$red: red($value);
$green: green($value);
$blue: blue($value);
#{$color-name}: unquote("rgb(#{$red}, #{$green}, #{$blue})");
#{$color-name}-rgb: $red,$green,$blue;
#{$color-name}-r: $red;
#{$color-name}-g: $green;
#{$color-name}-b: $blue;
}
// replace substring with another string
// credits: https://css-tricks.com/snippets/sass/str-replace-function/
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
@function alpha($color, $opacity) {
$color: str-replace($color, 'var(');
$color: str-replace($color, ')');
$color-r: var(#{$color+'-r'});
$color-g: var(#{$color+'-g'});
$color-b: var(#{$color+'-b'});
@return rgba($color-r, $color-g, $color-b, $opacity);
}
希望这会节省一些时间。
如果你使用深色和浅色模式,我使用这个示例。我更喜欢在颜色和 rgb 颜色变量分配之间分开。所以我每个循环使用两个。我意识到这个解决方案不是干代码。如果你想干代码,你可以使用一个循环。
$colors-light: (
white: #fff,
black: #0c0d0e,
orange: #f48024,
green: #5eba7d,
blue: #0077cc,
red: #d1383d,
red-100: #e2474c,
red-200: red,
);
$colors-dark: (
black: #fff,
white: #2d2d2d,
orange: #dd7118,
green: #5eba7d,
blue: #0077cc,
red: #aa1c21,
red-100: #c9292e,
red-200: red,
);
@function hexToRGB($hex) {
@return red($hex), green($hex), blue($hex);
}
@mixin generate_colors($colors) {
// Colors
@each $color, $value in $colors {
@if str-slice(#{$value}, 1, 1) == "#" {
--#{$color}: #{$value};
} @else {
--#{$color}: var(--#{$value});
}
}
// RGB Colors
@each $color, $value in $colors {
@if str-slice(#{$value}, 1, 1) == "#" {
--RGB_#{$color}: #{hexToRGB($value)};
} @else {
--RGB_#{$color}: var(--RGB_#{$value});
}
}
}
:root {
@include generate_colors($colors-light);
}
[data-theme="dark"] {
@include generate_colors($colors-dark);
}
干码
@mixin generate_colors($colors) {
// Colors, RGB Colors
@each $color, $value in $colors {
@if str-slice(#{$value}, 1, 1) == "#" {
--#{$color}: #{$value};
--RGB_#{$color}: #{hexToRGB($value)};
} @else {
--#{$color}: var(--#{$value});
--RGB_#{$color}: var(--RGB_#{$value});
}
}
}
css输出
:root {
--white: #fff;
--RGB_white: 255, 255, 255;
--black: #0c0d0e;
--RGB_black: 12, 13, 14;
--orange: #f48024;
--RGB_orange: 244, 128, 36;
--green: #5eba7d;
--RGB_green: 94, 186, 125;
--blue: #0077cc;
--RGB_blue: 0, 119, 204;
--red: #d1383d;
--RGB_red: 209, 56, 61;
--red-100: #e2474c;
--RGB_red-100: 226, 71, 76;
--red-200: var(--red);
--RGB_red-200: var(--RGB_red);
}
[data-theme="dark"] {
--black: #fff;
--RGB_black: 255, 255, 255;
--white: #2d2d2d;
--RGB_white: 45, 45, 45;
--orange: #dd7118;
--RGB_orange: 221, 113, 24;
--green: #5eba7d;
--RGB_green: 94, 186, 125;
--blue: #0077cc;
--RGB_blue: 0, 119, 204;
--red: #aa1c21;
--RGB_red: 170, 28, 33;
--red-100: #c9292e;
--RGB_red-100: 201, 41, 46;
--red-200: var(--red);
--RGB_red-200: var(--RGB_red);
}
body {
background-color: var(--white);
}
.colors {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
margin: 50px 0 0 30px;
}
.box {
width: 100px;
height: 100px;
margin-right: 5px;
}
.black {
background-color: var(--black);
}
.white {
background-color: var(--white);
}
.orange {
background-color: var(--orange);
}
.green {
background-color: var(--green);
}
.blue {
background-color: var(--blue);
}
.red {
background-color: var(--red);
}
.red-200 {
background-color: var(--red-200);
}
.black-rgba {
background-color: rgba(var(--RGB_black), 0.5);
}
.white-rgba {
background-color: rgba(var(--RGB_white), 0.5);
}
.orange-rgba {
background-color: rgba(var(--RGB_orange), 0.5);
}
.green-rgba {
background-color: rgba(var(--RGB_green), 0.5);
}
.blue-rgba {
background-color: rgba(var(--RGB_blue), 0.5);
}
.red-rgba {
background-color: rgba(var(--RGB_red), 0.5);
}
.red-rgba-200 {
background-color: rgba(var(--RGB_red-200), 0.5);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div>
<input type="checkbox" id="dark-switch" name="theme" />
<label for="dark-switch">Dark / Light</label>
</div>
<div class="color-box">
<div class="colors">
<div class="box red-200"></div>
<div class="box black"></div>
<div class="box white"></div>
<div class="box orange"></div>
<div class="box green"></div>
<div class="box blue"></div>
<div class="box red"></div>
</div>
<br>
<h1>RGBA</h1>
<div class="colors">
<div class="box red-rgba-200"></div>
<div class="box black-rgba"></div>
<div class="box white-rgba"></div>
<div class="box orange-rgba"></div>
<div class="box green-rgba"></div>
<div class="box blue-rgba"></div>
<div class="box red-rgba"></div>
</div>
</div>
<script>
const dark_switch = document.getElementById("dark-switch");
dark_switch.addEventListener("change", (e) => {
e.target.checked
? document.documentElement.setAttribute("data-theme", "dark")
: document.documentElement.setAttribute("data-theme", "light");
});
</script>
</body>
</html>
您可以使用 linear-gradient
修改颜色:
background: linear-gradient(to bottom, var(--your-color) -1000%, var(--mixin-color), 1000%)
$(() => {
const setOpacity = () => {
$('#canvas').css('--opacity', $('#opacity-value').val())
}
const setColor = () => {
$('#canvas').css('--color', $('#color-value').val());
}
$('#opacity-value').on('input', setOpacity);
$('#color-value').on('input', setColor);
setOpacity();
setColor();
})
#canvas {
width: 100px;
height: 100px;
border: 2px solid #000;
--hack: 10000%;
background: linear-gradient( to bottom, var(--color) calc((var(--opacity) - 1) * var(--hack)), transparent calc(var(--opacity) * var(--hack)));
}
#container {
background-image: linear-gradient(45deg, #b0b0b0 25%, transparent 25%), linear-gradient(-45deg, #b0b0b0 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #b0b0b0 75%), linear-gradient(-45deg, transparent 75%, #b0b0b0 75%);
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
padding: 10px;
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="canvas"></div>
</div>
<hr/>
<input type="range" id="opacity-value" min="0" max="1" step="0.1" value="0.5" />
<input type="color" id="color-value" />
Relative color syntax
有了这个允许颜色格式转换的新CSS能力(css-color-5),它也将允许为任何颜色添加不透明度任何格式,例如 RGB
(可以对任何其他格式进行相对转换):
html { --color: blue }
.with-opacity { background: rgb(from var(--color) r g b / 50%) }
(截至撰写本文时,浏览器尚不可用。将在到达后更新)
我正在用 electron 设计一个应用程序,所以我可以访问 CSS 个变量。我在 vars.css
:
:root {
--color: #f0f0f0;
}
我想在 main.css
中使用这种颜色,但应用了一些不透明度:
#element {
background: (somehow use var(--color) at some opacity);
}
我该怎么做?我没有使用任何预处理器,只使用 CSS。我更喜欢全 CSS 的答案,但我会接受 JavaScript/jQuery.
我不能使用 opacity
因为我使用的背景图片不应该是透明的。
在 CSS 中,您应该可以使用 rgba 值:
#element {
background: rgba(240, 240, 240, 0.5);
}
或者只设置不透明度:
#element {
background: #f0f0f0;
opacity: 0.5;
}
您可以为每种颜色设置特定的 variable/value - 原始颜色和不透明度:
:root {
--color: #F00;
--color-opacity: rgba(255, 0, 0, 0.5);
}
#a1 {
background: var(--color);
}
#a2 {
background: var(--color-opacity);
}
<div id="a1">asdf</div>
<div id="a2">asdf</div>
如果你不能使用这个并且你可以使用 javascript 解决方案,你可以使用这个:
$(function() {
$('button').click(function() {
bgcolor = $('#a2').css('backgroundColor');
rgb_value = bgcolor.match(/\d+,\s?\d+,\s?\d+/)[0]
$('#a2').css('backgroundColor', 'rgba(' + rgb_value + ', 0.5)');
});
});
:root {
--color: #F00;
}
#a1 {
background: var(--color);
}
#a2 {
background: var(--color);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a1">asdf</div>
<div id="a2">asdf</div>
<button>Click to change opacity</button>
这个确实可以用CSS实现。它只是有点脏,你必须使用渐变。我编写了一个小片段作为示例,请注意,对于深色背景,您应该使用黑色不透明度,至于光 - 白色。:
:root {
--red: rgba(255, 0, 0, 1);
--white-low-opacity: rgba(255, 255, 255, .3);
--white-high-opacity: rgba(255, 255, 255, .7);
--black-low-opacity: rgba(0, 0, 0, .3);
--black-high-opacity: rgba(0, 0, 0, .7);
}
div {
width: 100px;
height: 100px;
margin: 10px;
}
.element1 {
background:
linear-gradient(var(--white-low-opacity), var(--white-low-opacity)) no-repeat,
linear-gradient(var(--red), var(--red)) no-repeat;
}
.element2 {
background:
linear-gradient(var(--white-high-opacity), var(--white-high-opacity)) no-repeat,
linear-gradient(var(--red), var(--red)) no-repeat;
}
.element3 {
background:
linear-gradient(var(--black-low-opacity), var(--black-low-opacity)) no-repeat,
linear-gradient(var(--red), var(--red)) no-repeat;
}
.element4 {
background:
linear-gradient(var(--black-high-opacity), var(--black-high-opacity)) no-repeat,
linear-gradient(var(--red), var(--red)) no-repeat;
}
<div class="element1">hello world</div>
<div class="element2">hello world</div>
<div class="element3">hello world</div>
<div class="element4">hello world</div>
您不能采用现有颜色值并对其应用 Alpha 通道。也就是说,您不能采用现有的十六进制值,例如 #f0f0f0
,给它一个 alpha 分量,然后将结果值与另一个 属性.
但是,自定义属性允许您将十六进制值转换为 RGB 三元组以用于 rgba()
,将该值存储在自定义 属性 中(包括逗号!),替换该值将 var()
用于具有所需 alpha 值的 rgba()
函数,它将正常工作:
:root {
/* #f0f0f0 in decimal RGB */
--color: 240, 240, 240;
}
body {
color: #000;
background-color: #000;
}
#element {
background-color: rgba(var(--color), 0.8);
}
<p id="element">If you can see this, your browser supports custom properties.</p>
这似乎好得令人难以置信。1它是如何工作的?
神奇之处在于,当替换 属性 值中的 var()
引用时,自定义属性的值被 原样替换 ,在之前属性的值被计算出来。这意味着就自定义属性而言,示例中 --color
的值根本不是颜色值 直到 某处出现 var(--color)
表达式期望颜色值(并且仅在该上下文中)。来自 css 变量规范的 section 2.1:
The allowed syntax for custom properties is extremely permissive. The <declaration-value> production matches any sequence of one or more tokens, so long as the sequence does not contain <bad-string-token>, <bad-url-token>, unmatched <)-token>, <]-token>, or <}-token>, or top-level <semicolon-token> tokens or <delim-token> tokens with a value of "!".
For example, the following is a valid custom property:
--foo: if(x > 5) this.width = 10;
While this value is obviously useless as a variable, as it would be invalid in any normal property, it might be read and acted on by JavaScript.
If a property contains one or more var() functions, and those functions are syntactically valid, the entire property’s grammar must be assumed to be valid at parse time. It is only syntax-checked at computed-value time, after var() functions have been substituted.
这意味着您在上面看到的 240, 240, 240
值直接代入 rgba()
函数 在 声明被计算之前。所以这个:
#element {
background-color: rgba(var(--color), 0.8);
}
起初似乎无效 CSS 因为 rgba()
期望不少于四个以逗号分隔的数值,变成这样:
#element {
background-color: rgba(240, 240, 240, 0.8);
}
这当然是完全正确的 CSS。
更进一步,您可以将 alpha 分量存储在它自己的自定义中 属性:
:root {
--color: 240, 240, 240;
--alpha: 0.8;
}
并替换它,结果相同:
#element {
background-color: rgba(var(--color), var(--alpha));
}
这允许您拥有不同的 alpha 值,您可以随时交换这些值。
1 好吧,如果您 运行 浏览器中的代码片段不支持自定义属性。
:root{
--color: 255, 0, 0;
}
#element{
background-color: rgba(var(--color), opacity);
}
用 0 到 1 之间的任何值替换不透明度
我知道 OP 没有使用预处理器,但如果以下信息是此处答案的一部分,我会得到帮助(我还不能发表评论,否则我会评论@BoltClock 答案。
如果您正在使用,例如scss,上面的答案将失败,因为 scss 尝试使用 scss 特定的 rgba()/hsla() 函数编译样式,该函数需要 4 个参数。不过rgba()/hsla()也是原生的css函数,所以可以使用字符串插值来绕过scss函数
示例(在 sass 3.5.0+ 中有效):
:root {
--color_rgb: 250, 250, 250;
--color_hsl: 250, 50%, 50%;
}
div {
/* This is valid CSS, but will fail in a scss compilation */
background-color: rgba(var(--color_rgb), 0.5);
/* This is valid scss, and will generate the CSS above */
background-color: #{'rgba(var(--color_rgb), 0.5)'};
}
<div></div>
请注意,字符串插值不适用于非 CSS scss 函数,例如 lighten()
,因为生成的代码将无法运行 CSS。它仍然是有效的 scss,所以你在编译时不会收到任何错误。
如果你像我一样喜欢十六进制颜色,还有另一种解决方案。 十六进制值是 6 位数字,之后是 alpha 值。 00 是 100% 透明度 99 大约是 75% 然后它使用字母表 'a1-af' 然后 'b1-bf' 以 'ff' 结尾,这是 100% 不透明。
:root {
--color: #F00;
}
#element {
background: var(--color)f6;
}
我遇到了类似的情况,但不幸的是,给定的解决方案对我不起作用,因为变量可以是从 rgb
到 hsl
到 hex
甚至颜色的任何东西名字。
我现在通过将 background-color
和 opacity
应用于伪 :after
或 :before
元素解决了这个问题:
.container {
position: relative;
}
.container::before {
content: "";
width: 100%;
height: 100%;
position: absolute;
left: 0;
background-color: var(--color);
opacity: 0.3;
}
样式可能需要稍微更改,具体取决于应用背景的元素。
此外,它可能不适用于所有情况,但希望它在某些情况下有所帮助,因为其他解决方案无法使用。
编辑:
我刚刚注意到,这个解决方案显然也会影响文本颜色,因为它会在目标元素前面创建一个元素并为其应用透明背景色。
在某些情况下这可能是个问题。
要将 rgba() 与一般 css 变量一起使用,试试这个:
- 在 :root 中声明你的颜色,但不要像其他答案那样使用 rgb() 。只写值
:root{
--color : 255,0,0;
}
- 使用 --color 变量使用 var() 作为其他答案
#some-element {
color : rgba(var(--color),0.5);
}
SCSS / SASS
优点:您可以只使用十六进制颜色值,而不是为每个通道 (0-255) 使用 8 位。
这就是我最初的想法:https://codyhouse.co/blog/post/how-to-combine-sass-color-functions-and-css-variables
编辑: 您还可以修改 alpha 函数以仅使用 #{$color-name}-rgb
并省略生成的 *-r、*-g、*-b CSS变量。
结果
body {
--main-color: rgb(170, 68, 204);
--main-color-rgb: 170,68,204;
--main-color-r: 170;
--main-color-g: 68;
--main-color-b: 204;
}
.button-test {
// Generated from the alpha function
color: rgba(var(--main-color-r), var(--main-color-g), var(--main-color-b), 0.5);
// OR (you wrote this yourself, see usage)
color: rgba(var(--main-color-rgb), 0.5);
}
用法:
body {
@include defineColorRGB(--main-color, #aa44cc);
}
.button-test {
// With alpha function:
color: alpha(var(--main-color), 0.5);
// OR just using the generated variable directly
color: rgba(var(--main-color-rgb), 0.5);
}
Mixin 和函数
@mixin defineColorRGB($color-name, $value) {
$red: red($value);
$green: green($value);
$blue: blue($value);
#{$color-name}: unquote("rgb(#{$red}, #{$green}, #{$blue})");
#{$color-name}-rgb: $red,$green,$blue;
#{$color-name}-r: $red;
#{$color-name}-g: $green;
#{$color-name}-b: $blue;
}
// replace substring with another string
// credits: https://css-tricks.com/snippets/sass/str-replace-function/
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
@function alpha($color, $opacity) {
$color: str-replace($color, 'var(');
$color: str-replace($color, ')');
$color-r: var(#{$color+'-r'});
$color-g: var(#{$color+'-g'});
$color-b: var(#{$color+'-b'});
@return rgba($color-r, $color-g, $color-b, $opacity);
}
希望这会节省一些时间。
如果你使用深色和浅色模式,我使用这个示例。我更喜欢在颜色和 rgb 颜色变量分配之间分开。所以我每个循环使用两个。我意识到这个解决方案不是干代码。如果你想干代码,你可以使用一个循环。
$colors-light: (
white: #fff,
black: #0c0d0e,
orange: #f48024,
green: #5eba7d,
blue: #0077cc,
red: #d1383d,
red-100: #e2474c,
red-200: red,
);
$colors-dark: (
black: #fff,
white: #2d2d2d,
orange: #dd7118,
green: #5eba7d,
blue: #0077cc,
red: #aa1c21,
red-100: #c9292e,
red-200: red,
);
@function hexToRGB($hex) {
@return red($hex), green($hex), blue($hex);
}
@mixin generate_colors($colors) {
// Colors
@each $color, $value in $colors {
@if str-slice(#{$value}, 1, 1) == "#" {
--#{$color}: #{$value};
} @else {
--#{$color}: var(--#{$value});
}
}
// RGB Colors
@each $color, $value in $colors {
@if str-slice(#{$value}, 1, 1) == "#" {
--RGB_#{$color}: #{hexToRGB($value)};
} @else {
--RGB_#{$color}: var(--RGB_#{$value});
}
}
}
:root {
@include generate_colors($colors-light);
}
[data-theme="dark"] {
@include generate_colors($colors-dark);
}
干码
@mixin generate_colors($colors) {
// Colors, RGB Colors
@each $color, $value in $colors {
@if str-slice(#{$value}, 1, 1) == "#" {
--#{$color}: #{$value};
--RGB_#{$color}: #{hexToRGB($value)};
} @else {
--#{$color}: var(--#{$value});
--RGB_#{$color}: var(--RGB_#{$value});
}
}
}
css输出
:root {
--white: #fff;
--RGB_white: 255, 255, 255;
--black: #0c0d0e;
--RGB_black: 12, 13, 14;
--orange: #f48024;
--RGB_orange: 244, 128, 36;
--green: #5eba7d;
--RGB_green: 94, 186, 125;
--blue: #0077cc;
--RGB_blue: 0, 119, 204;
--red: #d1383d;
--RGB_red: 209, 56, 61;
--red-100: #e2474c;
--RGB_red-100: 226, 71, 76;
--red-200: var(--red);
--RGB_red-200: var(--RGB_red);
}
[data-theme="dark"] {
--black: #fff;
--RGB_black: 255, 255, 255;
--white: #2d2d2d;
--RGB_white: 45, 45, 45;
--orange: #dd7118;
--RGB_orange: 221, 113, 24;
--green: #5eba7d;
--RGB_green: 94, 186, 125;
--blue: #0077cc;
--RGB_blue: 0, 119, 204;
--red: #aa1c21;
--RGB_red: 170, 28, 33;
--red-100: #c9292e;
--RGB_red-100: 201, 41, 46;
--red-200: var(--red);
--RGB_red-200: var(--RGB_red);
}
body {
background-color: var(--white);
}
.colors {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: start;
-ms-flex-pack: start;
justify-content: flex-start;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
margin: 50px 0 0 30px;
}
.box {
width: 100px;
height: 100px;
margin-right: 5px;
}
.black {
background-color: var(--black);
}
.white {
background-color: var(--white);
}
.orange {
background-color: var(--orange);
}
.green {
background-color: var(--green);
}
.blue {
background-color: var(--blue);
}
.red {
background-color: var(--red);
}
.red-200 {
background-color: var(--red-200);
}
.black-rgba {
background-color: rgba(var(--RGB_black), 0.5);
}
.white-rgba {
background-color: rgba(var(--RGB_white), 0.5);
}
.orange-rgba {
background-color: rgba(var(--RGB_orange), 0.5);
}
.green-rgba {
background-color: rgba(var(--RGB_green), 0.5);
}
.blue-rgba {
background-color: rgba(var(--RGB_blue), 0.5);
}
.red-rgba {
background-color: rgba(var(--RGB_red), 0.5);
}
.red-rgba-200 {
background-color: rgba(var(--RGB_red-200), 0.5);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div>
<input type="checkbox" id="dark-switch" name="theme" />
<label for="dark-switch">Dark / Light</label>
</div>
<div class="color-box">
<div class="colors">
<div class="box red-200"></div>
<div class="box black"></div>
<div class="box white"></div>
<div class="box orange"></div>
<div class="box green"></div>
<div class="box blue"></div>
<div class="box red"></div>
</div>
<br>
<h1>RGBA</h1>
<div class="colors">
<div class="box red-rgba-200"></div>
<div class="box black-rgba"></div>
<div class="box white-rgba"></div>
<div class="box orange-rgba"></div>
<div class="box green-rgba"></div>
<div class="box blue-rgba"></div>
<div class="box red-rgba"></div>
</div>
</div>
<script>
const dark_switch = document.getElementById("dark-switch");
dark_switch.addEventListener("change", (e) => {
e.target.checked
? document.documentElement.setAttribute("data-theme", "dark")
: document.documentElement.setAttribute("data-theme", "light");
});
</script>
</body>
</html>
您可以使用 linear-gradient
修改颜色:
background: linear-gradient(to bottom, var(--your-color) -1000%, var(--mixin-color), 1000%)
$(() => {
const setOpacity = () => {
$('#canvas').css('--opacity', $('#opacity-value').val())
}
const setColor = () => {
$('#canvas').css('--color', $('#color-value').val());
}
$('#opacity-value').on('input', setOpacity);
$('#color-value').on('input', setColor);
setOpacity();
setColor();
})
#canvas {
width: 100px;
height: 100px;
border: 2px solid #000;
--hack: 10000%;
background: linear-gradient( to bottom, var(--color) calc((var(--opacity) - 1) * var(--hack)), transparent calc(var(--opacity) * var(--hack)));
}
#container {
background-image: linear-gradient(45deg, #b0b0b0 25%, transparent 25%), linear-gradient(-45deg, #b0b0b0 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #b0b0b0 75%), linear-gradient(-45deg, transparent 75%, #b0b0b0 75%);
background-size: 20px 20px;
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
padding: 10px;
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="canvas"></div>
</div>
<hr/>
<input type="range" id="opacity-value" min="0" max="1" step="0.1" value="0.5" />
<input type="color" id="color-value" />
Relative color syntax
有了这个允许颜色格式转换的新CSS能力(css-color-5),它也将允许为任何颜色添加不透明度任何格式,例如 RGB
(可以对任何其他格式进行相对转换):
html { --color: blue }
.with-opacity { background: rgb(from var(--color) r g b / 50%) }
(截至撰写本文时,浏览器尚不可用。将在到达后更新)