ant-design
ant-design copied to clipboard
Toggle dark with @media (prefers-color-scheme: dark) such like ThemeProvider
- [ ] I have searched the issues of this repository and believe that this is not a duplicate.
What problem does this feature solve?
The theme color changes according to the system theme
主题色根据系统主题变换
What does the proposed API look like?
import 'antd/dist/antd.dark.css'
加载这个样式后,并不是直接应用到全局,而是可以通过一个类名,比如 <body class="dark">来切换主题。
再或者是把 less 颜色变量暴露到 css var
:root {
--red: #ff6347;
--yellow: #ffc107;
--blue: #6495ed;
}
@media screen and (prefers-color-scheme: dark) {
:root {
color: #ddd;
--red: #ad1a00;
--blue: #1346a4;
}
}
Similar #16661
I'm doing this in .less file and it works fine.
@media (prefers-color-scheme: dark) {
@import "~antd/dist/antd.dark.less";
}
for toggle dark mode I do this but get a little color bug.
.dark-theme {
@import "~antd/dist/antd.dark.less";
}
I only used scss and css, and is there a way to use it in scss?
I only used scss and css, and is there a way to use it in scss?
I'm not sure but you can try it
@media (prefers-color-scheme: dark) {
@import "~antd/dist/antd.dark";
}
Just look at the node_modules/antd/dist/ directory. Compiled styles is here.
I only used scss and css, and is there a way to use it in scss?
I'm not sure but you can try it
@media (prefers-color-scheme: dark) { @import "~antd/dist/antd.dark"; }Just look at the
node_modules/antd/dist/directory. Compiled styles is here.
I had to try, but failed. If do this, It will not bundle the antd.dark css file.
I only used scss and css, and is there a way to use it in scss?
I'm not sure but you can try it
@media (prefers-color-scheme: dark) { @import "~antd/dist/antd.dark"; }Just look at the
node_modules/antd/dist/directory. Compiled styles is here.I had to try, but failed. If do this, It will not bundle the
antd.darkcss file.
Have you found a solution to import the file in SASS ?
I only used scss and css, and is there a way to use it in scss?
I'm not sure but you can try it
@media (prefers-color-scheme: dark) { @import "~antd/dist/antd.dark"; }Just look at the
node_modules/antd/dist/directory. Compiled styles is here.I had to try, but failed. If do this, It will not bundle the
antd.darkcss file.Have you found a solution to import the file in SASS ?
Sorry, I don't have a good idea. I override all colors which antd used in my scss.
I found a temporary and easy solution, I copied the css files of antd and antd dark and created two seperate scss file, each had a prefers color scheme only. So in prefers color scheme dark, I put all the dark css and in light the default css. So now each time I change my windows theme to light or dark, the website changes color flawlessly without any issue or extra work of modifying Less. 👍
@dukesx How to ensure that it can still work normally when update the antd version?
Look, this is a trade off you will have to make. Ant Design doesn't have a dark mode toggle and it is impossible to toggle it live. Until Ant Design team wakes up and finds out a way to implement dark mode the right way, this is the easiest and "working" way. You can write custom css but that's time taking and your color scheme probably won't fit the components correctly. There is another way that you use nodejs to watch antd folder, if changes happen, you copy all content inside antd.css and antd.dark.css to your new files so that you keep it updated.
proposed
@primary-color: #1890ff;
@primary-dark-color: #1890ff;
body {
--color-primary: @primary-color;
}
body.dark {
--color-primary: @primary-dark-color;
}
body.auto {
--color-primary: @primary-color;
@media screen and (prefers-color-scheme: dark) {
--color-primary: @primary-dark-color;
}
}
a {
color: var(--color-primary);
}
Default light theme
Add dark className to body to switch to dark mode
<body class="dark">
Add auto className to body to follow the system
<body class="auto">
AntDesign should really look into a ThemeProvider, or extend the ConfigProvider, it is really annoying to be forced to use css vars to customise the theme (considering it's not supported on all browsers).
a system like @zeit-ui/react would work so much better for dynamic theming. Take my example in this thread, we have multiple clients, with their own branding colors, then we have a dark and light mode as well. Many methods have been tested but it simply does not scale, eg; injecting the less vars as suggested in the docs.
The only performant solution I found was to do a complete cssvars override of the antd components.
https://github.com/PaulPCIO/antd-themed-cssvars
@afc163 🙏
AntDesign should really look into a ThemeProvider, or extend the ConfigProvider, it is really annoying to be forced to use css vars to customise the theme (considering it's not supported on all browsers).
Extending the ConfigProvider would be ideal. We have a similar requirement to your example re light/dark/whitelabeling and i'd really rather not have to go down the scss route. Proper dynamic theming is really the last piece that's missing from Antd
I stumbled on this issue and spent three days trying to find a decent solution. Since converting all variables to CSS vars and using SCSS is out of my scope, I had to find an alternative solution. Injecting styles with Less was not scalable since it killed my app's performance. What I first decided was to just do as the Ant team does for their docs: prefetch styles, use theme-switcher, and change the CSS directly on the HTML.
At first, I was very happy with how fast it was compared to solutions using less.modifyVars, however, I hit a block since a flickering occurred when loading and injecting the styles; also, styles that were not Antd conflicted because of the order. Therefore, to solve this I created a library similar to theme-switcher, but using React's API. It comes with some extra features like selecting injection point and adding stylesheet injection status (to display a loading to avoid the flickering).
You can check the library here: react-css-theme-switcher. It currently has 100% code coverage and is open to suggestions and PRs.
Currently, I can customize the theme however I want and my app performance was not as impacted. It is a good solution for the meantime.
I'll be writing a blog post on how to get custom CSS stylesheets and implement react-css-theme-switcher. As soon as it is written, I will update this comment with the link.
TL;DR: My solution to dynamic theming was to use react-css-theme-switcher and swap CSS stylesheets with the theme I need within React.
Edit: Here is the blog post for those who want to read through a tutorial of the solution.
I stumbled on this issue and spent three days trying to find a decent solution. Since converting all variables to CSS vars and using SCSS is out of my scope, I had to find an alternative solution. Injecting styles with Less was not scalable since it killed my app's performance. What I first decided was to just do as the Ant team does for their docs: prefetch styles, use theme-switcher, and change the CSS directly on the HTML.
At first, I was very happy with how fast it was compared to solutions using
less.modifyVars, however, I hit a block since a flickering occurred when loading and injecting the styles; also, styles that were not Antd conflicted because of the order. Therefore, to solve this I created a library similar to theme-switcher, but using React's API. It comes with some extra features like selecting injection point and adding stylesheet injection status (to display a loading to avoid the flickering).You can check the library here: react-css-theme-switcher. It currently has 100% code coverage and is open to suggestions and PRs.
Currently, I can customize the theme however I want and my app performance was not as impacted. It is a good solution for the meantime.
I'll be writing a blog post on how to get custom CSS stylesheets and implement react-css-theme-switcher. As soon as it is written, I will update this comment with the link.
TL;DR: My solution to dynamic theming was to use react-css-theme-switcher and swap CSS stylesheets with the theme I need within React.
Looks nice. Looking forward to reading it!
Same issue here, I use injectType: 'lazyStyleTag' to get around this. But the drawback is quite significant, both of the CSS is at my bundle righty now without any tree shaking.
This should really be a priority, runtime theming is a pretty much used feature nowadays. Spent several hours to make it work, using a workaround.
The only performant solution I found was to do a complete cssvars override of the antd components.
https://github.com/PaulPCIO/antd-themed-cssvars
Really appreciate the work done here. Too bad that since it's not officially supported, something might break the theme in future releases (minor changes to antd, new components).
For anyone that wants to use the @PaulPCIO approach:
Usage:
- git clone the repo and copy all files locally (node-sass is required for CRA)
- Import index.scss in your App.js (or relevant) file.
- Create themes.scss at index level, import it at the bottom of index.
- In themes.scss customize your themes:
.light-theme {
--primary-color: #007bff;
--disabled-color: #6c757d;
--bodyBackground: #ffffff;
// ... etc
}
.dark-theme {
--primary-color: #000000;
--disabled-color: #4a4a4b;
--bodyBackground: #000000;
// ... etc
}
- Assign light/dark className to App, change on button event click.
+1 to ThemeProvider
Hi community,
Why not just replace all less variables with css vars.
This improvement will allow for super flexible customization tools. It will increase total styles size a little, but it really helps to customize Ant Design globally or any individual piece of the UI.
// https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less
@primary-color: var(--antd-blue-6);
@success-color: var(--antd-green-6);
@font-size-sm: var(--antd-font-size-sm);
and define this variables in global styles:
// https://github.com/ant-design/ant-design/blob/master/components/style/core/global.less
:root {
--antd-blue-6: #0000ff;
--antd-green-6: #00ff00;
--antd-font-size-sm: 12px;
}
then we can easily redefine this variables for any pieces of the code:
// global dark theme
body.dark-theme {
--antd-blue-6: #ffffff;
}
// there is all antd components inside .header will inherit redefined --antd-blue-6 color
.header {
--antd-blue-6: green;
}
I just created a PR to support automatic dark mode through theme generation.
You can use the umi-plugin-antd-theme plugin to generate an automatic dark mode theme.
chenshuai2144/antd-pro-merge-less/pull/24
@yisiqi, will that work for those of use using Create React App or Next.js?
CSS Variable support is pretty widespread these days, if the less variables could all just be replaced with CSS Variables I think it would simplify a lot of use cases. Not to mention CRA and Storybook among others not playing nicely with LESS out of the box. I currently have a big file where I assign all antd css variables to less variables to help get around some of these issues.
Hello people!
So why we have this awesome PR abandoned at all? #26139
@tigran-ucraft and @baldarian can you tell was whats happened in your work?
I was starting to create a PR with something like it 🙃
I think that this is very good issue. Because css variables helps us to change theme at runtime. Few months ago, I need an UI framework to support color changes for multi tenant app. I could not find a good solution for antd to change colors at runtime.
It looks like ant design comes with an experimental ConfigProvider nowadays, which accepts a theme prop: https://ant.design/docs/react/customize-theme-variable
I however haven't found a way to export all nextjs dark theme variables, as they are only defined in deeply nested less files
(() => {
const isDarkTheme = window.matchMedia("(prefers-color-scheme: dark)").matches;
import(`antd/dist/antd.${isDarkTheme ? 'dark.' : ''}css`);
})();
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
Write your root component. it works :)
@afc163 any update on being able to toggle darkmode with ConfigProvider? 🙏
@media (prefers-color-scheme: dark) { @import "~antd/dist/antd.dark.less"; }
Does this need to set the class on the body? I tried it but it didn't work. I'm a little confused. Thanks
I used this to enable dynamic dark mode in a scss file and it's working:
@use 'sass:meta';
body:not(.dark) {
@include meta.load-css('node_modules/antd/dist/antd.css', $with: null);
}
body.dark {
@include meta.load-css('node_modules/antd/dist/antd.dark.css', $with: null);
}
The dark mode switch just adds a dark class to the body tag.
Demo: https://arifszn.github.io
Use SCSS Nesting import:
https://sass-lang.com/documentation/at-rules/import#nesting
Create a antd.dark.scss
@media (prefers-color-scheme: dark) {
@import '~antd/dist/antd.dark';
}
Import antd.dark.scss in your JS index.ts
import React from 'react';
// This for Light
import './antd.less';
// This for Dark
import './antd.dark.scss';
https://github.com/huacnlee/autocorrect/commit/a827af4fddc98d54ecff104a1a8b805f6a74b760