# element-plus-dark

## 起源

Element UI 和现在的 Element Plus 已经成为事实上的 Vue 项目首选骨架，也就是说，哪怕你只需要 Layout、Button、Input 寥寥几个组件，Element 也是首选。

同时，一些项目可能需要暗黑模式，而 Element Plus 目前还未提供官方解决方案，因此诞生了这个非官方项目：Element Plus Dark。

2022 年 2 月 7 日，Element Plus 正式版上线。

2022 年 2 月 17 日，非官方的暗黑模式解决方案 Element Plus Dark v1.0.0 上线。

## DEMO

[http://www.el-pp.com/dark-mode](http://www.el-pp.com/dark-mode)

## 更新日志

- **v3.0.0-2022.7.21**：适应 Element Plus 2.2.0 以后版本，做了若干改进。

- **v2.0.2-2022.3.22**：根据反馈，修改了 Button 组件的暗黑模式样式，变得更合理。

- **v2.0.1-2022.2.24**：删除了一个本项目新增的变量`--dark-bg-color-dark`，合并到`--el-disabled-bg-color`。不妨碍使用。

- **v2.0.0-2022.2.23**：将 CSS 变量声明的位置从`:root`改为`.element-plus-dark`，以便更容易实现一键关闭暗黑模式。你的项目需要做的对应调整是必须给`body`标签加上这个类名。如果你的项目打算局部使用暗黑模式，且**绝对不使用有弹出层的组件**，那么类名也可以放在更深层的元素上。

## 安装

```sh
yarn add element-plus-dark
```

## 使用方法

### 引入 SCSS

#### 1. main.js

```js
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
import App from './App.vue'; // 引入 App.vue 必须放在引入 Element Plus 之后，因为需要在 App.vue 中引入 element-plus-dark，覆盖 Element Plus 原有变量和样式
```

#### 2. App.vue

```scss
// SCSS
$dark-bg-color-base: rgb(你的基本背景色); // 应写，不写即使用默认暗黑背景色 rgb(29, 59, 93)
$dark-mixed-color: rgb(一个接近于白色的色值，用于跟背景色混合成文本颜色和边框颜色); // 可以不写，不写默认使用 #ffffff
@import 'element-plus-dark/index.scss';
```

基础背景色的来源：

如果暗黑模式下用到了大背景图，这时候基础背景色应来自于大背景图，你可以使用图片取色工具（例如[https://www.matools.com/image-color](https://www.matools.com/image-color)）来识别背景图的主背景色。没有背景图的话，就看设计师怎么设计，或者前端工程师怎么选色。

#### 3. index.html

给`body`标签加上`class="element-plus-dark"`即可。

### 进阶步骤

#### 1. 使用官方的《自定义主题》

根据 Element Plus 官方提供的[《自定义主题》](https://element-plus.gitee.io/zh-CN/guide/theming.html)功能，重定义`primary`、`success`、`danger`……的一个或几个色值，即可生成一套定制化更高的暗黑模式主题。

#### 2. 实现一键换肤

详见[《本项目文档》](http://www.el-pp.com/dark-mode/#/guide/quickstart)。

#### 3. 实现一键关闭黑暗模式

详见[《本项目文档》](http://www.el-pp.com/dark-mode/#/guide/quickstart)。

## 本方案优势

### 1. 使用足够简单

最简单情况下，你只需要确定“基本背景色”这一个色值，即可生成一套漂亮的暗黑模式主题。

最复杂情况下，你也只需要先确定基本背景色，再根据 Element Plus 官方提供的[《自定义主题》](https://element-plus.gitee.io/zh-CN/guide/theming.html)功能，重定义`primary`、`success`、`danger`……的一个或几个色值，即可生成一套定制化更高的暗黑模式主题。

### 2. 有科学的变量设计理念和变量使用理念

设计理念在下文详细介绍。

## 变量设计理念

### 1. 单变量入口

只需要给 Sass 变量`$dark-bg-color-base`赋予合理的色值，作为主背景色，其他所有变量全部由这个变量计算而成，包括有一些 Element Plus 原本写死的色值，我方案都改成了计算值。

### 2. 其他变量依赖计算

使用者只需确定 3 类变量：背景色、文本色、边框色。当然，使用者可以自行修改它们的算法。

### 3. 尽量迁就 Element Plus 原有 CSS 变量，重新赋值

这样的变量例如`--el-bg-color`等。

### 4. 创造一些新的 CSS 变量

主要是 6 个背景色变量，可以说它们是我方案的核心变量。

### 5. 抛弃官方的某些原有变量

官方某些变量在我方案中必须抛弃使用，比如`--el-color-white`，这是官方欠考虑的一个变量，它的值是写死的`#ffffff`，可能官方的考虑是将来`#ffffff`可以改为灰白色或者深色，但是，这个变量有时用在文本上，有时用在背景上，在暗黑模式中，白色的字是常见的，往往可以继续沿用，但白色的背景是大忌讳，必须改为暗黑背景，一个变量不可能同时负责文本的白色和背景的深色，这是冲突的，所以我方案只能抛弃这个变量。

## 变量使用理念

### 1. 页面主内容区使用基本背景色

这毫无疑问。

### 2. 位于主内容区中的大型组件，使用基本背景色

比如 Calendar 应使用基本背景色。

### 3. 弹出层，分两种情况考虑：

- 如果弹出层有半透明蒙版，这时候弹出层是作为当前内容区的，比如 Dialog 等，那么弹出层的背景色也使用基本背景色。

- 如果弹出层没有半透明蒙版，比如 Cascader、Select 等，那么弹出层的背景色要使用`--dark-bg-color-light-1`，也就是比基本背景色亮一点，以示区分。如果弹出层之上继续弹出新层，那么使用`--dark-bg-color-light-2`。

### 4. 输入框的背景色，使用`--dark-bg-color-light-1`

在暗黑模式中，输入框背景显然需要跟主背景相区分，要更亮一点，而且它应跟它的下拉层背景色一致，以表示下拉是输入框的延伸，是一个整体，当点击下拉的内容，内容就会跳到输入框中。上文说过，它的下拉弹出层应使用`--dark-bg-color-light-1`，恰好它自身也是用`--dark-bg-color-light-1`，可谓恰到好处。

### 5. 基本背景色上的高亮色，使用`--dark-bg-color-light-1`

这毫无疑问。

### 6. `--dark-bg-color-light-1`里面又需要高亮，使用`--dark-bg-color-light-2`

比如日期选择器的下拉弹出层，它本身是一级高亮，鼠标悬停在日期上的时候，又需要高亮，也就是高亮的高亮，那么使用二级高亮。

### 7. 二级高亮之上再高亮，使用`--dark-bg-color-light-3`

极少场合需要用到，在此不举例。

### 8. disabled 色、不可点击色，一律使用`--el-disabled-bg-color`

通常情况下，无论什么上下文，一律使用`--el-disabled-bg-color`，以表示统一。但是，如果 Element Plus 的某个组件的原本设计是不用 disabled 色，那么我方案也不用。

### 9. Loading 组件的蒙版背景色，重置为`--dark-bg-color-base-alpha`

在白色背景下，蒙版的背景色值无论基于`rgb(0,0,0)`还是基于`rgb(255,255,255)`做透明效果都可以接受，但是在暗黑模式下，这个蒙版的背景色值无论基于`rgb(0,0,0)`还是基于`rgb(255,255,255)`做透明效果都是不科学的，效果会非常突兀，就放佛一块膏药压在区域上方，因为暗黑背景下，背景色的差异会很明显，很突兀。所以我方案设定了这个变量，用于蒙版的背景色。

### 10. 不要有白色背景的交互组件

这里尤其强调 Button 组件，在不设定`type`属性的前提下，它的背景色是纯白色，在白色主题下，白色表示“低调、不显眼”，但是在暗黑模式下，白色表示“夜空中最亮的星”，所以尽量不要使用不带`type`属性的 Button。某些组件内嵌了不带`type`的 Button，我方案专门做了美化处理。
