我正在设计一个电子应用程序,所以我可以访问 CSS 变量。我在 vars.css
中定义了一个颜色变量:
:root {
--color: #f0f0f0;
}
我想在 main.css
中使用这种颜色,但应用了一些不透明度:
#element {
background: (somehow use var(--color) at some opacity);
}
我该怎么做呢?我没有使用任何预处理器,只有 CSS。我更喜欢全 CSS 的答案,但我会接受 JavaScript/jQuery。
我不能使用 opacity
,因为我使用的背景图像不应该是透明的。
您不能采用现有的颜色值并将 Alpha 通道应用到它。也就是说,您不能将现有的十六进制值(例如 #f0f0f0
)赋予它一个 alpha 分量并将结果值与另一个属性一起使用。
但是,自定义属性允许您将十六进制值转换为用于 rgba()
的 RGB 三元组,将该值存储在自定义属性中(包括逗号!),使用 var()
将该值替换为 rgba()
函数您想要的 alpha 值,它会起作用:
:root { /* #f0f0f0 十进制 RGB */ --color: 240, 240, 240; } 身体 { 颜色: #000;背景颜色:#000; } #element { 背景颜色:rgba(var(--color), 0.8); }
如果你能看到这个,你的浏览器支持自定义属性。
这似乎好得令人难以置信。1 它是如何工作的?
神奇之处在于,当替换属性值中的 var()
引用时,按原样替换自定义属性的值,在计算该属性的值之前。这意味着就自定义属性而言,您示例中的 --color
值根本不是颜色值直到 var(--color)
表达式出现在某个需要颜色值的地方(并且仅在这种情况下)。来自 css-variables 规范的 section 2.1:
自定义属性的允许语法非常宽松。
例如,以下是有效的自定义属性: --foo: if(x > 5) this.width = 10;虽然这个值作为变量显然是无用的,因为它在任何普通属性中都是无效的,但它可能会被 JavaScript 读取和操作。
如果属性包含一个或多个 var() 函数,并且这些函数在语法上有效,则必须假定整个属性的语法在解析时有效。在 var() 函数被替换后,它仅在计算值时进行语法检查。
这意味着您在上面看到的 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 好吧,如果您在不支持自定义属性的浏览器中运行代码片段。
我知道 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 { /* 这是有效的 CSS,但在 scss 编译中会失败 */ background-color: rgba(var(--color_rgb), 0.5); /* 这是有效的 scss,会生成上面的 CSS */ background-color: #{'rgba(var(--color_rgb), 0.5)'}; }
请注意,字符串插值不适用于非 CSS scss 函数,例如 lighten()
,因为生成的代码不是函数式 CSS。不过它仍然是有效的 scss,因此您在编译时不会收到任何错误。
@function rgb($args...) { @return #{'rgb(#{$args})'}; }
@function rgba($args...) { @return #{'rgba(#{$args})'}; }
@function hsl($args...) { @return #{'hsl(#{$args})'}; }
{ 4}````
rgba
是 rgb
的同义词已经有一段时间了。因此您可以去掉“a”。
:root { @each $color, $value in $colors { --#{$color}_rgb: #{red($value), green($value), blue($value)}; } }
sass
包,此解决方法似乎不再需要
我遇到了类似的情况,但不幸的是,给定的解决方案对我不起作用,因为变量可以是从 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;
}
样式可能需要稍作更改,具体取决于应应用背景的元素。此外,它可能不适用于所有情况,但希望它在某些情况下有所帮助,因为其他解决方案无法使用。
编辑:我刚刚注意到,这个解决方案显然也会影响文本颜色,因为它会在目标元素前面创建一个元素并对其应用透明背景颜色。在某些情况下,这可能是一个问题。
rgb
或 HSL
)的优点,而且还避免了原生 CSS 颜色函数和 Sass 的颜色函数之间的任何冲突。请参阅下面的SimplyPhy's answer。
:before
,这样您就可以在不使用 z-index
的情况下获得正确的堆叠顺序。
相对颜色语法
借助这种允许颜色格式转换的新 CSS 功能 (css-color-5),它还允许为任何格式的任何颜色添加不透明度,例如,添加到 RGB
(相对转换可以以任何其他格式完成):
html { --color: blue }
.with-opacity { background: rgb(from var(--color) r g b / 50%) }
(在撰写本文时,尚未在浏览器中可用。将在到达后更新)
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);
}
希望这可以节省一些时间。
这确实可以通过 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 { 宽度:100px;高度:100px;边距:10px; } .element1 { 背景:线性渐变(var(--white-low-opacity),var(--white-low-opacity))无重复,线性渐变(var(--red),var(- -red)) 不重复; } .element2 { 背景:线性渐变(var(--white-high-opacity),var(--white-high-opacity))无重复,线性渐变(var(--red),var(- -red)) 不重复; } .element3 { 背景:线性渐变(var(--black-low-opacity),var(--black-low-opacity))无重复,线性渐变(var(--red),var(- -red)) 不重复; } .element4 { 背景:线性渐变(var(--black-high-opacity),var(--black-high-opacity))无重复,线性渐变(var(--red),var(- -red)) 不重复; }
如果您使用深色和浅色模式,我使用此示例。我更喜欢将颜色和 rgb 颜色变量分配分开。所以我每个循环使用两个。我意识到这个解决方案不是干代码。如果你想干代码,你可以使用一个循环。
$colors-light:(白色:#fff,黑色:#0c0d0e,橙色:#f48024,绿色:#5eba7d,蓝色:#0077cc,红色:#d1383d,red-100:#e2474c,red-200:红色,) ; $colors-dark:(黑色:#fff,白色:#2d2d2d,橙色:#dd7118,绿色:#5eba7d,蓝色:#0077cc,红色:#aa1c21,red-100:#c9292e,red-200:红色,) ; @function hexToRGB($hex) { @return red($hex), green($hex), blue($hex); } @mixin generate_colors($colors) { // 颜色 @each $color, $value in $colors { @if str-slice(#{$value}, 1, 1) == "#" { --#{$颜色}: #{$value}; } @else { --#{$color}: var(--#{$value}); } } // RGB 颜色 @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) { // 颜色,RGB 颜色 @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; --黑色:#0c0d0e; --RGB_black: 12, 13, 14; --橙色:#f48024; --RGB_橙色:244、128、36; --绿色:#5eba7d; --RGB_green:94、186、125; --蓝色:#0077cc; --RGB_blue: 0, 119, 204; --红色:#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; --白色:#2d2d2d; --RGB_white:45、45、45; --橙色:#dd7118; --RGB_橙色:221、113、24; --绿色:#5eba7d; --RGB_green:94、186、125; --蓝色:#0077cc; --RGB_blue: 0, 119, 204; --红色:#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); } 身体 { 背景颜色: var(--white); } .colors { 显示:-webkit-box;显示:-ms-flexbox;显示:弯曲; -webkit-box-orient:水平; -webkit-box-direction:正常; -ms-flex-direction:行;弹性方向:行; -ms-flex-wrap:换行;弹性包装:换行; -webkit-box-pack:开始; -ms-flex-pack:开始;证明内容:弹性开始; -webkit-box-align:居中; -ms-flex-align:居中;对齐项目:居中;边距:50px 0 0 30px; } .box { 宽度:100px;高度:100px;右边距:5px; } .black { 背景颜色:var(--black); } .white { 背景颜色:var(--white); } .orange { 背景颜色:var(--orange); } .green { 背景颜色:var(--green); } .blue { 背景颜色:var(--blue); } .red { 背景颜色:var(--red); } .red-200 { 背景颜色:var(--red-200); } .black-rgba { 背景颜色:rgba(var(--RGB_black), 0.5); } .white-rgba { 背景颜色:rgba(var(--RGB_white), 0.5); } .orange-rgba { 背景颜色:rgba(var(--RGB_orange), 0.5); } .green-rgba { 背景颜色:rgba(var(--RGB_green), 0.5); } .blue-rgba { 背景颜色:rgba(var(--RGB_blue), 0.5); } .red-rgba { 背景颜色:rgba(var(--RGB_red), 0.5); } .red-rgba-200 { 背景颜色:rgba(var(--RGB_red-200), 0.5); }
$colors-light: ( 'color-primary': #2F302F, 'color-primary-variant': #4E4E4E,
您可以使用 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;高度:100px;边框:2px 实心#000; --黑客:10000%;背景:线性渐变(到底部,var(--color)计算((var(--opacity)-1)* var(--hack)),透明计算(var(--opacity)* var(--黑客))); } #container { 背景图像:线性渐变(45deg,#b0b0b0 25%,透明 25%),线性渐变(-45deg,#b0b0b0 25%,透明 25%),线性渐变(45deg,透明 75% , #b0b0b0 75%), 线性渐变(-45deg, 透明 75%, #b0b0b0 75%);背景尺寸:20px 20px;背景位置:0 0、0 10px、10px -10px、-10px 0px;填充:10px;显示:内联块; }
:root{
--color: 255, 0, 0;
}
#element{
background-color: rgba(var(--color), opacity);
}
将不透明度替换为 0 到 1 之间的任何值
rgba(var(--color), opacity)
位。特别是因为您的自定义属性值是整个 rgb() 表示法。也是因为“不透明”关键字。
您可以为每种颜色设置特定的变量/值 - 原始颜色和具有不透明度的颜色:
:root { --color: #F00; --颜色不透明度:rgba(255, 0, 0, 0.5); } #a1 { 背景:var(--color); } #a2 { 背景:var(--color-opacity); }
如果你不能使用这个并且你可以使用 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 { 背景:var(--color); } #a2 { 背景:var(--color); }
如果你像我一样喜欢十六进制颜色,还有另一种解决方案。十六进制值是 6 位数字,之后是 alpha 值。 00 是 100% 的透明度 99 是大约 75% 然后它使用字母 'a1-af' 然后 'b1-bf' 以 'ff' 结尾,它是 100% 不透明的。
:root {
--color: #F00;
}
#element {
background: var(--color)f6;
}
var(--color)f6
不起作用(在这种情况下产生的值将是 #f0f0f0 f6
,这是无效的)。我的成功工作结果是使用 Vue3 并引用 js 导入的颜色属性,例如:`background-color: v-bind(this.colourHex + 'f6');` 为混淆道歉。
要将 rgba() 与通用 css 变量一起使用,请尝试以下操作:
在 :root 中声明你的颜色,但不要像其他答案那样使用 rgb()。只写值
:root{ --color : 255,0,0; }
使用 --color 变量使用 var() 作为其他答案
#some-element { 颜色 : rgba(var(--color),0.5); }
在 CSS 中,您应该能够使用 rgba 值:
#element {
background: rgba(240, 240, 240, 0.5);
}
或者只是设置不透明度:
#element {
background: #f0f0f0;
opacity: 0.5;
}
不定期副业成功案例分享
"240, 240, 240"
无法使用颜色选择器进行编辑。当您需要为您的 GUI 找到正确的颜色时,这是一个巨大的失误。color: rgb(var(--color), .4)
。但我发现这个 SOQ 的原因是因为以下 不 工作::root { --hex-color: "#333333"; } element { background: var(--hex-color)99 /*this should be alpha 60%*/ }
,但不知何故,这两个字符串没有加入#33333399
,这将工作。var(--hex-color)99
被转换为两个标记#333333 99
(注意分隔标记的空间),这显然不是你想要的。自定义属性最初被定义为复制标记,而不是字符串,这是最终结果。现在解决这个问题为时已晚。