Как применить непрозрачность к переменной цвета CSS?

я разрабатываю приложение в electron, поэтому у меня есть доступ к переменным CSS. Я определил переменную цвета в vars.css:

:root {
  --color: #f0f0f0;
}

Я хочу использовать этот цвет в main.css, но с некоторой непрозрачностью:

#element {
  background: (somehow use var(--color) at some opacity);
}

как бы я это сделал? Я не использую препроцессор, только CSS. Я бы предпочел ответ all-CSS, но я приму JavaScript / jQuery.

Я не могу использовать opacity потому что я использую фоновое изображение, которое не должно быть прозрачный.

8 ответов


вы не можете взять существующее значение цвета и применить к нему альфа-канал. А именно, вы не можете взять существующее шестнадцатеричное значение, такое как #f0f0f0, дайте ему Альфа-компонент и используйте полученное значение с другим свойством.

однако пользовательские свойства позволяют конвертировать шестнадцатеричное значение в триплет RGB для использования с rgba(), сохраните это значение в пользовательском свойстве (включая запятые!), подставим это значение с помощью var() на с желаемым Альфа-значение, и это будет просто работать:

:root {
  /* #f0f0f0 in decimal RGB */
  --color: 240, 240, 240;
}

body {
  color: #000;
  background-color: #000;
}

#element {
  background-color: rgba(var(--color), 0.5);
}
<p id="element">If you can see this, your browser supports custom properties.</p>

это кажется слишком хорошим, чтобы быть правдой.1 как это работает?

магия заключается в том, что значения пользовательских свойств замещенных как при замене var() ссылки в стоимости имущества, до вычисляется значение этого свойства. Это означает, что, что касается пользовательских свойств, значение --color в вашем примере-это не цвет значения до a var(--color) выражение появляется где-то, что ожидает, что значение цвета (и только в этом контексте). От 2.1 спецификации css-переменных:

разрешенный синтаксис для пользовательских свойств является чрезвычайно разрешительным. Продукция соответствует любой последовательности одного или нескольких токенов, если последовательность не содержит , , unmatched ,, или, или токены верхнего уровня или токены со значением "!".

например, допустимым пользовательским свойством является следующее:

--foo: if(x > 5) this.width = 10;

хотя это значение явно бесполезно в качестве переменной, поскольку оно было бы недопустимым в любом нормальном свойстве, оно может быть прочитано и обработано JavaScript.

и 3:

если a свойство содержит одну или несколько функций var (), и эти функции синтаксически допустимы, грамматика всего свойства должна считаться допустимой во время синтаксического анализа. Он проверяется только синтаксисом во время вычисляемого значения после замены функций var ().

это означает, что 240, 240, 240 значение, которое вы видите выше, подставляется непосредственно в rgba() функции до объявление вычисляется. Так вот:

#element {
  background-color: rgba(var(--color), 0.5);
}

что сначала не кажется допустимым CSS, потому что rgba() ожидает не менее четырех числовых значений, разделенных запятыми, становится следующим:

#element {
  background-color: rgba(240, 240, 240, 0.5);
}

что, конечно, вполне допустимо для CSS.

сделав еще один шаг, вы можете сохранить Альфа-компонент в своем собственном пользовательском свойстве:

:root {
  --color: 240, 240, 240;
  --alpha: 0.5;
}

и заменить его, с тем же результатом:

#element {
  background-color: rgba(var(--color), var(--alpha));
}

это позволяет вам иметь различные Альфа-значения, которые вы можете поменять местами на ходу.


1Ну, это, если вы запустите код в браузере, который не поддерживает пользовательские свойства.


Я знаю, что OP не использует препроцессор, но мне бы помогло, если бы следующая информация была частью ответа здесь (я пока не могу комментировать, иначе я бы прокомментировал ответ @BoltClock.

Если вы используете, например, 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>

обратите внимание, что интерполяция строк не будет работать для функций scss без CSS, таких как lighten(), потому что полученный код не будет функциональным CSS. Это все равно будет действительным scss, поэтому вы не получите никакой ошибки в компиляции.


этой действительно возможно с 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>

в CSS вы должны иметь возможность использовать значения rgba:

#element {
  background: rgba(240, 240, 240, 0.5);
}

или просто установите непрозрачность:

#element {
  background: #f0f0f0;
  opacity: 0.5;    
}

вы можете задать определенную переменную/значение для каждого цвета - оригинал и один с прозрачностью:

: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>

:root{
--color: 255, 0, 0;
}

#element{
    background-color: rgba(var(--color), opacity);
}

где вы заменяете непрозрачность чем-либо между 0 и 1


Если вы любите шестнадцатеричные цвета, как я есть другое решение. Шестнадцатеричное значение-это 6 цифр после Альфа-значения. 00-100% прозрачность 99 составляет около 75%, затем он использует алфавит "a1-af", затем "b1-bf", заканчивающийся "ff", который на 100% непрозрачен.

:root {
--color: #F00;
}

#element {
background: var(--color)f6;
}

используя scss, вы можете сделать:

rgba(color($colors, colorVar), 0.5);