如何使用 CSS 实现暗/亮模式。
如果您曾经为大型 Web 应用编写过 CSS,那么您一定知道管理 CSS 有多难。再加上日益增长的对应用支持暗色和亮色模式的需求,您的应用将变得无比繁琐。掌握一些方法论和预处理器固然重要,但即使有了这些工具,如果从一开始就没有进行合理的结构化,CSS 代码库也很容易膨胀成一个庞然大物,难以管理。
在本指南中,我将向您介绍一个我用来管理 CSS 的简单系统,以及如何将其融入您当前的前端工作流程。我们将首先简要介绍一些方法论和预处理器,以及为什么如果您还没有学习过,就应该学习一个。
为什么我们需要 CSS 方法论?
在编写 CSS 时,我认为最好避免选择标签,甚至避免选择元素的后代,因为 HTML 结构将来可能会发生变化。更好的选择是将 HTML 拆分成独立的组件,使用类来设置样式,然后将它们组合起来以实现所需的界面,这就是 CSS 方法论的用武之地。CSS 方法论是正式的、文档化的 CSS 编写系统,它使我们能够将前端作为一组小型、独立的模块进行开发、维护和扩展。
CSS 方法论为我们提供了有效管理 CSS 的结构和思维模型。借助 CSS 方法论,我们可以轻松地遵循 DRY(不要重复自己)的理念,因为我们的 CSS 会被划分成独立的模块,这使得样式设计变得轻而易举,而重复则变得困难。
为什么我们需要 CSS 预处理器?
方法论为我们提供了管理 CSS 的系统,而 SASS、LESS 和 Stylus 等预处理器则提供了以易于理解和维护的方式实现这些预处理器的工具。市面上有不少方法论和预处理器可供选择,但在本指南中,我将使用 BEM 方法论,因为它相对容易上手且非常直观。此外,由于 SASS 广受欢迎,我也会选择它作为我的预处理器。
构建 CSS 的更好方法
构建可扩展且可维护的系统的第一步是将主要值分组。主要值是指系统多个部分依赖的值,例如颜色、字体系列和字体大小。如果系统的多个组件都依赖某个值,则最好将该值隔离并存储在某个位置,然后从依赖该值的组件中引用该值,而不是将其硬编码到这些组件中。这样,当系统发生变更时,我们只需更新系统的一部分,并将变更反映到所有依赖该值的组件中。
对原色值进行分组时,我们会将这些值存储在 CSS 变量中,并在组件中引用这些变量。我们想要做的是挑选原色和字体,并将它们存储在名称易于理解的 CSS 变量中。如果我们有 UI 可供查看,那么操作起来会更容易;但如果没有,我们就需要自己做出这些艰难的设计决策。
有些设计会针对不同的层级结构使用不同的字体,并针对不同的消息/文本使用不同的颜色,因此了解我们正在处理的内容至关重要。命名字体变量时,最好根据其用例来命名,而不是使用一些通用名称,颜色变量也一样。我们希望放弃像 --font-ubuntu、--color-red 这样的命名,而使用像 --headline-font、--main-accent-color 这样的命名,因为这些名称能够清晰地解释每种字体和颜色在系统中的作用。这样,我们就能一目了然地了解每种颜色和字体的作用。
结合我们目前所说的一切,我们的代码库应该看起来更像这样。
:root {
--main-accent0: hsl(165, 100%, 50%);
/* lighter version for hovers */
--main-accent1: hsl(165, 100%, 90%);
--headline-font: Ubuntu;
}
/* then in our call to action we can do like this*/
.button {
background-color: var(--main-accent0);
font-family: var(--headline-font);
&:hover {
background-color: var(--main-accent-1);
}
}
如何构建 CSS 以进行主题切换
说到主题(深色模式/浅色模式),我知道几个想法:一种方法是将深色和浅色主题变量放在各自的样式表中,并在用户需要时加载。我不喜欢这种方法,因为浏览器必须从服务器获取主题,而对于高延迟的服务器、网速较差的用户,甚至离线使用我们应用的用户,我们的 Web 应用都可能无法流畅运行。
我推荐的方法是将所有变量放在一个样式表中,然后将它们拆分成不同的类,然后根据我们想要实现的模式来切换这些类。我的意思如下。
/*main.scss*/
.theme {
&__light {
--high-contrast-bg: hsl(194, 2%, 93%);
--high-contrast-text: hsl(194, 2%, 28%);
}
&__dark {
--high-contrast-bg: hsl(194, 2%, 48%);
--high-contrast-text: hsl(194, 2%, 98%);
}
}
.card {
padding: 20px;
background-color: var(--high-contrast-bg);
color: var(--high-contrast-text);
}
<!-- index.html -->
<body class="theme theme__light">
<div class="card">
<div class="card__header">
header
</div>
<div class="card__body">
body
</div>
<button class="theme-switcher">switch to <span class="theme-switcher__current-mode">dark</span> mode</button>
</div>
</body>
下面是一个可以帮助我们实现这一目标的 Javascript 代码片段。
document.addEventListener("DOMContentLoaded", () => {
const theme = document.querySelector(".theme");
const button = document.querySelector(".theme-switcher");
const mode = document.querySelector(".theme-switcher__current-mode");
button.addEventListener("click", () => {
theme.classList.remove("theme__dark", "theme__light");
if (mode.innerText == "dark") {
theme.classList.add("theme__dark");
mode.innerText = "light";
} else {
theme.classList.add("theme__light");
mode.innerText = "dark";
}
});
});
感谢您阅读本指南,希望您有所收获。如果您对本指南有任何疑问或建议,请随时提出。
文章来源:https://dev.to/uduakabaci/how-to-achieve-darklight-mode-with-css-3p07