mdo / ama

Ask @mdo anything!
94 stars 40 forks source link

Bootstrap dark mode #300

Closed vinorodrigues closed 3 years ago

vinorodrigues commented 4 years ago

Hey there Mark.

I was hoping you could look at some of my ideas around Bootstrap dark mode where I've looked at the code side of getting Bootstrap 4 to be ... dark. I didn't want to make a pull request on it because I don't believe its an elegant solution, but I see that most of your own personal work has dark mode in mind and I thought you'd enjoy the read. I did not focus on the actual colors (because I'm not a graphics professional), but I'd love to hear your thoughts on the methods I've adopted.

Also I wanted to show how easy one can get Bootstrap dark (code took me 3 days) - so hoping you could incentivize the team to bring this forward to V5 and not V6.

Anyway - for your reading pleasure (or displeasure) vinorodrigues/bootstrap-dark

Thank you (for letting me waste your time).

vinorodrigues commented 3 years ago

Hey there Mark.

I created a follow-on to the above work ... this time for V5-β1. Same principles - vinorodrigues/bootstrap-dark-5

mdo commented 3 years ago

This is pretty phenomenal work, @vinorodrigues! Wow.

I would love to find a way to get this into the main project for v5. It would be tremendously powerful for everyone and a huge boost to v5's feature development over v4. Some thoughts on it since you shared here (and sorry for not following up sooner!) and I'm still poking around...

Happy to chat more here or in our Bootstrap Slack if that works better! Let's hash this out and see what we can make happen :D.

vinorodrigues commented 3 years ago

"pretty phenomenal work"

A true honor coming from you. Thank you! (But I was mostly inspired by Thomas Steiner, @tomayac - so I can't take all the credit.)

"accomplish this without duplicating the imports"

Yes – absolutely. You're currently doing so with the prefers-reduced-motion. Very doable. The caveat is that it will need to be done to each (most) files in the scss folder. Also worth considering that this means the @media (prefers-color-scheme: dark) { line will appear 39-times in the output CSS. i.e. you're trading source efficiency for output efficiency. Having said that, the extra 1,500 bytes makes no difference… and this is the way I would do it right now anyway.

"could we hot-swap the variables files or override"

The original body of my work had certain parameters that I needed to work with, one of was that I wanted to make this happen without any modifications to core. I thus created a _variables-alt.scss file. The intent was that it be added alongside the _variables.scss file. Theme builders would then still include the core (and "alt") scss' and also their own overrides. Count we consolidate the two _variables files? Yes absolutely … but I'd recommend not to --- at least not for v5 or v5.1. My thinking there is that BS v5 should remain single color for now, but also add a dual-color super-variant. (Just like you have a -utilities & -grid sub-variants.)

"Are there "global to dark mode" resets that are necessary beyond variables"

For now … yes ☹. My work includes a small set of -alt mixins and functions. Most of these use color-based variables within functions that makes for "alternate" color manipulation not viable (hence the additional mixin and function scss'.) But there is a silver lining … one can expand the current functions/mixins without changing the dependent core by modifying the function calls by adding additional default parameters – thus core calls remain unchanged, and "alternate" calls add the "-alt" colors as parameters. Easy change with no negative outcome.

"color themes vs just dark mode and light mode"

Umm… depends on how you view it. My view (on my bit of work) is to leverage the prefers-color-scheme media query that the browsers and OS provide. I explain in the work as to why I disagree with the concept of the toggle button.

If you view if from that perspective, i.e. prefers-color-scheme driven only by browser/OS, then one needs to remember that that's browser based. i.e. it will only ever be binary: either "light" or "dark". (Nothing stopping you from having dark-green and light-green for example.)

If you view it from the "toggle button" perspective, then that functionality requires additional JS and a CSS class hierarchy that leaves open to as many "themes" as you want… but we'd need to create the framework around that.

"a way to get this into the main project for v5"

Your wish is my command, my liege.

Jokes aside – I've been dying to get a pull request built… but I haven't because I was confident that it would not get approved – and I chose to build it as a snap-on so that it was functional outside of the dev track.

What I can do – for now – is build a browser/OS decides variant - using prefers-color-scheme media query. And also, some docs around how to build the "toggle button" variant – but that needs some JS, and an agreed upon CSS class hierarchy etc. etc. and I'm just not the best at JS code, and wouldn't proport to make assumptions on class hierarchy's. I aim to have something workable as "dark-mode" ... and enough seeds so that someone who's better than me at this can take it where it needs to go. I've added myself to your Slack – will ping you on a DM and we can have this conversation from there onward. (I'm in Sydney, Australia, so expect conversational lag.)

Give me the weekend to get something done. I'll add you as a contributor to my branch and won't PR until we're both happy.

tomayac commented 3 years ago

"pretty phenomenal work"

Awesome work indeed! <3

A true honor coming from you. Thank you! (But I was mostly inspired by Thomas Steiner, @tomayac - so I can't take all the credit.)

Thanks, happy my blog post was helpful. If you add this to Bootstrap, please also add color-scheme at the same time. The two go together really well.

mdo commented 3 years ago

I'm very down for color-scheme support via media query. Ideally we can be pretty creative with our solution here. For example, perhaps we disable the default dark mode component variations when enabling the new dark mode as Sass level.

Providing CSS variables alongside this would be absolutely stellar, but I'm not sure we can get there with our current architecture. Thoughts, demos, and spiked ideas would be really amazing to see and talk around before going too far in any one direction.

Visually, this looks and feels amazing. I'm very down to help jam and give feedback, though these next couple weeks I'm not super available. Take your time and let me know how I can give feedback as ideas progress!

mdo commented 3 years ago

I'd also say, feel free to spike out some ideas and commentary in the main Bootstrap repo. I'd be keen to get @ffoodd's opinion on this stuff too :).

ffoodd commented 3 years ago

Impressive work @vinorodrigues!

IMHO CSS custom properties are the way to go. There's only two choices, to me:

  1. either custom props, and a single file to rule them all—which could unveil things like switching theme based on prefers-color-scheme or using selectors like [data-theme] or a class name (choice that could be handled Sass-side, through some variables like $enable-color-schemes and $enable-prefers-color-scheme-media-query);
  2. or multiple build, using different variables, and simply switched thanks to <link media="">.

As a sidenote, this is opinionated as giving the choice to the user only. Which is great, without a doubt. However I'd say it also need to consider author choice (e.g. light color scheme as a default but some parts in dark scheme). This cannot be handled through prefers-color-scheme and requires some scoping, which is why I'd go with custom properties and selectors (being class name or data attribute).

Basically, abstract any color-related properties and values as custom properties, and using selectors and/or media queries to scope colors. This would solve the duplicate imports. I don't think it'd need any change in our core mixins and functions, since we'd call them in custom properties, scoped to a selector or media query (e.g. using tint() in light scope and shade() in dark scope).

I'm convinced this could be done without breaking changes in Bootstrap v5, however it'd be a huge amount of efforts to make it happen.

On my side it's still maturing until I'm confident enough to start something. :) I'll keep an eye on this discussion, it's very interesting (and thanks again @vinorodrigues for this awesome work and pushing us forward to this).

vinorodrigues commented 3 years ago

Impressive work

Thank YOU! Coming from the likes of you it is truly humbling.

CSS custom properties are the way to go

I would whole heartedly agree, but as you mentioned, the amount of work needed is immense. For β1 the closest component would be the tables files that uses CSS variables to awesome effect... but even it falls a bit short (i.e. the color and border-color props. are not var'ed.)

This cannot be handled through prefers-color-scheme and requires some scoping

Yes! Correct. (And you'd need to expand the JS library to incorporate management of color choice and the persistence thereof...) And, indeed, I agree with the general sentiment that this should wait for v6.

But I think we're mixing the ability to choose color here.

If we look at the spirit of what prefers-color-scheme is intended to do (see Media Queries Level 5 Specification – namely that the "user-agent" (a.k.a. browser) describes a binary user choice.. either light or dark – then the choice is not only binary, but it's almost literally black-and-white. (interesting also that the spec has removed the no-preference option.)

The choices of color is not tethered to this media query... alas the two should work in tandem to give the best UX. MDN has a simple example of this in their prefers-color-scheme reference . IMHO choices of color should indeed be driven by both user and developer. But, if one wishes to, when honouring prefers-color-scheme, offer only a binary choice ... light and dark – and then through UX offer variants of color, be it dark or bright, or red, or green, or blue.

I think what's confused the community is the over-use of the concept, and term, "dark mode"... going by what the git issues & StackOverflow questions are mostly asking; it's that verkakte toggle button. Indeed, that is a popular UI technique (some would say trend), but it's in essence deprecated by the prefers-color-scheme media query. "Dark mode", as is today, is driven by the OS.. be it MacOS/IOS or Win10 or Android "appearance" configuration, or the browser (i.e. Firefox will honour the browser theme preference, and then the theme in turn will or will not honour the OS preference (default theme does).)


(But I don't want to start a philosophy debate ... interesting as it may be.)

Here's my thinking...

(And this may well be just me thinking this way. You see, I'm not a developer, or anything software related. I'm the IT Facilities Manager for a large Airport and I look after electrical and air-conditioning and likes for 9 datacentres (small ones) and over 480 network hubs. I'm wired to think that if something is broke, fix it first, the quickest way possible to get it running again, and then take your time to research, strategize and implement the best and long-term solution. Given that ...)

v5.0 should have a rudimentary "dark mode" offering. Doesn't need to be defaulted into the already given sets of core, reboot, grid and utilities ... these should stay as is ... but offered as a 5th variant. One can even add a comment/note that this is experimental etc.

Let the masses have it ... and then, as they will, bare the commentary and advice ... in there will be some new thinking. New ways to do this. Efficiencies offered. And also, the dev team will be seeded with inspiration and better ways to implement this.

v5.1 can introduce interactive color selections and expanded utility classes to aid in that.

v6.0 would then have the pure CSS variables approach.

... but that's just my thinking. Bootstrap is not in my dominion – I have no right to even make suggestions. All I can offer is a working example, and to make you aware that it exists.

I will remain honoured that you've all taken the time to read this.

Thank you! Thank you! Thank you!

PS: The effort to merge my code into Bootstrap source base is already done. No docs yet .. still learning how to use that .. but if you want a look-see head on over to my fork at vinorodrigues/bootstrap.

ffoodd commented 3 years ago

That's a very smart approach, I'd say! One way could be another variable files, to compile a variant. Simple and efficient enough, and should allow us to fine tune our color scheme. Not sure we'll get to this point though.

Regarding custom properties, my opinion (and probably other team members') is that we shall use them more and more. Takes time, obviously, but this will eventually unleash so much powers for Bootstrap.

RTL felt more urgent to most of us, but the next chapter in my mind is definetely custom properties.

And dark mode is coming, for sure. :)