Is there a way, using only CSS, to change the background colour of cells based on the value in them?
To illustrate this, I'm trying to replicate the effect of Excel conditionally formated values:
If possible, it would be great to be able to interpolate between 2 or 3 colours.
Absolutely!
As long as you're okay with using CSS variables, it is more than possible to have 2 or 3 colour gradients.
You can use CSS color-mix
and CSS variables to achieve a color mix based on a variable value.
Use the following CSS:
.highlight-color {
--min: 0;
--max: 1;
--incs: oklch;
--value: 0.5;
--high-color: #F8696B;
--middle-color: #FFEB84;
--low-color: #63BE7B;
}
.highlight-color .highlightme {
/* This is where the magic happens */
--normed: calc(100% * (var(--value) - var(--min))/(var(--max) - var(--min)));
}
.highlight-color.highlight-2color .highlightme {
background-color: color-mix(
in var(--incs),
var(--high-color) var(--normed),
var(--low-color)
);
}
.highlight-color.highlight-3color .highlightme {
--n1: calc((var(--normed) - 50%) * 2);
--n2: calc(var(--normed)*2);
background-color: color-mix(
in var(--incs),
color-mix(in var(--incs), var(--high-color) var(--n1), var(--middle-color)) var(--normed),
color-mix(in var(--incs), var(--middle-color) var(--n2), var(--low-color))
);
}
and then the following HTML:
<table>
<tbody>
<tr class="highlight-color highlight-3color" style="--min: 0; --max: 1;">
<td class="highlightme" style="--value: 0.00;">0.00</td>
<td class="highlightme" style="--value: 0.07;">0.07</td>
<td class="highlightme" style="--value: 0.14;">0.14</td>
<td class="highlightme" style="--value: 0.21;">0.21</td>
<td class="highlightme" style="--value: 0.29;">0.29</td>
<td class="highlightme" style="--value: 0.36;">0.36</td>
<td class="highlightme" style="--value: 0.43;">0.43</td>
<td class="highlightme" style="--value: 0.50;">0.50</td>
<td class="highlightme" style="--value: 0.57;">0.57</td>
<td class="highlightme" style="--value: 0.64;">0.64</td>
<td class="highlightme" style="--value: 0.71;">0.71</td>
<td class="highlightme" style="--value: 0.79;">0.79</td>
<td class="highlightme" style="--value: 0.86;">0.86</td>
<td class="highlightme" style="--value: 0.93;">0.93</td>
<td class="highlightme" style="--value: 1.00;">1.00</td>
</tr>
</tbody>
</table>
And you should get the following:
You can also use the following Javascript to automatically set the CSS values:
document.querySelectorAll('.autohighlight').forEach(el => {
const values = [];
const els = el.querySelectorAll('.highlightme');
els.forEach(vel => {
values.push(vel.innerText / 1);
vel.style.setProperty('--value', vel.innerText / 1);
});
const max = Math.max(...values);
const min = Math.min(...values);
el.style.setProperty('--min', min);
el.style.setProperty('--max', max);
});