-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add dark mode variant #2279
Add dark mode variant #2279
Conversation
I think as long as this is kept as opt-in somehow, it shouldn't be a problem for most people. Purge CSS is our friend. I also think that utility classes are such a great way to implement dark mode color differences. Great work! |
Is there a way to have a hybrid strategy? Eg default to the media query unless the theme is explicitly set as a class? |
Would we really need to add other color affecting classes then |
Regarding the file size comments, maybe this is where the divergence starts and bigger features start getting pulled into non-default plugins like typography. That way you specifically import it if you want it, otherwise everybody else is in affected until the dark mode fad goes away :p |
Just dropping that here in case it wasn't considered but perhaps also including a |
@pspeter3 The best way to do this is just to use the Something like this as an inline script in the head before any of the page loads: <html>
<head>
<script>
if (('themePreference' in localStorage) && localStorage.themePreference === 'dark') {
document.querySelector('html').classList.add('dark')
} else if (!('themePreference' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.querySelector('html').classList.add('dark')
}
</script>
</head>
<!-- ... -->
</html> |
@ekvedaras The main use case is setting a background color that appears when overscrolling in macOS, that can only be done on the HTML tag unfortunately. |
@lihbr I considered that originally but ultimately decided to use a class because then the class automatically respects the user's |
Makes sense indeed! I think I had some issues in the past with Modernizr conflicting with Vue meta but that was probably due to a poor usage of mine 🤔 |
I did a simple implementation of dark mode in my last project, at first using the media queries (like this PR), but as another "screen", and when I needed to use tailwind in CSS it looked really nice: @screen dark {
.panel {
@apply text-white;
}
} But when I needed to make dark mode settable by the user, I had to switch to doing something like setting a class on html (like in this PR) and then doing this wasn't as nice (I use svelte). I had to write these each time I wanted to target something as dark like: :global(html.dark) .panel {
@apply text-white;
} I don't know how those @dark {
.panel {
@apply text-white;
}
} |
IndexedDB is async so you can get a flash of the wrong color whereas localStorage is sync and blocking 😊 Anyways if people want to use the media query strategy of course you’re welcome to, that’s why I’m including both. It’s even the default! |
This is amazing, previous media implementation was on but yet we have to do a lot of work on saving the user preferences, thanks @adamwathan ! |
I think not giving users the option to override OS theme for a particular website is not taking accessibility into account. Depending on the website, one may choose a different theme. This is crucial for users with visual disability. I have seen such users who prefer dark theme overall (since decreased brightness is better for eyes) but prefer light theme for blogs where they have to read a lot of text because reading light text on dark background irritates their eyes. |
We should probably also not be handling this with JavaScript in case the user has disabled it or has an unstable connection. That seems like an accessibility concern as well. The only reasonable solution is to manage user preference server-side, or maybe a cookie, and then send pre-rendered HTML with the correct CSS down the wire. |
Have you considered the way Apple approaches this? Instead of defining a dark variant, you would define a dark color for each color in the configuration file. Below is a screenshot of the color assets in Xcode. So This means the class strategy is not an issue anymore, and you potentially save a lot of code, both in the CSS files and as you create your design (since you don't have to use any class at all). You could keep the dark variant to give some more flexibility when needed. |
@sowenjub That's achievable by setting your color variables to CSS variables, no? Which you can then swap on the fly with different stylesheets. The issue with it is that your classes either need to be function based like |
Doing this breaks text-opacity and bg-opacity classes, so if you need those, you can't use CSS variables for color declarations. |
@cbenjafield Can you create a GitHub repo that shows it not working so I can easily pull it down and tinker with it? Don't have a ton of time to set it up from scratch but if I can just clone it and sort it out in 5 minutes I can definitely help. |
Ah, solved it literally just as you replied - just me being stupid and not updating purgecss to handle the dark class 🤦🏼♂️ |
hey, any example on how to use the dark mode without the media query? the thank you :) |
We can change the values of the color classes based on the dark mode whether is enabled or not. |
can anyone send me the link of this feature in the official docs ? |
The feature is still experimental so this pull request is the docs for now 👍🏻 |
HI! |
@Im-Fran You probably need to enable the |
Oh, oki, thanks |
Hi, how about prefix? Will dark become tw-dark? I didnt test but tell me if you know :D |
I’ve tried to unsubscribe from this thread but am still getting emails.
On Wed, Oct 21, 2020 at 1:36 PM IRediTOTO ***@***.***> wrote:
Hi, how about prefix? Will dark become tw-dark? I didnt test but tell me
if you know :D
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#2279 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AHRLYS4PYXV7D7RKG6CCOW3SL5A5NANCNFSM4QRD3H2A>
.
--
Gideon S Crawley
646-667-5520
|
I'm a little late to the party here, but it might be nice to offer a way to provide a custom class for the Maybe something like this? // tailwind.config.js
module.exports = {
dark: { class: 'is-dark-mode' }
// ...
} I'd be happy to take a shot at a PR adding this if others agree it would be useful. It'd be great to land this before 2.0 |
This PR introduces experimental support for a new
dark
variant that allows you to conditionally add different styles based on whether "dark mode" is enabled.In practice it looks like this:
It is made available under the
darkModeVariant
experimental flag:Functionality
Stackable by default
The
dark
variant automatically stacks against basic variants likehover
andfocus
, and also combines with responsive prefixes likesm
,lg
, etc., so you can do things like this no problem:The
dark
variant does not stack withmotion-safe
andmotion-reduce
variants, but I don't expect that will actually be an issue for anyone. In the future we will likely provide more control over how variants are stacked in general.Media query and class-based strategies
By default we use a "media" strategy, which generates classes like this:
This is fine for many projects, but has the limitation of not being able to store a user's preference, or allow them to switch between light mode and dark mode with a toggle since it is tied to their operating system preferences.
To support more sophisticated needs, I've also implemented a "class" strategy that you can enable like so:
This will generate classes like this instead:
To use this strategy, you'll need to add a parent class of "dark" whenever you'd like to enable dark mode, usually to the
html
element:Default configuration
By default, the
dark
option is set tomedia
:The
dark
variant is enabled for the following core plugins:backgroundColor
borderColor
divideColor
textColor
placeholderColor
gradientColorStops
Enabling in your config file
To enable the dark variant for any of Tailwind's utilities, add
dark
to thevariants
configuration for any plugin:Design Rationale
The obvious question when implementing this feature is "why not build some generalized universal theming solution that supports an arbitrary number of themes?"
The main reasons are:
So for now, this feature is unapologetically dark mode only. Every design decision has been made with the mindset of "we only support light mode and dark mode and we don't care about supporting anything else".
That's why the parent class is simply
dark
, the prefix is justdark
, the configuration option is justdark
, etc.Would love any feedback on this. One concern I have myself is that using the
class
strategy, you can't easily do this:...because only child elements are affected. We could update the selector to make this work but it would result in a significant increase in file size. If anyone has any ideas on how to make that work without doubling the number of color-based selectors I'd love to hear them.
In general, this feature introduces a lot of classes because of the fact that it stacks and targets color classes, so it adds a lot of weight to the default CSS file. I personally don't care (I use PurgeCSS and you should too) but I expect it will cause more "wow Tailwind is huge how does anyone use this?" type of remarks. I'm considering building a "TailwindLite" CDN version for 2.0 to try and combat this a bit, but still eventually we are going to hit some critical threshold where the file size becomes an issue even in development mode, so do have to be careful with this stuff.