The demo is based on:
React: 17.0.2
Less: 4.1.1 (if less is used)
1. Dynamically add tag custom attributes (HTML,body……)
app.tsx
import "./styles.less";
export default function App() {
// Switch themes
const changeTheme = (type: string) = > {
const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)")
.matches; // Get whether the system is in dark mode
if (type= = ="auto") {
document.documentElement.setAttribute(
"data-prefers-color",
prefersDarkMode ? "dark" : "light"
);
} else {
document.documentElement.setAttribute("data-prefers-color".type); }};return (
<div className="App">
<h1>Dark Light Demo</h1>
<div>
<button
className="btn"
onClick={()= > {
changeTheme("dark");
}}
>
change Dark
</button>
</div>
<div>
<button
className="btn"
onClick={()= > {
changeTheme("light");
}}
>
change Light
</button>
</div>
<div>
<button
className="btn"
onClick={()= > {
changeTheme("auto");
}}
>
change Auto
</button>
</div>
</div>
);
}
Copy the code
var.less
@c-bg: #fff;
@c-bg-dark: # 141414;
@c-text: # 141414;
@c-text-dark: rgba(255.255.255.0.65);
@c-border: #d9d9d9;
@c-border-dark: # 434343;
Copy the code
styles.less
[DATA-COLOR =”dark”]
@import "./var.less";
body {
background: @c-bg;
[data-prefers-color="dark"] & {
background: @c-bg-dark; }}.App {
font-family: sans-serif;
text-align: center;
color: @c-text;
[data-prefers-color="dark"] & {
color: @c-text-dark; }}.btn {
margin-top: 10px;
padding: 4px 15px;
font-size: 14px;
border-radius: 2px;
color: rgba(0.0.0.0.85);
color: @c-text;
border: 1px solid @c-border;
user-select: none; cursor: pointer;
background: @c-bg;
[data-prefers-color="dark"] & {
color: @c-text-dark;
border: 1px solid @c-border-dark;
background: @c-bg-dark; }}Copy the code
2. Use CSS to customize properties (variables)
Introduction to the CSS custom properties: developer.mozilla.org/zh-CN/docs/…
app.tsx
// Replace less with CSS and keep the rest of the code the same.
- import "./styles.less";
+ import "./styles.css"; .Copy the code
styles.css
html {
--c-bg: #fff;
--c-text: # 141414;
--c-border: #d9d9d9;
}
html[data-prefers-color="dark"] {
--c-bg: # 141414;
--c-text: rgba(255.255.255.0.65);
--c-border: # 434343;
}
body {
background: var(--c-bg);
}
.App {
font-family: sans-serif;
text-align: center;
color: var(--c-text);
}
.btn {
margin-top: 10px;
padding: 4px 15px;
font-size: 14px;
border-radius: 2px;
color: rgba(0.0.0.0.85);
color: var(--c-text);
border: 1px solid var(--c-border);
user-select: none;
cursor: pointer;
background: var(--c-bg);
}
Copy the code
Can also be modified by js: document documentElement. Style. The setProperty (‘ – themeColor ‘, ‘# 333’);
3. Dynamic change <link>
Suppose the following subject directories exist:
├─ dark.css ├─ light.CSS ├─ blue.css ├─ red.css ├─ yellow.cssCopy the code
onClick = (theme) = > {
let styleLink = document.getElementById('theme-style');
if (styleLink) {
// If there is a link tag with id as theme-style, modify its href directly
styleLink.href = `/theme/${theme}.css`; // Switch themes}}else {
// Create a new one if it does not exist
styleLink = document.createElement('link');
styleLink.type = 'text/css';
styleLink.rel = 'stylesheet';
styleLink.id = 'theme-style';
styleLink.href = '/theme/light.css';
}
document.body.append(styleLink); }};Copy the code
4. Use less. ModifyVars ()
color.less
@c-bg: #fff;
@c-text: # 141414;
@c-border: #d9d9d9;
Copy the code
index.html
<! DOCTYPEhtml>
<html lang="en">.<head>
<link rel="stylesheet/less" type="text/css" href="/color.less" />
</head>.</html>
Copy the code
app.tsx
import "./styles.less";
const loadScript = (src: string) = > {
return new Promise((resolve, reject) = > {
const script = document.createElement("script");
script.type = "text/javascript";
script.src = src;
script.onload = resolve;
script.onerror = reject;
document.head! .appendChild(script); }); };let lessLoaded = false;
export default function App() {
// Switch themes
const changeTheme = (type: string) = > {
// You can automatically configure the topic by type
// const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)")
// .matches;
const changeColor = () = >{(window as any).less
.modifyVars({
"@c-bg": "# 141414"."@c-text": "Rgba (255, 255, 255, 0.65)"."@c-border": "# 434343"
})
.then((res) = > {
alert("Theme changed successfully!");
});
};
const lessUrl =
"https://gw.alipayobjects.com/os/lib/less/3.10.3/dist/less.min.js";
if (lessLoaded) {
changeColor();
} else{(window as any).less = {
async: true.javascriptEnabled: true
};
loadScript(lessUrl).then(() = > {
lessLoaded = true; changeColor(); }); }};return (
/ /... Same as above...
);
}
Copy the code
- None of the above methods are initialized. If you need to initialize, please call the switch topic function.
- Each of the above methods has its own advantages and disadvantages. Please choose them accordingly. If there is a better solution, please share it. 🤣 🤣 🤣