Bootstrap: Feature: support var(--variables) with fallback for runtime change

Created on 26 Jan 2018  路  12Comments  路  Source: twbs/bootstrap

We have in :root a map of variables with can be use by default in all elements/components with proper fallback.
Can we add another $support-css4 to generate additional fallback styles?
This feature can be added later in roadmap if docs aren't stable right now.

Example:

.swatch-blue {
    color: #fff;
    background-color: #007bff;
}

to:

.swatch-blue {
    color: #fff;
    background-color: #007bff;
    background-color: var(--blue);
}

Benefits:

  • works same as before
  • new way to change color in runtime!
  • can be change by js in one place to enable fast change of parameters
  • can be enabled by setting

$support-runtime-variable or $support-css4

(or something like that)

  • this feature expand to not only colors but breakpoints and other properties

Need to:

  • check if some browser incorrect implement that feature
  • invert colors can be tricky

How to do that in clever way and I added benefit of this approach:
https://codepen.io/anon/pen/XVLvLQ

Better idea:

  • create some tool like autoprefixer to enable it by default without bloat code. But add documentation about that solution on site so no new issue will be generated.

Documentation and credits for amazing work:
https://getbootstrap.com/docs/4.0/getting-started/theming/#color
https://css-tricks.com/difference-between-types-of-css-variables/

css v4

Most helpful comment

Being able to easily change the theme colors at runtime would be a very neat feature.

Let me know if I can help write a PR to add support.

All 12 comments

There is a PostCSS plugin that does change var declerarations, it could be useful

This PostCSS plugin indeed do something but it don't understand connection between variables and connected properties. It won't change fixed value to global variable. After some investigation you will find that no tool currently support fallback module like I wrote. This variable will be good for showing example of template (all theme in envato market).

Being able to easily change the theme colors at runtime would be a very neat feature.

Let me know if I can help write a PR to add support.

I was able to successfully use CSS variables to support runtime theming for things like $body-color:

$body-color: var(--body-color);

So now you can alter the value of --body-color on the root element with JS (or by settting a theme CSS class that applies them).

But when trying to use that approach with e.g. buttons it doesn't work because they use functions like darken on the values:

$secondary: var(--secondary);
      background-color: darken($color, 10%) !important;
                       ^
      Argument `$color` of `darken($color, $amount)` must be a color
Backtrace:
   node_modules/bootstrap/scss/mixins/_background-variant.scss:12, in function `darken`
   node_modules/bootstrap/scss/mixins/_background-variant.scss:12, in mixin `@content`
   node_modules/bootstrap/scss/mixins/_hover.scss:21, in mixin `hover-focus`
   node_modules/bootstrap/scss/mixins/_background-variant.scss:11, in mixin `bg-variant`
   node_modules/bootstrap/scss/utilities/_background.scss:4
      in node_modules/bootstrap/scss/mixins/_background-variant.scss (line 12, column 25)

I looked into this too @felixfbecker and realized the same thing. The Sass functions at compile time prevent a really good solution for the moment.

It would require a thoughtful refactoring to support. Open to any suggestions from a Bootstrap / Sass expert.

When / if blend lands in CSS this would be a easier change: https://www.w3.org/TR/css-color-4/#blend-adjuster

Thanks for sharing that spec, this will be incredibly useful!

But in the meantime, is there a solution where Bootstrap allows to customize the hover colors through variables/maps and only _defaults_ them to the darkened values? Or somehow checks if they are a custom property?

I found out that these components can be themed with CSS vars (because they don't use compile-time color manipulation):

  • Links ($link-color, $link-hover-color)
  • Forms ($input-, $input-btn-, ...)

While these cannot:

  • Buttons
  • Alerts
  • Tables

@felixfbecker are many colors associated with Buttons, Alerts, and Tables respectively? Could the compile time manipulation be extracted into variables that are passed into the mixins?

btn-background
btn-hover-background
etc...

Would this make runtime color manipulation more feasible?

Yeah that would work perfectly for me. From what I saw the compile time color manipulation is mostly just darkening one step for hover effects. And alerts could also easily be configured with Sass variables instead of color manipulation. It is probably even possible to still default these variables to the color manipulation.

If that's possible, you could propose adding all these color variants as variables in _root.scss to the :root pseudo class. Then add a mixin that pulls from the global :root color variables if present otherwise from the $ sass variables to generate the CSS at compile time.

I think that won鈥檛 work because you can鈥檛 detect at compile time whether a (runtime) CSS var is set, and it doesn鈥檛 have to be set on :root.
But it should be possible to simply introduce the extra Sass variables for hover etc. and let the user set them to a CSS var.

Closing out as not a bug and not a feature request we can take on right now. I think we're better served in v4's lifespan by focusing first on Sass variables and then CSS as a first class come v5 or so.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

IamManchanda picture IamManchanda  路  3Comments

leomao10 picture leomao10  路  3Comments

matsava picture matsava  路  3Comments

eddywashere picture eddywashere  路  3Comments

devfrey picture devfrey  路  3Comments