使用SCSS模块的React.js启用暗模式ð
#javascript #css #react #scss

在我最近的一个项目中,我需要将对暗模式的支持添加到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 。我们还添加一个媒体查询以根据用户的操作系统设置应用暗模式。

Mac OS theme change

这是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);
  }
}

这样,组件的黑暗模式样式将被隔离并在文件末端方便地位于端,从而易于通过它们导航。 ð