--- title: Theming lang: en-US --- # Custom theme Element Plus uses BEM-styled CSS so that you can override styles easily. But if you need to replace styles at a large scale, e.g. change the theme color from blue to orange or green, maybe overriding them one by one is not a good idea. We provide four ways to change the style variables. ## Change theme color These are examples about custom theme. - Full import: [element-plus-vite-starter](https://github.com/element-plus/element-plus-vite-starter) - On demand: [unplugin-element-plus/examples/vite](https://github.com/element-plus/unplugin-element-plus) ### By SCSS variables `theme-chalk` is written in SCSS. You can find SCSS variables in [`packages/theme-chalk/src/common/var.scss`](https://github.com/element-plus/element-plus/blob/dev/packages/theme-chalk/src/common/var.scss). :::warning We use sass modules ([sass:map](https://sass-lang.com/documentation/values/maps)...) and `@use` to refactor all SCSS variables. And by using `@use` to all SCSS variables, it solves the duplicate output problem caused by `@import`. > [Introducing Sass Modules | CSS-TRICKS](https://css-tricks.com/introducing-sass-modules/) For example, We use `$colors` as a map to preserve different types of colors. `$notification` is a map where all variables of the `notification` component at. In the future, we will write documentation for variables that can be customized for each component. You can also directly checkout the source [var.scss](https://github.com/element-plus/element-plus/blob/dev/packages/theme-chalk/src/common/var.scss). ::: ```scss $colors: () !default; $colors: map.deep-merge( ( 'white': #ffffff, 'black': #000000, 'primary': ( 'base': #409eff, ), 'success': ( 'base': #67c23a, ), 'warning': ( 'base': #e6a23c, ), 'danger': ( 'base': #f56c6c, ), 'error': ( 'base': #f56c6c, ), 'info': ( 'base': #909399, ), ), $colors ); ``` ### How to override it? If your project also uses SCSS, you can directly change Element Plus style variables. Create a new style file, e.g. `styles/element/index.scss`: :::warning You should use `@use 'xxx.scss' as *;` instead of `@import 'xxx.scss';`. Because the sass team said they will remove `@import` eventually. > [Sass: @use](https://sass-lang.com/documentation/at-rules/use) vs [Sass: @import](https://sass-lang.com/documentation/at-rules/import) ::: ```scss // styles/element/index.scss /* just override what you need */ @forward 'element-plus/theme-chalk/src/common/var.scss' with ( $colors: ( 'primary': ( 'base': green, ), ) ); // If you just import on demand, you can ignore the following content. // if you want to import all styles: // @use "element-plus/theme-chalk/src/index.scss" as *; ``` Then in the entry file of your project, import this style file instead of Element's built CSS: :::tip Import `element/index.scss` before scss of element-plus to avoid the problem of sass mixed variables, because we need generate light-x by your custom variables. ::: Create a `element/index.scss` to combine your variables and variables of element-plus. (If you import them in ts, they will not be combined.) :::tip In addition, you should distinguish your scss from the element variable scss. If they are mixed together, each hot update of `element-plus` needs to compile a large number of scss files, resulting in slow speed. ::: ```ts import { createApp } from 'vue' import './styles/element/index.scss' import ElementPlus from 'element-plus' import App from './App.vue' const app = createApp(App) app.use(ElementPlus) ``` If you are using vite, and you want to custom theme when importing on demand. Use `scss.additionalData` to compile variables with scss of every component. ```ts import path from 'path' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // You can also use unplugin-vue-components // import Components from 'unplugin-vue-components/vite' // import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' // or use unplugin-element-plus import ElementPlus from 'unplugin-element-plus/vite' // vite.config.ts export default defineConfig({ resolve: { alias: { '~/': `${path.resolve(__dirname, 'src')}/`, }, }, css: { preprocessorOptions: { scss: { additionalData: `@use "~/styles/element/index.scss" as *;`, }, }, }, plugins: [ vue(), // use unplugin-vue-components // Components({ // resolvers: [ // ElementPlusResolver({ // importStyle: "sass", // // directives: true, // // version: "2.1.5", // }), // ], // }), // or use unplugin-element-plus ElementPlus({ useSource: true, }), ], }) ``` If you are using webpack, and you want to custom theme when importing on demand. ```ts // webpack.config.ts // use unplugin-element-plus import ElementPlus from 'unplugin-element-plus/webpack' export default defineConfig({ css: { loaderOptions: { scss: { additionalData: `@use "~/styles/element/index.scss" as *;`, }, }, }, plugins: [ ElementPlus({ useSource: true, }), ], }) ``` ### By CSS Variable CSS Variables is a very useful feature, already supported by almost all browsers. (IE: Wait?) > Learn more from [Using CSS custom properties (variables) | MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) We have used css variables to reconstruct the style system of almost all components. :::tip It is compatible with the SCSS variable system. We use the function of SCSS to automatically generate css variables for use. ::: This means you can dynamically change individual variables inside the component to better customize it without having to modify scss and recompile it. > In the future, the css variable names and role documentation for each component will be written to each component. Like this: ```css :root { --el-color-primary: green; } ``` If you just want to customize a particular component, just add inline styles for certain components individually. ```html Tag ``` For performance reasons, it is more recommended to custom css variables under a class rather than the global `:root`. ```css .custom-class { --el-tag-bg-color: red; } ``` If you want to control css var by script, try this: ```ts // document.documentElement is global const el = document.documentElement // const el = document.getElementById('xxx') // get css var getComputedStyle(el).getPropertyValue(`--el-color-primary`) // set css var el.style['--el-color-primary'] = 'red' ``` If you want a more elegant way, check this out. [useCssVar | VueUse](https://vueuse.org/core/usecssvar/)