2016-10-13 3 views
20

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

:root { 
    --color: #f0f0f0; 
} 

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

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

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

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

+0

Так звучит, что вы должны использовать более одного элемента .... – epascarello

+0

Я бы предпочел не делать этого, но мне кажется, мне нужно ... :( – JoshyRobot

ответ

35

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

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

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

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

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

Разрешенный синтаксис для настраиваемых свойств чрезвычайно разрешительный. Произведение декларации-значения соответствует любой последовательности одного или нескольких токенов, если последовательность не содержит < bad-string-token>, < bad-url-token>, непревзойденный <) -token>, <] - токен>, или <} -token>, или верхний уровень < Точка с точкой с запятой> токены или < delim-token> жетоны со значением "!".

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

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

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

И section 3:

Если свойство содержит один или несколько вара() функцию, и эти функции синтаксический действительно, грамматика всей собственности должен считаться действительным во время синтаксического анализа. Он проверяется только синтаксисом при вычисленном значении времени, после замены функций 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)); 
} 

Это позволяет иметь различные альфа-значения, которые вы можете менять на лету.


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

+3

Это прекрасное – Roberrrt

+1

@ Roberrrt: Это то, что я должен был осознать на самом деле, на самом деле, увидев, как я опубликовал [эти] (http://stackoverflow.com/questions/37442603/how-to-use-commas-in- a-css-variable-fallback/37443195 # 37443195) [ответы] (http://stackoverflow.com/questions/38751778/is-it-possible-to-use-css-custom-properties-in-values-for- the-content-property/38751906 # 38751906) ранее. – BoltClock

+0

Тем не менее, это действительно полезно, возможен ли такой же принцип с SCSS/Less/Sass? – Roberrrt

0

В CSS вы должны быть в состоянии использовать либо значения RGBA:

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

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

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

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

0

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

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

Если вы не можете использовать это, и вы нормально с раствором яваскрипта, вы можете использовать это один:

$(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>

+0

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

+0

Проверьте обновление для js solution – Dekel

1

Это действительно возможно с помощью 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 { 
 
\t width: 100px; 
 
\t height: 100px; 
 
\t margin: 10px; 
 
} 
 
    
 
    
 
.element1 { 
 
\t background: 
 
     linear-gradient(var(--white-low-opacity), var(--white-low-opacity)) no-repeat, 
 
\t linear-gradient(var(--red), var(--red)) no-repeat; 
 
} 
 

 
.element2 { 
 
\t background: 
 
     linear-gradient(var(--white-high-opacity), var(--white-high-opacity)) no-repeat, 
 
\t linear-gradient(var(--red), var(--red)) no-repeat; 
 
} 
 
    
 
.element3 { 
 
\t background: 
 
     linear-gradient(var(--black-low-opacity), var(--black-low-opacity)) no-repeat, 
 
\t linear-gradient(var(--red), var(--red)) no-repeat; 
 
} 
 

 
.element4 { 
 
\t background: 
 
     linear-gradient(var(--black-high-opacity), var(--black-high-opacity)) no-repeat, 
 
\t 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>

+0

Вам не нужно указывать размер фона - градиенты не имеют собственного значения и будут автоматически растягиваться в результате. – BoltClock

+0

@BoltClock Да, я буквально думал об этом, когда я разместил его, это было просто немного поиграть в костепен;). Убрали сейчас, спасибо! – Roberrrt

+0

Это умно, я не думал о том, чтобы накладывать сплошные градиенты друг на друга, когда я ответил на [аналогичный вопрос] (http://stackoverflow.com/questions/29591465/use-css-variables-with-rgba-for -градиент-прозрачность) в прошлом году. Этот вопрос, вероятно, более общий, так, как он был написан, тот, на который я ответил, был очень конкретным вариантом использования. – BoltClock

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

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

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

+0

Является ли это попыткой ответить на вопрос? Потому что, если это так, код действительно не имеет смысла. В частности, бит 'rgba (var (- color), opacity). Тем более, что ваше значение свойства - это полная запись rgb(). Но также из-за ключевого слова «непрозрачность». – BoltClock

+0

woops my bad rgb частей не должно быть в var –

2

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

Если вы используете, например, scss, ответ выше будет терпеть неудачу, потому что scss пытается скомпилировать стили с помощью scss-specific rgba()/hsla(), которая требует 4 параметра. Однако rgba()/hsla() также являются встроенными функциями css, поэтому вы можете использовать string inter чтобы обходить функцию scss.

Пример (действуют в дерзости 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, поэтому вы не получите ошибки в компиляции.

Смежные вопросы