在我最近的一个项目中,我需要将对暗模式的支持添加到React.js单页应用程序(SPA)。由于我们使用SCSS模块来设计我们的元素,因此让我们探索如何在用SCSS模块的React.js项目中实现Dark Mode。
切换配色方案
在广泛的浏览器支持CSS variables的情况下,我没有看到使用 Body类 + CSS变量方法的任何替代方案。这意味着,当用户在应用程序中启用DAMP模式时,将.dark
类添加到body
标签中,并且根据此类的存在或不存在变量。
CSS变量
如果您尚不熟悉, css变量(自定义属性)是CSS中的实体,可以使您存储值然后在样式中使用它们。例如:
body {
--text-color: #ccc; // define a CSS variable
}
h1 {
color: var(--text-color); // get a variable
}
p {
color: var(--text-color); // get a variable
}
变量名称应始终以双连键( - )开头,然后使用 var()函数访问变量。
var()功能将尝试在其范围内或从其父母中找到 - 文本色变量。就我们而言,这就是身体。但是,您可以重新定义此变量,例如, h1 和 p 元素内部的元素具有不同的颜色:
section {
--text-color: #ddd
}
在我们的情况下,此技巧将有助于覆盖变量。
真实情况
首先,声明设计师在上的布局中使用的所有变量:roo t pseudo-class,然后将它们添加到项目中的 global.scss 文件中:< br>
:root {
--black: #000;
--gray: #ccc;
--white: #fff;
--blue: #0085f2;
}
在这种情况下,我建议不要将变量名称与您打算使用它们的实体相关。例如,不要将它们命名为 - 文本主要色:#ccc ,因为我们将以React组件样式的级别定义此功能。例如,您有一个组件:
import classNames from "classnames";
import styles from "./Text.module.scss";
interface ITextProps {
type?: "primary" | "secondary";
children?: React.ReactNode;
}
export const Text: React.FC<ITextProps> = ({ type = "primary", children }) => {
return (
<p className={classNames(styles.root, styles[`${type}Type`])}>{children}</p>
);
};
您可以看到,这是一个简单的反应组件,可以具有两种类型之一,我们打算在样式文件中处理。
此组件的样式文件(text.module.scss)看起来像这样:
.primaryType {
--text-color: var(--blue);
color: var(--text-color);
}
.secondaryType {
--text-color: var(--black);
color: var(--text-color);
}
在这里,对于每种文本类型,我定义了自己的变量,其值取自:root pseudo-class。
现在,要启用文本模式,我们需要使用 body.dark 类。我们可以如下:
.primaryType {
--text-color: var(--blue);
color: var(--text-color);
}
.secondaryType {
--text-color: var(--black);
color: var(--text-color);
}
:global(.dark) {
.primaryType {
--text-color: var(--gray);
}
.secondaryType {
--text-color: var(--white);
}
}
:Global(.dark)允许我们使用全局SCSS模块类。在这里,我们只是覆盖变量值,由于 dark 类中的嵌套,它将比上面声明的值更高的优先级。
由于我们使用的是SCSS,因此我们可以根据这种方法创建 Mixin 。我们还添加一个媒体查询以根据用户的操作系统设置应用暗模式。
这是Mixin的样子:
SCSS混合
@mixin dark-mode {
@media (prefers-color-scheme: dark) {
@content;
}
:global(.dark) {
@content;
}
}
这是您可以使用此混音的方法:
@import "../styles/mixins";
.primaryType {
--text-color: var(--blue);
color: var(--text-color);
}
.secondaryType {
--text-color: var(--black);
color: var(--text-color);
}
@include dark-mode {
.primaryType {
--text-color: var(--gray);
}
.secondaryType {
--text-color: var(--white);
}
}
这样,组件的黑暗模式样式将被隔离并在文件末端方便地位于端,从而易于通过它们导航。 ð