I like sass variables and they're great during buildtime. But projects that need a microfrontend architecture (i.e. webcomponents) tend not to rebuild components. They rather reuse existing components and provide the style context to it.
Using CSS variables will allow to provide runtime configuration for styling, such as colors. CSS variables can work in conjunction of SASS.
I'm happy with a few the first couple of CSS variables in bootstrap, but as already mentioned they're only exposed and not used by bootstrap itself. This means, if a project likes to override these CSS variables at runtime, there's no effect with the bootstrap components themself.
Is there anything against going into the CSS variable direction? Browser support is really great and the fallback option will keep non-supported browsers happy.
I understand this is a big change though. It woudl work like this:
Intialize CSS vars. We use use double-double fallback to ensure we have a fallack and do not need to repeately add the fallback everywhere.
:root {
--primary: var(--primary-color, #{$primary});
}
Then for each and every component that uses the primary color, we could use the --primary variable instead. For example on a button, it would go like this (just a few lines that i'm using in my sandbox project, so its not so relevant to bootstrap sources):
.btn {
&-primary {
background-color: var(--primary);
border-color: var(--primary);
&:hover,
&:not(:disabled):not(.disabled):active {
background-color: var(--primary-darken);
border-color: var(--primary-darken);
}
}
}
This would allow to change the color at runtime.
Bootstrap supports IE10 & IE11 which don't support CSS Variables (Custom Properties), I'm afraid we can't do this right now.
Understood that support for IE10/11 still is important. What about introducing a fallback. We could have a mixin that would generate both the fallback as well as the custom property.
@mixin customProperty($name, $value) {
// fallback for older browser who do not support custom properties / css variables
#{$name}: #{$value};
// create a css variable (this might override the variable on any of the ancestor elements)
--#{$name}: #{$value};
// use the css variable on the property
#{$name}: var(--#{$name}, #{$value});
}
Alternatively we could use postcss but I'm personally not so much in favor of that since it doesn't allow to use those properties outside the root scope.
Could you provide a demo of how you would use that mixin?
Hi @MartijnCuppens,
I'd use it like this:
In a selector call the mixin:
.any-selector {
@include customProperty('color', #{$primary});
}
This would give the following output, with $primary set to #ffffff;
.any-selector {
color: #ffffff
--color: #ffffff;
color: var(--color, #ffffff);
}
In addition, we could make the fallback optional, by introducing a sass variable.
btw, it's just a quick example.
Hmm, and what is the benefit of that? Aren't you always overwriting the variable?
Custom properties will give a lot of benefits to the code base (you might want to have a look at https://www.youtube.com/watch?v=2an6-WVPuJU), but in the context of this ticket I'm mainly interesting in extendibility. Especially for projects that run in the cloud and should allow to override some variables (i.e. primary color) without a rebuild of the code.
Besides extensibility (which is big word for just configuring the vars), it also allows for easy upgradability.
Hi @tobi-or-not-tobi I love CSS variables, but @MartijnCuppens has a good point, since they are not supported on IE11, it'd be a huge effort to change every declaration to be a mixin, not to mention that we the sass abstraction would get too far away from real CSS in my opinion.
I know this will not solve your usecase, but the first step we are taking towers custom properties is exposing our color pallet as CSS variables:
https://github.com/twbs/bootstrap/blob/v4-dev/scss/_root.scss
@mdo Maybe we can add using css variables as an idea for v5?
Thanks @andresgalante. I'm aware of the variables being exposed (and that's great), but it unfortunately doesn't allow to override them at runtime. The compatibility concerns make sense though.
What about using something like that: https://github.com/malyw/css-vars. Abstraction not too far from CSS, and there is option to generate and load separate file for browsers which do not support CSS variables.
I'm afraid we can't just use a mixin to mimic the exact behaviour of CSS variables. Also bootstrap uses a lot of darken()
and lighten()
sass functions, which can't be applied to CSS variables. There is also the color-yiq
function which determines the text color based on the background-color of buttons (that's why the text color of the warning button is dark on the bootstrap docs) which won't work anymore.
If we find a solution for this, we could think about generously implementing them in v5 only if IE support is dropped.
(btw, sorry for being the party pooper here 😉)
The lack of darken
, lighten
and color-yig
like functions in vanilla CSS doesn't need to be a show stopper here imho. Those functions can and should still be used at build time, and could be in addition exposed as color variants, i.e. --primary-darken
.
Library consumers can configure those variants at _build time_ as they're used to, but in case they want to use runtime configuration (or extend without rebuilding), they will be responsible for configuring those custom properties technique that suits them. Javascript comes to mind, but even existing HSL color system would already work. Whenever CSS color-mod comes around, it will be more convenient.
(btw, sorry for being so persistent here 😉 – I understand the concerns, but want to think in solutions before dropping the whole idea altogether)
@NormSukhrob I guess we first need to wait whether bootstrap wants to move into this direction or not. Then the technical implementation can be done, personally I think using an external dependency for such a small thing is a bit of an overkill, but its good inspiration.
It was just an example of some flexible solution.
CSS variables great modern feature, and as most popular frontend library, bootstrap shouldn't escape usage of it. IMHO
As suggested, developers could have a choice using vars in runtime or just in build time. Yes, some workarounds or better solutions will be needed, like your suggestion using *-darken
or with additional *-darken
, *-lighten
maps which can be by default computed from darken()
and lighten()
functions for build time option in separate computed variables file, which can be different for runtime and build time usages. Even for build time usage it will give more control over colors for devs.
I believe, nowadays, with a popularity of frameworks like angular, react and etc., flexibility and dynamic features in great demand.
Hope, bootstrap team will make steps toward CSS variables.
P.S. and very hope that we will not have to wait v5))))))
Replacing lighten() and darken() in SASS could be done with using hsl() colors.
See https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#hsl()
And it works from IE8 onwards. https://msdn.microsoft.com/en-us/library/hh781508(v=vs.85).aspx#colors
@andresgalante would be this part of v4
or actually v5
I am saying because of the label v4
that you added.
For this to be able to make it into production we need to drop support for IE, which I totally support, because few of us still care about IE shouldn't mean we need to be lock down in time until they want to convert or take business decisions (we still having marquee tags in the core browser cores, we will never get there if we wait for them).
No plans to rearchitect all of the codebase to do this. It'd be a significant investment and involve rewriting just about everything.
Like every single version of Boostrap that you break backwards compatibility and because you rearchitect everything.
Don’t take it personally but it is the truth.
So I don’t see how you could use that argument to be honest. Specially that you don’t need to rearchitect that much (progressive enhancement exists)
@yordis Last time I rewrote everything, it took me over three years to do it :). My hope for v5 was not to fundamentally change the project, but to do a less disruptive change. My point isn't that this cannot happen, but it would take a breaking change (aka, major) release to do it and a lot of time.
@mdo do I get it right that the vision is that CSS custom properties are not for Bootstrap?
The runtime configurability of CSS custom properties over build-time configurability are huge, imho. Webapps are going to change with smaller reusable webcomponents, using view encapsulation that _cannot_ be controlled with a global css. Cloud native applications prefer configurability over extensibility.
Imagine we would change the primary color for an app with a large number of webcomponents. Without CSS custom properties, it means that we need to rebuild and redeploy all the webcomponents (assuming primary color is used everywhere) and clients can no longer use the cached components (which is so important . Moreover, the components are not reusable as the CSS is baken into the component.
Using CSS custom properties is going to make a much better story. Web components can be reused by multiple apps; CSS custom properties _do_ pass the encapsulated shadow DOM by design; changing CSS custom properties do not require a new build, deployment and the components do not need to be evicted from caches.
@mdo has been a long trip with Bootstrap and being grateful for your work, but I believe you are being stubborn on this one.
CSS Variables are 100% supported on green browsers and the global usage is quite enough for saying that we should start embracing the technology.
Keeping v5 without major updates shouldn’t be the goal, like I said Bootstrap has been breaking changes every major release and everyone is aware of that.
I do not believe that the rearchitecture has to be that bad, specially that must of the source code is well known and written so far.
Progressive enhancement always exists and we could slowly upgrade the framework to be 100% CSS variables with all the good practices in the future.
Sorry, but I can see any valid point for not doing it. I would take the initiative of written the spec of the changes and the roadmap and implement it if you want.
I don’t want to create another Bootstrap and having to deal with marketing the framework. I would love to see you change your mind.
Just put in perspective the implications of not doing this agains your thoughts right now.
Isn't it possible for you to distribute a 2nd file, something like bootstrap.customproperties.css
?
This way it doesn't have to brake any existing websites.
Just give us the option.
Or use something similar to this polyfill - https://github.com/jhildenbiddle/css-vars-ponyfill. I tested it in one of my recent projects and it worked really well. Possibly even load it only in IE 10/11 only to avoid additional JS in modern browsers.
Inspired by this issue, I figured that it's possible to take the existing bootstrap CSS, parse all colors, figure out the color palette and replace all colors with variables. I wrote a blog post about it in a little more detail:
https://medium.com/@Hermanhasawish/how-i-repainted-bootstrap-without-sass-d789f41aa74b
@Hermanya Do You have source scss files?
@piernik as I replied on medium, I don't have a source scss file, because I'm not relying on scss to generate the color palette. With this css file from my blog post, you can set a bunch of css variables with color codes generated using a tool like https://hermanya.github.io/palette/ or https://palx.jxnblk.com
I cannot agree more with @yordis on this one. 2020 and Bootstrap isn't using CSS variables yet? It sucks that such an awesome proposal gets closed without any valid reason, considering it's leading most web development being the most used framework everywhere, yet it falls short on features like these.
The implementation should not be too hard, I found these links with great useful info - in fact, I worked on something last night to use CSS variables and so far it's working well. The downside is that I have to specify all overrides in a separace scss file. Sucks but hey, CSS variables are used.
Here's some food for thought: https://codyhouse.co/blog/post/how-to-combine-sass-color-functions-and-css-variables
@Hermanya 's post was greatly useful as well, but it leverages on the postprocessed code to apply the variables. Maybe a post-css-loader can be written or something, but that'd be for webpack users or things like that. IMHO, I think that bootstrap and the browsers are already mature enough to support CSS variables out-of-the-box with just a few changes, as already demonstrated by the codyhouse link.
It'd be great if you guys can change your mind. As Yordis said, I don't want to make another bootstrap and deal with all the stuff around it, but attitudes like these sometimes don't give you much choice. You should listen to your users, to your community, just like Docker just did.
The color-yiq
function seems to be the bottleneck here, since the lightness of var(--color)
is unknown when compiling scss. Maybe someone comes up with some magic calc()
of hsl values to solve this?
If it can help anyone, I wrote this gist which is an effort to handle custom properties in combination with bootstrap.scss. It’s not perfect yet, so please test this in your environment before use in production. It consists basically of converting your colors to hsl and applying transformations on those values. JS can help you converting hex and rgb to hsl.
Update 2019-03-24: I solved the color-yiq
problem in the latest version of my gist (follow my bootstrap import order to make this work!).
sass variables are not dynamic, css variables are. This is helpful when working on features such as darkmode.
Please allow theming by css variables defined outside of bootstrap.css
Let's do this. Not sure what approach we should take, we have lot's of shades of the primary
color for example and have to find a way to deal with all these shades.
I made an attempt here to bypass some bootstrap and sass functions to be able to use _custom properties_. Basically, I replicated each function which turned out to be problematic* to understand values like hsl(var(--primary-h), var(--primary-s), var(--primary-l))
since they are the easiest to work with in terms of changing the color values using calc()
. However, I guess it would be too strict as a requirement to define all color values in hsl, unless there is a way to fix _that_.
_*Problematic functions like lighten
, darken
, mix
and color-yiq
expect their params to be color values instead of --var
._
Relying on lightness might not be the best idea since the palette can be a little unpredictable, see https://codepen.io/joshmcrty/pen/OVZbBr
@MartijnCuppens I would love to help you with the execution of this, but I am not sure how we could sync up and where to start writing a proposal to some execution plan.
We could just open ourselves to random PRs, but it will require a lot of back and forward since multiple people could be conflicting with each other.
Personally, I would replace one-to-one SASS variables per component before tackling big files that may have a huge impact but it would slow the PR review process and harder to prevent bugs.
Related to: #30494
I agree with @yordis and are also willing to help with this. I don't think changing the variables one-to-one per component is bad. It's actually a good, procedural approach to it.
I have a solution somewhat ready that doesn't require changing variables or overriding functions in bootstrap. I'll share a repo or gist soon :)
Be careful there: CSS custom properties are not a replacement for Sass variables.
They can be very useful for components variants to prevent duplication in generated output (@MartijnCuppens is using them for Tables in #30466 for example) or to play with some context on runtime (like say, data-*
attribute values or whatever).
But replacing font-weight: 300
by font-weight: var(--fw-300);
or whatever is a nonsense to me: this is just longer and really benefits from being customized on the Sass-side.
@twbs/css-review I think we should define a clear position about this, before crumbling under custom properties related PR.
Be careful there: CSS custom properties are not a replacement for Sass variables.
Indeed! Not planning to convert our whole _variables.scss
to custom properties.
This is not going to be an easy job, we got to figure out have to combine the powers of Sass and custom properties.
@ffoodd While I do agree, if I may chip in, in my case I'm developing an Angular app that heavily uses bootstrap and it allows customization by the user for their different clients, so they can have, in my case, their brand colors in the interface.
Using CSS variables has proven to be really useful in the sense that the app doesn't have to be recompiled to add either "skins" or support a limited color set (and also bloating the source code) and instead use CSS variables for colors only.
I don't think that using them is "bad" at all. I don't see anything wrong with using a CSS variable with font sizes though, if you want to provide an accessibility feature, some users (like my mom) don't know the hotkeys for increasing font size so a small drop-down for changing that without reloading the page (performance-wise, it makes sense!) Is very appreciated. Heck, even Stack Overflow implemented dark mode with a small toggle. The docker docs also do this as well. It would be just natural that bootstrap supports CSS variables in 2020. If Ionic can do it and keep up with the latest trends, why bootstrap can't?
Also, happy to see this is not a proposal anymore but a task :) will share the gist tomorrow!
I don't think that using them is "bad" at all.
Neither do I :D
But some use cases are — mostly those increasing code bloat and making millions of users downloading too much code, don't you agree?
Bootstrap will (and is starting) to use custom properties, that's a fact. No debate there.
However let me walk through your examples
Branding your app UI is a great idea (done this too) and using custom properties sure is the way to go — I also suggest using an input type=color
and localStorage
for this ;) — however that's not a Bootstrap feature: what you're suggesting would result in an increased Bootstrap's file size to match your very specific need, thus make every other Bootstrap user load more code without any need for them. We can't do that, obviously.
However using a customized Bootstrap doesn't prevent you from using custom properties as values in _variables.scss
, and setting them roughly in _root.scss
. Which won't bloat your code that much, given that this is an important feature for your project.
Relying on a dropdown to change font-size is weird (seriously, Firefox gives you zoom control beside the address bar) but let's go: even for this specific need, custom properties wouldn't be the way to go. Bootstrap completely relies on rem
unit (which is fluid) and RFS (which is great ;)): given that this dropdown should zoom in or out your UI, it'd only take you to change the :root
font-size.
So using custom properties everywhere would be way much heavier than simply changing root font-size.
Well, this one is probably a very good candidate — you may find somes issues and PRs about dark mode (mostly on a component basis), but will defintely need a deeper reflexion now that we can use custom properties.
We'll have to make this step-by-step, but Bootstrap v5 will keep on using custom properties :)
I assume the big issue there is no support for color modification like it is in SASS in css3
Be careful there: CSS custom properties are _not_ a replacement for Sass variables.
- Sass variables are pre-processed, custom properties are not: this means Sass variables bloat the source code whereas custom properties bloat the generated output, that is bad.
It's not bad the benefits totally outweigh the few bytes it will add to the CSS.
- Sass variables can thus be used to customize Bootstrap on build time and deliver static optimized assets, whereas custom properties are applied on runtime in the browser, which is possibly negligible but conceptually bad;
- custom properties are inherited, which should be carefully used: extremely powerful, but could lead to style leaks too.
I do not understand that styleleaks issue at this point but. Bootstrap already has decided to prefix CSS vars with --bs
. The fact that they are inherited is actually very good! It creates new and awesome opportunities to have variations of components ...
They can be very useful for components variants to prevent duplication in generated output (@MartijnCuppens is using them for Tables in #30466 for example) or to play with some context on runtime (like say,
data-*
attribute values or whatever).
And you know that already. But only highlight bad, badbad ...
One of the best reasons to do basically all vars in CSS would be Dark Mode. It would actually need more CSS then just have separate themes and load a different file based on user dark more setting. But I would prefer a simpler and easier dark mode. With SCSS variables simply switch on dark mode media query.
I am a bit confused how this is supposed to go forward. I looked at https://github.com/twbs/bootstrap/pull/30466 and its seems to be about reducing the variant code, great but why nest the variables on .table
. This way they can not be reused elsewhere.
How about simply creating all CSS vars in :root {
? Please do not argue with CSS bloat. Bootstrap was never about being minimalistic with all the utility classes ... Apart from that I do not think it will actually take up that many bytes to do this. It's not bloat if it's actually very useful.
My suggestion would be to simply write over almost all SCSS vars to CSS vars into :root {
but maybe keep _variables.scss
as it at least for v4 as people rely on SCSS code based on those. For v5 maybe consider actually removing variables that are not needed. What are the issues/blocks?
In v5 _variables.scss
lighten()
is actually only used 2 times. Darken 5 times. I am sure this can be done with a PostCSS without ever really looking. But the question is, is it really needed? There is a customizer coming. If could actually just calculate those in plain JS and then just print out fixed colors, maybe with a comment like // this is color xxxx darkened xx%
.
What about just using split up hsl()
colors and then a variable like. --bs-table-hover-color-lightness: 80%;
is this possible? Never tried this, may be just overcomplicate things to just keeping both or using postCSS maybe better?
Obviously things to generate the grid need to stay in scss, but I am wondering if many if not almost all SCSS vars can be actually dropped. But maybe its just easier to keep them in case later something is needed in SCSS? The actual CSS calc()
can be used to things as well like halving paddings and simple things that BS currently uses SCSS for. This way simple themes are not just about colors and can be prototyped fast. The new customizer can have a limited live preview without having to use an in browser SCSS compiler.
W8, actually there is this Idea out for v5 to create a new flex based grid, maybe no complicated grid generation needed at all in the future. I can see Bootstrap using SCSS basically only for nesting and file organization in the future.
Just thinking out loud here, not proposing anything else than just create all CSS vars in :root{
. And actually use them in the other files. What would happen if https://github.com/twbs/bootstrap/pull/30495/files would be PRed again? Another insta rejection? What has changed now?
About different shades of colors. Why not multiple color variations? --bs-blue-100
(almost black), --bs-blue-200
, --bs-blue-900
(almost white) and so on.
Creating those in scss wouldn't be a problem.
Problem with manipulating colors in browser could be easily resolved with javascript
. You pick only 500
variant and js
would calculate remaining variants.
Bootstrap team could create such js
library and website owners (if want to privide UI with color customization) can use it.
What would happen if https://github.com/twbs/bootstrap/pull/30495/files would be PRed again? Another insta rejection? What has changed now?
@nextgenthemes they burned me out, took the time to propose something #30494 to end up talking about nonsensical and obvious things; assuming that I am stupid or something?!
Stuck in analysis paralysis and trying to answer all the questions instead of letting the code to answer the questions for them 🤷
Good luck with the adventure.
Tons of progress has been made on Bootstrap's source code outside this issue, so let's not lose site of the fact that we've already implemented tons of CSS variables :). We're doing it because only recently did we fully drop IE11 support in v5; at the start of this issue around two years ago, v5 wasn't even on our radar.
Okay, with that out of the way, here's the other gotcha—v5 will not be a massive departure from v4. As such, Sass is the preprocessor of choice, so for now, this is about finding a balance between Sass and CSS vars. We'll continue to have that mindset through v5, and perhaps in v6 abandon Sass if the stars align.
Addressing some other points raised here:
We won't be using JS to adjust what CSS/Sass can do for us now, so no thanks to the JS modified colors :).
@yordis Your PR was closed because the complete transition from Sass to CSS vars adds at least 1,000 lines of CSS before minification. _variables.scss
is 1,200+ lines. Coupled with the goal of making v4 to v5 transitions easier, we're not interested in a full transition at this time.
Moreover, moving the .display-
Sass vars to CSS vars comes at the cost of using Sass maps to generate these classes. I'm sure something exists for PostCSS to accomplish this as well, but at this time, a hybrid approach is preferred and more powerful.
We likely could remove all of the lighten()
and darken()
functions with a little bit of clever engineering. We'll keep looking into that.
CSS vars fallbacks are great—love them overall and just wrote a short blog post about some experiments with them as a way to control global options. It's not perfect, and can't be used in every situation, but it's definitely interesting.
As @MartijnCuppens and @ffoodd have mentioned, we're definitely pushing on using CSS vars for components and utilities where we can. I also think we can do more with color utilities and component modifiers, so expect some changes there as well.
Bottom line is we're hoping to find a balance. Help us out by pointing out where customization without compilation would be a huge boost to your productivity and more. I'd love to keep chipping away at this and keep the project evolving like everyone else would prefer :).
Hope that helps!
Personally when I think custom css props, I think size and color.
Also, as a random proposition, if css custom properties will be used for coloring, there might be a use for pre-made theming classes, generated through sass (like inverted colors, or dimmer colors).
+1
I need to create ability to switch a theme for the users on the fly. With css variables it will be very simple but now I will to find another solution....
The most impactful step Bootstrap could take towards this in v5 would be removing usages of darken()
et al and allowing those to be individual SCSS variables. They can still be defaulted to darken()
another SCSS variable, so it should be mostly backwards-compatible, but this would allow us to set all SCSS variables to equivalent CSS variables without the compiler choking on it. Currently we can achieve that for some components, but not for those that use darken()
, like buttons.
Of course if eventually Bootstrap moved to CSS vars directly for most things only that would be amazing, but this step would already provide a lot of value.
hey, just have a little idea for but rather global
here we have
https://github.com/twbs/bootstrap/blob/main/scss/_root.scss#L4
--bs
as prefix does it make sense to make it another variable for prefix
$prefix: "--rtx";
:root {
@each $color, $value in $colors {
#{$prefix}-#{$color}: #{$value};
}
it will be possible to change "brand" prefix
potentially may break some functionality but will be more comfortable especially while create own kit and want reuse some bt styles?
i don't know is it comfortable for anybody?
The most impactful step Bootstrap could take towards this in v5 would be removing usages of
darken()
et al and allowing those to be individual SCSS variables. They can still be defaulted todarken()
another SCSS variable, so it should be mostly backwards-compatible, but this would allow us to set all SCSS variables to equivalent CSS variables without the compiler choking on it. Currently we can achieve that for some components, but not for those that usedarken()
, like buttons.Of course if eventually Bootstrap moved to CSS vars directly for most things only that would be amazing, but this step would already provide a lot of value.
https://github.com/twbs/bootstrap/issues/31538 there is an issue about it, avoiding formulas in styles can help both with customizations and make Bootstrap CSS variables friendly
Just opened a PR for a new Sass variable for the CSS variable prefix: https://github.com/twbs/bootstrap/pull/31684. Good suggestion, @8nix!
@felixfbecker There's a PR at #30622 from @MartijnCuppens that is rewriting some colors work. Still using some tints/shades, but we can likely pare things down further in addition to that PR.
Regarding some CSS vars in components, is this the direction folks are wanting? See #31685 and #30500.
Just wanted to say that it would be really great if this was shipped in the next v5 release :crossed_fingers:
To give an example I worked on a Django project that used Bootstrap 4, but we wanted to customize the colours and fonts to match the company branding, so we ended up installing node.js
and configuring webpack
just to change some SASS variables.
It brought a lot of complexity into the project stack just to change a few colours. Now if this goes forward we could simply edit the variables values directly in the CSS without needing all of those extra tools and build step.
Regarding some CSS vars in components, is this the direction folks are wanting? See #31685 and #30500.
I would like to see support both SCSS variables mode, e.g. for shorter bundles and projects already using SCSS, and CSS variable mode (for runtime customizations, creating new modifications of components on the fly, for web-components, dark-mode, contrast mode).
This can be achieved if in SCSS styles we use just SCSS variables, but we can set values of this variables to CSS variables:
// Variables (maybe separate file of variables with CSS vars mode
$color: var(--color);
// SCSS styles
.btn {
color: $color;
}
Additional benefit: I can just remove this style by setting $color: null
, which will decrease CSS size even more.
@ydmitry I'm not sure to understand. It doesn't seem possible this way, since the main benefit of custom properties is to define their values on a component basis, eg. --bs-table-striped-color
on .table
.
What would happen to the custom props declarations, with your suggestion? How'd you drop them, and replace them with their targetted properties to ensure the same end result?
Current styles for tables:
.table {
--bs-table-bg: transparent;
--bs-table-striped-color: #212529;
}
.table > :not(caption) > * > * {
background-color: var(--bs-table-bg);
background-image: linear-gradient(var(--bs-table-accent-bg),var(--bs-table-accent-bg));
}
.table-striped > tbody > tr:nth-of-type(2n+1) {
--bs-table-accent-bg: var(--bs-table-striped-bg);
}
Should output something like this without custom props (skipping the transparent
values, since they wouldn't be outputted, would they?):
.table-striped > tbody > tr:nth-of-type(2n+1) {
background-image: linear-gradient(#212529, #212529);
}
And please note that even if this code block looks shorter, the overall tables with all variants would not.
I don't see any way to handle both cases, and don't see any point either.
FWIW, there's a way to nullify custom props too, as explained by @MartijnCuppens in a comment. If that's needed, we might interpolate all our custom props, maybe?
@ffoodd when we use:
.table-striped > tbody > tr:nth-of-type(2n+1) {
--bs-table-accent-bg: var(--bs-table-striped-bg);
}
It's not possible to combine both SCSS and CSS. But this approach is about how to write styles. It will require to drop IE11 support without any backports. Currently in v5 support is dropped, but it is possible to find some polyfills.
I'm sorry I still don't get your point. What's your approach? How do you solve the issue I mention?
For this use case - only with writing additional properties and selectors
// CSS variables declaration:
.table {
--bs-table-bg: transparent;
--bs-table-striped-color: #212529;
--bs-table-accent-bg: var(--bs-table-striped-color);
}
// SCSS to CSS variables mapper
$table-bg: var(--bs-table-bg) !default;
$table-bg-image: linear-gradient(var(--bs-table-accent-bg),var(--bs-table-accent-bg)) !default;
$table-accent-bg: var(--bs-table-striped-bg) !default;
// Pure SCSS variables for projects without CSS variables support
$table-bg: transparent !default;
$table-accent-bg: #212529 !default;
$table-bg-image: linear-gradient($table-accent-bg, $table-accent-bg) !default;
// SCSS component styles
.table > :not(caption) > * > * {
background-color: $table-bg;
background-image: $table-bg-image;
}
.table-striped > tbody > tr:nth-of-type(2n+1) > * {
// we added a property here, in some cases we will need to add selectors too
// in case if we have more styles those were using --bs-table-accent-bg variable
background-image: $table-accent-bg;
}
So that we have only SCSS variables in SCSS components.
For the projects which doesn't support CSS variables we can include a file with only SCSS variables.
In some projects we can decide which of the variables make CSS and allow runtime swtiching of these properties with different selectors, e.g.:
// Projects SCSS
$table-accent-bg: var(--my-table-with-special-accent-bg);
// Will generate a variant with special accent color, this will be allowed in SCSS of the projects, but not in SCSS of the library
.my-table {
--my-table-with-special-accent-bg: #F00;
}
I'll need a POC to understand, I don't think that could work at all for now :/
I'll need a POC to understand, I don't think that could work at all for now :/
Please take a look into a pull request https://github.com/twbs/bootstrap/pull/31708
With this strategy - no need to transform all SCSS variables to CSS variables, library users could just easily setup own variants by setting own CSS variables.
We can provide separate _variables-css.scss
file with everything enabled as a CSS variables and expressed with CSS expressions, so users can opt-in CSS variables for e.g. font sizes (mentioned before):
// BS variable override
$font-size: var(--my-font-size);
// Create wrapper and variants
:root {
--font-size: 16px;
}
@media screen (max-width: 320px) {
--font-size: 13px;
}
Or for variable for specific component:
$toast-background-color: var(--toast-background-color);
$toast-color: var(--toast-color);
.toast {
--toast-background-color: rgba($white, .85);
--toast-color: $grey-100;
}
.my-toast-variant {
--toast-background-color: red;
--toast-color: white;
}
And it will allow to partially support IE11 for users who have to support it in their applciations. Yes, without variants, but only core part.
@ydmitry Thanks for the PR, that makes it clearer! Your point is to use var()
in Sass variables and not directly in components, which is really interesting indeed.
Not sure it can be generalized but it'd allow to opt-in for custom properties with something like $enable-custom-properties
(or $support-ie11
?), as we do with shadows or radii.
Need to think deeper on this but I get your point now, thanks for your patience :)
Here we can support both specific values without increase of the default Bootstrap css size or enable CSS variables mode for applications those need to change colors runtime: https://github.com/twbs/bootstrap/pull/31753 (Alert). It removes darken
usage from styles and moved to variables declaration to be managable. Docs updated too.
Need a feedback which approach is better for CSS variables in Bootstrap - https://github.com/twbs/bootstrap/pull/31789 or https://github.com/twbs/bootstrap/pull/31753 ?
Need a feedback which approach is better for CSS variables in Bootstrap - #31789 or #31753 ?
While I'm not a BS developer (but a heavy user), those two PRs are a bit confusing to me, but I'll +1 your method a couple comments above ( https://github.com/twbs/bootstrap/issues/26596#issuecomment-695345684 ) as I feel it adds the flexibility we need. The media queries example was great, if it's intended to work as I'm thinking. Having the flexibility to do it per component or per property is awesome.
Just my 2 cents :)
@darkguy2008 thank you for feedback!
Well, these pull requests for not trivial case with alert variants:
$primary
and it also changes primary alert automatically$theme-colors
. So e.g. for night theme need to adapt all of the variants.null
.Gave my feedback here: https://github.com/twbs/bootstrap/pull/30500/files#r497388035
Can I just say that I'm so _so_ happy to see you guys have been making progress on this in the past few weeks - thanks a lot! And thank you @mdo for taking this into consideration again for v5, and trying things out.
Just my 2 cents - the biggest argument that I see thrown around _against_ Bootstrap is that "_Websites powered by Bootstrap all look the same_". I believe making it dead-simple to change the color palette and sizes for Bootstrap-powered websites, using CSS variables instead of having to recompile everything, will be a game-changer. I believe _in time_ it will render that argument dead. I don't see this as a minor feature, but as something HUGE. The way I see it, it'll make it easier for template developers to do their job. And easier for developers to not use a template at all. Really excited about this 🥳 🤞
Chiming in here because I love the progress with this and I'm excited to see CSS variables becoming a first-class concept in Bootstrap 5. With this comment I'd like to describe our concrete use case, provide insight into how this can benefit users/devs as well as outline some needs regarding the CSS variables implementation.
Our approach up to now has been to fork Bootstrap v4 and implement this ourselves, using a technique described in this thread already: Programmatically replacing existing colors with our own custom properties.
The main reason for this was to enable light/dark mode for our sites and apps. As stated by others already, this made it possible for us to provide one general bootstrap.css file and a separate files containing only the variable definitions.
In our case it would be possible to even merge these two files, but we have these separate as we are also using the variable file on sites without Bootstrap. Keeping them separate would also allow for one file per "theme" and loading/swapping in only the chosen theme, as other sites are doing it.
The fork and replace approach works and provides great flexibility, but having this as a native feature inside Bootstrap would be even greater.
The main hurdle has already been described in other comments: Providing the color variations, which are generated via SASS functions (e.g. lighten
or darken
). We've circumvented this by introducing separate custom properties.
Depending on how far one wants to go there might be more colors per concept (concept being something like "primary", "warning" or "light" here), but we've come a good way with the main color plus three variations. Here's an example with our primary palette:
/* variables */
--btcpay-color-primary: var(--btcpay-brand-primary);
--btcpay-color-primary-accent: var(--btcpay-brand-tertiary);
--btcpay-color-primary-backdrop: #D2E5CF;
--btcpay-color-primary-text: var(--btcpay-color-neutral-900);
/* sample from usage in alert */
.alert-primary {
color: var(--btcpay-color-primary-text, var(--btcpay-color-white));
background-color: var(--btcpay-color-primary-backdrop);
border-color: var(--btcpay-color-primary-backdrop); }
.alert-primary hr {
border-top-color: var(--btcpay-color-primary-accent); }
Based on this one could go even further and provide component-level properties, which by default leverage the common ones. It's great to see Bootstrap taking this direction, as it allows for even more flexibilty.
A concrete use case for us would be to tweak e.g. the button colors just in dark mode, by setting them via --bs-button-primary-background
(made that up) in dark mode and leaving the defaults as it is in light mode.
Right now, we are solving this via CSS overrides, luckily as these cases are rare.
We have a Bootstrap kitchensink page where you can see this in action.
Use the button in the top-right corner to toggle between light and dark mode.
As you can see we e.g. inverted the light and dark color, depending on which mode you are in.
The power of this approach is being able to easily switch between these modes by just providing a different set of variables (either via separate files or like here via :root
and :root[data-theme
selectors). This frees us from generating a whole bootstrap.css
per theme and saves the users bandwidth.
I think when add CSS variables need to have some list of features on which we are focusing:
From the examples provided by Bootstrap teams I see 1st and partially 2nd goals. Am I right? Are there any plans to support more extended 2nd and 3rd features?
Now that css variable are exposed (https://getbootstrap.com/docs/5.0/customize/css-variables/#root-variables) I thought this would also mean that classes like btn-success
would inherit that color. However it seems like that is not the case. Is this still planned for v5.x or rather put off to v6?
I just saw that the Bootstrap 5 beta is released and with that no more features go into v5. I assume that means v5 will not have support for CSS vars and theming. That's very disappointing. There was progress on this issue, so I kind of assumed it would be a big part of v5.
@felixfbecker well, it's still in Beta. I would bet that they will make it for the final version, that's what we all are hoping for anyways as it is/was one of the big news for V5...
With our first beta release of Bootstrap 5, we’re calling it on new features and breaking changes. From here on out, we’re only fine-tuning features, bugs, and documentation on our way to a stable v5 release. Woohoo!
https://blog.getbootstrap.com/2020/12/07/bootstrap-5-beta-1/
With our first beta release of Bootstrap 5, we’re calling it on new features and breaking changes. From here on out, we’re only fine-tuning features, bugs, and documentation on our way to a stable v5 release. Woohoo!
https://blog.getbootstrap.com/2020/12/07/bootstrap-5-beta-1/
Thanks for the link. Well, then it's a major disappointment indeed. It's sad to see that one of the biggest, most useful features (way more than RTL, popper.js v2 and tooltip positioning...) is still being left off for a next version. So much for listening to the community! :/
Not all hope is lost. While I agree that I will most likely not ship with v5.0 I can very well see this implemented as a backwards compatible feature in v5.1.
Styles which are currently implemented like: background-color: #00ff00
could definitiv be replaced by background-color: var(--bs-success)
. Supporting styles which currently use SCSS calculations could also still be used by introducing another layer of indirection.
Dropping #32424 as a first step to getting more CSS vars inside v5.
The goal was never to go full-in on CSS vars for v5. Up until a few months ago we had planned on supporting IE11, which doesn't allow CSS variables. Now that things are settling with the beta process, we can look for ways to iterate. #32424 is an example of what I think we should be looking to do in v5:
:root
variablesThat's not a perfect solution or formula, but it's been the direction I've planned on going since we first dropped IE11. Hope that helps, and please let the feedback (continue to) rip!
That already sound fantastic. Good to get the stance of someone from the devteam towards this!
I just commented on https://github.com/twbs/bootstrap/issues/31538#issuecomment-742801115 about what possibilities I personally envision from these changes.
Keep up the great work. v5 already looks great and increasing the CSS var adoption throughout the next few minor releases would make it even better. Personally I hope you focus on colors regarding the usage of CSS vars as I think that is where people will be most excited for them.
Most helpful comment
@mdo has been a long trip with Bootstrap and being grateful for your work, but I believe you are being stubborn on this one.
CSS Variables are 100% supported on green browsers and the global usage is quite enough for saying that we should start embracing the technology.
Keeping v5 without major updates shouldn’t be the goal, like I said Bootstrap has been breaking changes every major release and everyone is aware of that.
I do not believe that the rearchitecture has to be that bad, specially that must of the source code is well known and written so far.
Progressive enhancement always exists and we could slowly upgrade the framework to be 100% CSS variables with all the good practices in the future.
Sorry, but I can see any valid point for not doing it. I would take the initiative of written the spec of the changes and the roadmap and implement it if you want.
I don’t want to create another Bootstrap and having to deal with marketing the framework. I would love to see you change your mind.
Just put in perspective the implications of not doing this agains your thoughts right now.