Is it possible to use calc()
function in CSS to manipulate hexadecimal color value?
In following CSS snippet I would like to use --enable
variable to switch between two hexadecimal color values for background-color
property of the MyBtnStyle: --enable-color
and --disable-color
.
It was possible to accomplish this when using rgb(r,g,b)
color format where each color component was computed using calc()
, but I would prefer to directly switch between hexadecimal color values.
:root {
--enable: 0;
--disable-color: #ff0000;
--disable-r: 255;
--disable-g: 0;
--disable-b: 0;
--enable-color: #00ff00;
--enable-r: 0;
--enable-g: 255;
--enable-b: 0;
}
.MyBtnStyle {
width: 100%;
height: 100%;
text-align: center;
border: 2px;
margin: 1px 1px;
color: black;
padding: 1px 1px;
background-color: calc(var(--enable-color)*var(--enable) + var(--disable-color)*(1 - var(--enable)));
}
/* this works */
/* rgb( calc(var(--enable-r)*var(--enable) + var(--disable-r)*(1 - var(--enable)) ),
calc(var(--enable-g)*var(--enable) + var(--disable-g)*(1 - var(--enable)) ),
calc(var(--enable-b)*var(--enable) + var(--disable-b)*(1 - var(--enable)) )) */
You cannot multiply hex values like You are doing. A trick is to use gradient and control the percentage of colors. This will work with any color format:
:root {
--enable: 0;
--disable-color: red;
--enable-color: #00ff00;
}
.MyBtnStyle {
text-align: center;
margin: 5px;
color: black;
padding:20px;
background:
linear-gradient(
var(--enable-color) calc(100% * var(--enable)),
var(--disable-color) calc(100% * var(--enable)),
var(--disable-color) calc(100% * (1 - var(--enable)))
);
}
<div class="MyBtnStyle" style="--enable:1">some text</div>
<div class="MyBtnStyle">some text</div>
Here is another syntax where you adjust the background-size
:
:root {
--enable: 0;
--disable-color: red;
--enable-color: #00ff00;
}
.MyBtnStyle {
text-align: center;
margin: 5px;
color: black;
padding:20px;
background:
linear-gradient(var(--enable-color),var(--enable-color)),
var(--disable-color);
background-size:100% calc(100% * var(--enable))
}
<div class="MyBtnStyle" style="--enable:1">some text</div>
<div class="MyBtnStyle">some text</div>
Here is another idea inspired from this answer where you can apply color to text or any other property and not only background. This trick works with hsl()
coloration.
:root {
--enable: 0;
--disable-color: red;
--enable-color: #00ff00;
}
.MyBtnStyle {
text-align: center;
margin: 5px;
color: hsl(0,100%, calc((1 - var(--enable))*100%));
border:3px solid hsl(120,100%, calc((1 - var(--enable))*50%));
padding:20px;
background:
linear-gradient(var(--enable-color),var(--enable-color)),
var(--disable-color);
background-size:100% calc(100% * var(--enable))
}
<div class="MyBtnStyle" style="--enable:1">some text</div>
<div class="MyBtnStyle">some text</div>
This can be useful in order to have full control on the contrast. We change the background color and the text color at the same time. It's easy between black and white colors (or two version of the same colors) since we have to only control the lightness.
To express any combination of two colors simply rely on the code in the question where we define rgb()
colors
Another related question to get more tricks: How to change the color of <div> Element depending on its height using CSS?