Use CSS variables for controlling colors
Currently CSS variables are only defined in dark mode. We should have them in light mode as well for more reliable behavior, and to allow us to get rid of almost-duplicate stylesheets for light and dark modes.
Some discussion from this thread about the split being bad.
The problem
The palette variables that are used in bootstrap, and a bunch of our own SCSS. Anywhere that SCSS color functions (mix
, darken
, color-yiq
, etc) are used will error. We can't do something like $gray-50: --gray-50;
as then we get SCSS compilation errors (the color functions need literals), and there is also scoping differences (order matters for SCSS but not for CSS vars, this is pretty minor though).
Possible solutions
Override SCSS built-ins to handle custom properties
Toying with this in !71523 (closed)
Basically we define our own functions for lighten
, darken
, mix
, and color-yiq
, to check argument type and behave differently.
We can reimplement the color functions use CSS variables and calc, or define suffixed-alternate variables, or (most likely) some combination of both.
An example
@function darken($color, $amount) {
@if is-custom-property($color) {
@return #{$color}-dark-#{$amount};
}
// maybe there is a way to call the original `darken` instead??
@return adjust-color($color, $lightness: -1 * $amount);
}
which you then use like this
:root {
--red: #ff0000;
--red-dark-50: #880000;
}
$red: #ff0000;
// works with SCSS variable
.text-dark-red {
color: darken($red, 50);
// outputs
color: #880000;
}
// or with CSS variable
.text-dark-red {
color: darken(--red, 50);
// outputs
color: var(--red-dark-50);
}
OR we can go even further and split rgb (or hsl) for our color variables, like in this example. This would allow us to reimplement things like mix()
and color-yiq
at runtime.
$red: #ff0000;
:root {
// we declare our colors
--red: $red;
// then these get generated using functions/mixins
--red-hue: hue($red);
--red-saturation: saturation($red);
--red-lightness: lightness($red);
}
.text-dark-red {
color: darken(--red, 50);
// outputs this
color: hsl(
var(--red-hue),
var(--red-saturation),
calc(var(--red-lightness) - 50%)
);
}
Bulk replace of our SCSS vars with CSS variables
We could find/replace all of our own variable usages with SCSS ones. Simplifies the task (for our own CSS at least), and means the SCSS looks kinda like the compiled form (too much SCSS trickery can be bad for searchability).
Cons:
- lots of manual work
- if it's a straight find/replace we lose the chance for more semantically meaningful variables (
--color-link-text
vs the current$blue-500
) - This would still require keeping light/dark (and the separate palette variables) for bootstrap. So we'd generate/export separate
bootstrap_light
andbootstrap_dark
CSS files (or maybe even for gitlab-ui).
Also need to update dark mode dev docs on this - see !50131 (comment 510496141)