英文:
How to change CSS dynamically for whole site with vite and lit?
问题
Dear all, 我正在开发一个使用 Vite 和 Lit 的 Node 应用程序。我希望用户可以在运行时动态更改样式,例如在整个站点之间选择暗黑和明亮的主题。
我知道您可以直接import
“css”文件并将其应用于单个 Lit 元素。但是如何在整个站点上动态更改样式呢?我还注意到ìmport from "xxxx.css"
不能包含动态变量,因此以下内容似乎不受支持?
let theme = "dark"
import "folder/" + theme + ".css";
有什么建议可以帮助我实现这个目标吗?
英文:
Dear all I am developing a node app with vite and lit. I like to have the option that the user can change the style dynamically at runtime for instance to select between a dark and bright theme for the whole site.
I know that you can directly import
"css" files and apply it on single lit elements. But how I can change the style dynamically for the whole site? I also noticed that an ìmport from "xxxx.css"
can not contain a dynamic variable,so the following seems not to be supported?
let theme = "dark"
import "folder/" + theme + ".css";
Any suggestion how I can best achieve my goal?
答案1
得分: 1
这最好通过将所有元素中的颜色设置为CSS自定义属性来处理。例如:
class MyCustomCard extends LitElement {
static styles = css`
.card {
/* 设置自定义属性和默认值 */
background-color: var(--sys-color-surface, #FFF);
color: var(--sys-color-on-surface, #000);
...
}
`;
...
}
然后,您可以在文档的根目录下创建一个名为theme.css
的主题文件。例如:
<!-- index.html -->
<head>
<link rel="stylesheet" href="theme.css">
</head>
/* theme.css */
/* 亮色主题 */
:root, body.force-light-mode {
--sys-color-surface: #FFF;
--sys-color-on-surface: #000;
...
}
/* 自动暗色主题 */
@media (prefers-color-scheme: dark) {
:root {
--sys-color-surface: #000;
--sys-color-on-surface: #FFF;
...
}
}
/* 用户偏好的暗色模式 */
body.force-dark-mode {
/* 这可以使用 @import 来去重复 https://developer.mozilla.org/en-US/docs/Web/CSS/@import */
--sys-color-surface: #000;
--sys-color-on-surface: #FFF;
...
}
然后,您可以创建一个切换暗色主题的切换按钮,该按钮会在body
上切换force-*-mode
类:
class ThemeToggle extends LitElement {
render() {
return html`
<div>Select Theme</div>
<label>
Light Mode
<input
type="radio"
@change=${this.onChange('light')}
name="theme">
</label>
<label>
Follow System
<input
type="radio"
@change=${this.onChange('system')}
name="theme"
checked>
</label>
<label>
Dark Mode
<input
type="radio"
@change=${this.onChange('dark')}
name="theme">
</label>`
}
onChange = (mode) => (e) => {
if (e.target.checked) {
switch(mode) {
case 'light':
document.body.classList.add('force-light-mode');
break;
case 'dark':
document.body.classList.add('force-dark-mode');
break;
}
} else {
switch(mode) {
case 'light':
document.body.classList.remove('force-light-mode');
break;
case 'dark':
document.body.classList.remove('force-dark-mode');
break;
}
}
}
}
英文:
This is best handled by setting all your colors in your elements as CSS Custom Properties. e.g.
class MyCustomCard extends LitElement {
static styles = css`
.card {
/* Set custom property and default value */
background-color: var(--sys-color-surface, #FFF);
color: var(--sys-color-on-surface, #000);
...
}
`;
...
}
Then you can have a theming.css file at the root of your document. e.g.
<!-- index.html -->
<head>
<link rel="stylesheet" href="theme.css">
</head>
/* theme.css */
/* light theme */
:root, body.force-light-mode {
--sys-color-surface: #FFF;
--sys-color-on-surface: #000;
...
}
/* auto dark theme */
@media (prefers-color-scheme: dark) {
:root {
--sys-color-surface: #000;
--sys-color-on-surface: #FFF;
...
}
}
/* user preference dark mode */
body.force-dark-mode {
/* This can be deduplicated with an @import https://developer.mozilla.org/en-US/docs/Web/CSS/@import */
--sys-color-surface: #000;
--sys-color-on-surface: #FFF;
...
}
Then you can have a dark theme toggle that toggles the force-*-mode
class on body:
class ThemeToggle extends LitElement {
render() {
return html`
<div>Select Theme</div>
<label>
Light Mode
<input
type="radio"
@change=${this.onChange('light')}
name="theme">
</label>
<label>
Follow System
<input
type="radio"
@change=${this.onChange('system')}
name="theme"
checked>
</label>
<label>
Dark Mode
<input
type="radio"
@change=${this.onChange('dark')}
name="theme">
</label>`
}
onChange = (mode) => (e) => {
if (e.target.checked) {
switch(mode) {
case 'light':
document.body.classList.add('force-light-mode');
break;
case 'dark':
document.body.classList.add('force-dark-mode');
break;
}
} else {
switch(mode) {
case 'light':
document.body.classList.remove('force-light-mode');
break;
case 'dark':
document.body.classList.remove('force-dark-mode');
break;
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论