Element: [Bug Report] custom theme, CSS repeated multiple times

Created on 2 Jul 2018  ·  58Comments  ·  Source: ElemeFE/element

Element UI version

2.4.2

OS/Browsers version

ubuntu16.4

Vue version

2.5.17-beta.0

Reproduction Link

https://jsfiddle.net/mmx38qxw/localproject

Steps to reproduce

按照官网2种自定义主题步骤操作,设置好新的主题后,打开项目页面,从控制台可以看到button,input等空间的样式重复多次,有4次,7次甚至更多次.
使用webpack css去重插件也不生效

What is Expected?

css样式不重复

What is actually happening?

css样式重复

Most helpful comment

I meet the same problem

All 58 comments

Translation of this issue:

Element UI version
2.4.2

OS/Browsers version
Ubuntu16.4

Vue version
2.5.17-beta.0

Reproduction Link
https://jsfiddle.net/mmx38qxw/localproject

Steps to reproduce
According to the operation of 2 custom theme steps of the official network, after setting up a new theme, opening the project page, from the console, you can see that the style of button, input and other spaces can be repeated many times, 4 times, 7 times or even more times.

The use of webpack CSS to remove the plug-in is not effective
What is Expected?

CSS style does not repeat
What is actually happening?

CSS style duplication

I meet the same problem

@ashen9 请问你解决了吗

Same problem on 2.4.6, make my custom template overridden by the default one.

In my project same styling gets repeated > 10 times. I believe it might have something to do with the webpack setup?

@ststaynov i had tried to add some plugins to deal css in webpackconfigs,but nothing happend

Same to me ( I got 7 times), and I used this way http://element-cn.eleme.io/#/zh-CN/component/custom-theme#zai-xiang-mu-zhong-gai-bian-scss-bian-liang

Did somebody managed to resolve this? :/

I have the same problem.

@ashen9 请问你解决了吗

没有,应该是按需加载时各个组件有重复定义的class,改成全量加载后,element打包去重了

Same issue;
If want to use input & input-number, and import styles and components on demand, I have styles included twice, because, for my example, in file: input-number.scss i have:
@import "input";
Why was it imported in all components? Not enough mixins & vars? 👎

Same problem.

same here

"element-ui": "^2.4.5" same problem

same problem
怀疑是否现部分scss文件的引用有问题
以下是dropdown.scss的头部

@import "mixins/mixins";
@import "common/var";
@import "button";
@import "./popper";

是不是这里@import了button导致button样式重复编译


fast-sass-loader can fix this bug. It can remove the duplication code.

same problem v2.6.1 on nuxt

repeat

same! and its killing me.
I doubt whether this is because element does not make use of sass partials.

The problem still exist in version 2.7, how to fix this?

the same on 2.8.0

@Leopoldthecoder @QingWei-Li are you aware of this?

same problem
怀疑是否现部分scss文件的引用有问题
以下是dropdown.scss的头部

@import "mixins/mixins";
@import "common/var";
@import "button";
@import "./popper";

是不是这里@import了button导致button样式重复编译

fast-sass-loader can fix this bug. It can remove the duplication code.

@chenzhq 指出了问题的根源。多处scss 组件模块重复引用了其他模块,导致本地开发会看到多份重复样式,只是因为 production build 的时候被自动dedup了

@Leopoldthecoder @QingWei-Li 移除组件内部的重复引用是否可行?还是说因为要兼顾按需引用的特性才搞成这样?

@Leopoldthecoder @QingWei-Li are you aware of this?

same problem
怀疑是否现部分scss文件的引用有问题
以下是dropdown.scss的头部

@import "mixins/mixins";
@import "common/var";
@import "button";
@import "./popper";

是不是这里@import了button导致button样式重复编译
fast-sass-loader can fix this bug. It can remove the duplication code.

@chenzhq 指出了问题的根源。多处scss 组件模块重复引用了其他模块,导致本地开发会看到多份重复样式,只是因为 production build 的时候被自动dedup了

using fast-sass-loader only fixes it on production? or also on dev?

@edum18 both. Depend on your webpack orvue.config.js.
you can use it to replace the sass-loader.

This is not an elegant solution.

Anybody tested on the latest version 2.9.1?

Anybody tested on the latest version 2.9.1?

Yeah, problem is still there...

same problem here with [email protected]

I have the same problem with [email protected]

I tried to do that but it didn't work。Where is the configuration error?CSS repeated 2 times

chainWebpack: config => {
    const types = ['vue-modules', 'vue', 'normal-modules', 'normal'];

    const addFastSassLoader = rule => {
        rule
            .use('sass-loader')
            .set('loader', 'fast-sass-loader');
    };
    const scssRule = config.module.rule('scss');
    const sassRule = config.module.rule('sass');
    types.forEach(type => addFastSassLoader(scssRule.oneOf(type)));
    types.forEach(type => addFastSassLoader(sassRule.oneOf(type)));
},

[email protected] is normal,now is [email protected]
vue-cli is 3.0.0-rc.11

I tried to do that but it didn't work。my CSS repeated 7 times,[email protected]

chainWebpack: config => { ['scss', 'sass'].forEach(style => { ['vue', 'vue-modules', 'normal-modules', 'normal'].forEach(one => { config.module .rule(style) .oneOf(one) .use('sass-loader') .loader('fast-sass-loader') }) }) }

function replaceSassLoader2Fast(rule) {
    rule.use('sass-loader')
        .loader('fast-sass-loader')
        .options({
            includePaths: [
                path.join(process.cwd(), 'src'),
            ],
        });
}
// chainWebpack
const types = ['vue-modules', 'vue', 'normal-modules', 'normal'];
types.forEach((type) => {
    replaceSassLoader2Fast(config.module.rule('scss').oneOf(type));
});

same problem with sass-loader, webpack4 and [email protected] duplicated over 5 times :(

we moved off element-ui because of this issue, hope it gets sorted soon :)

I solved this issue by importing a custom css theme created on https://element.eleme.io/#/en-US/theme
You can configure the same variables as you would do with a custom theme but, in this case, the theme builder creates a .css file for you. Download the custom theme and import it:

import Vue from 'vue';
import Element from 'element-ui';

import PTlang from 'element-ui/lib/locale/lang/pt-br';
import locale from 'element-ui/lib/locale';

// Custom theme you just created  
import '../assets/styles/element-ui-theme/theme/index.css';

locale.use(PTlang);
Vue.use(Element);

Don't forget to add the fonts folder that comes with your downloaded theme.
My element-ui-theme directory:
image

Hi, @iamkun Could you solve this problem? Many people have met it. Thx.

same problem.
image

same here, hope this will get solved real soon.

Same problem, any workaround ?

Same problem, any workaround ?

a workaround was already posted.

Same issue. I add optimization in dev config to fix it.

// webpack.dev.js
...
optimization: {
    splitChunks: {
      cacheGroups: {
        styles: {
          name: 'styles',
          test: /\.css$/,
          chunks: 'all',
          enforce: true
        }
      }
    }
  }
...

For people having css rules loaded more than twice I know where the problem lies, a bug exists with the sass loader that will bundle the file every time it is imported in another scss file

So if you are importing your theme.scss in other components to use the colors of your theme then you should just import the colors/variables in this file, so split your theme.scss into two files

1 - colors.scss

$--color-primary: #00A09E;
$--color-warning: #EE7219;
$--color-danger: #FE4A49;
$--color-info: #00AEEF;
$--color-success: #D6AE15;
$--color-text-primary: #242B35;
$--color-text-secondary: #D6AE15;

2 - theme.scss

@import "colors";

$--font-path: '~element-ui/lib/theme-chalk/fonts';

// The default generated file is
// @import "~element-ui/packages/theme-chalk/src/index";
// If you want to reduce the size further by getting rid of unused css, 
// copy the content of the previous file and comment the lines of the elements you don't need:
@import "~element-ui/packages/theme-chalk/src/base.scss";
@import "~element-ui/packages/theme-chalk/src/pagination.scss";
@import "~element-ui/packages/theme-chalk/src/dialog.scss";
@import "~element-ui/packages/theme-chalk/src/autocomplete.scss";
@import "~element-ui/packages/theme-chalk/src/dropdown.scss";
@import "~element-ui/packages/theme-chalk/src/dropdown-menu.scss";
@import "~element-ui/packages/theme-chalk/src/dropdown-item.scss";
@import "~element-ui/packages/theme-chalk/src/menu.scss";
@import "~element-ui/packages/theme-chalk/src/submenu.scss";
@import "~element-ui/packages/theme-chalk/src/menu-item.scss";
@import "~element-ui/packages/theme-chalk/src/menu-item-group.scss";
@import "~element-ui/packages/theme-chalk/src/input.scss";
@import "~element-ui/packages/theme-chalk/src/input-number.scss";
@import "~element-ui/packages/theme-chalk/src/radio.scss";
@import "~element-ui/packages/theme-chalk/src/radio-group.scss";
@import "~element-ui/packages/theme-chalk/src/radio-button.scss";
@import "~element-ui/packages/theme-chalk/src/checkbox.scss";
@import "~element-ui/packages/theme-chalk/src/checkbox-button.scss";
@import "~element-ui/packages/theme-chalk/src/checkbox-group.scss";
@import "~element-ui/packages/theme-chalk/src/switch.scss";
@import "~element-ui/packages/theme-chalk/src/select.scss";
@import "~element-ui/packages/theme-chalk/src/button.scss";
@import "~element-ui/packages/theme-chalk/src/button-group.scss";
@import "~element-ui/packages/theme-chalk/src/table.scss";
@import "~element-ui/packages/theme-chalk/src/table-column.scss";
@import "~element-ui/packages/theme-chalk/src/date-picker.scss";
@import "~element-ui/packages/theme-chalk/src/time-select.scss";
@import "~element-ui/packages/theme-chalk/src/time-picker.scss";
@import "~element-ui/packages/theme-chalk/src/popover.scss";
@import "~element-ui/packages/theme-chalk/src/tooltip.scss";
@import "~element-ui/packages/theme-chalk/src/message-box.scss";
@import "~element-ui/packages/theme-chalk/src/breadcrumb.scss";
@import "~element-ui/packages/theme-chalk/src/breadcrumb-item.scss";
@import "~element-ui/packages/theme-chalk/src/form.scss";
@import "~element-ui/packages/theme-chalk/src/form-item.scss";
@import "~element-ui/packages/theme-chalk/src/tabs.scss";
@import "~element-ui/packages/theme-chalk/src/tab-pane.scss";
@import "~element-ui/packages/theme-chalk/src/tag.scss";
@import "~element-ui/packages/theme-chalk/src/tree.scss";
@import "~element-ui/packages/theme-chalk/src/alert.scss";
@import "~element-ui/packages/theme-chalk/src/notification.scss";
@import "~element-ui/packages/theme-chalk/src/slider.scss";
@import "~element-ui/packages/theme-chalk/src/loading.scss";
@import "~element-ui/packages/theme-chalk/src/row.scss";
@import "~element-ui/packages/theme-chalk/src/col.scss";
@import "~element-ui/packages/theme-chalk/src/upload.scss";
@import "~element-ui/packages/theme-chalk/src/progress.scss";
@import "~element-ui/packages/theme-chalk/src/spinner.scss";
@import "~element-ui/packages/theme-chalk/src/message.scss";
@import "~element-ui/packages/theme-chalk/src/badge.scss";
@import "~element-ui/packages/theme-chalk/src/card.scss";
@import "~element-ui/packages/theme-chalk/src/rate.scss";
@import "~element-ui/packages/theme-chalk/src/steps.scss";
@import "~element-ui/packages/theme-chalk/src/step.scss";
@import "~element-ui/packages/theme-chalk/src/carousel.scss";
@import "~element-ui/packages/theme-chalk/src/scrollbar.scss";
@import "~element-ui/packages/theme-chalk/src/carousel-item.scss";
@import "~element-ui/packages/theme-chalk/src/collapse.scss";
@import "~element-ui/packages/theme-chalk/src/collapse-item.scss";
@import "~element-ui/packages/theme-chalk/src/cascader.scss";
@import "~element-ui/packages/theme-chalk/src/color-picker.scss";
@import "~element-ui/packages/theme-chalk/src/transfer.scss";
@import "~element-ui/packages/theme-chalk/src/container.scss";
@import "~element-ui/packages/theme-chalk/src/header.scss";
@import "~element-ui/packages/theme-chalk/src/aside.scss";
@import "~element-ui/packages/theme-chalk/src/main.scss";
@import "~element-ui/packages/theme-chalk/src/footer.scss";
@import "~element-ui/packages/theme-chalk/src/timeline.scss";
@import "~element-ui/packages/theme-chalk/src/timeline-item.scss";
@import "~element-ui/packages/theme-chalk/src/link.scss";
@import "~element-ui/packages/theme-chalk/src/divider.scss";
@import "~element-ui/packages/theme-chalk/src/image.scss";
@import "~element-ui/packages/theme-chalk/src/calendar.scss";
@import "~element-ui/packages/theme-chalk/src/backtop.scss";
@import "~element-ui/packages/theme-chalk/src/infinite-scroll.scss";
@import "~element-ui/packages/theme-chalk/src/page-header.scss";
@import "~element-ui/packages/theme-chalk/src/cascader-panel.scss";
@import "~element-ui/packages/theme-chalk/src/avatar.scss";
@import "~element-ui/packages/theme-chalk/src/drawer.scss";
@import "~element-ui/packages/theme-chalk/src/popconfirm.scss";

And then in your app's scss (not in js) replace your theme imports (eg: @import '{}/element-ui/theme.scss) to color imports (@import '{}/element-ui/colors.scss)

You will also need to get rid of the default element css file (the one without your custom colors)
If you generated your element-ui config with vue-cli (like I did) this is how to do it

Even though you chose to have a custom theme during generation of the config, the plugin still added those lines in babel.config.js (this is a bug that needs to be fixed)

module.exports = {
  'presets': [
    '@vue/cli-plugin-babel/preset'
  ],
  'plugins': [
    [
      'component',
      {
        'libraryName': 'element-ui',
        'styleLibraryName': 'theme-chalk' //THIS
      }
    ]
  ]
}

Change it to

module.exports = {
  'presets': [
    '@vue/cli-plugin-babel/preset'
  ],
  'plugins': [
    [
      'component',
      {
        'libraryName': 'element-ui',
        'style': false
      }
    ]
  ]
}

And the css included will only be your optimized theme's version

Same Issue. Version: 2.11.1

.el-input__inner style repeated 18 times.

@Tofandel After trying your solution, repetition reduced to 11, but it still exists.

@Tofandel didn't work for me.

@munjal-vandana did you do both suggestions?

I'm pretty sure you're including your custom theme multiple times

@munjal-vandana did you do both suggestions?

I'm pretty sure you're including your custom theme multiple times

Yes! It was due to the Custom theme.

@praveenpuglia You know without giving details, I can't help you.. What did you try? What is not working?

I used whatever you suggested above. Still see a lot of duplicates. Specially with input elements.

Change it to

module.exports = {
  'presets': [
    '@vue/cli-plugin-babel/preset'
  ],
  'plugins': [
    [
      'component',
      {
        'libraryName': 'element-ui',
        'style': false
      }
    ]
  ]
}

And the css included will only be your optimized theme's version

I use Vue CLI, which use PostCSS. Besides @chenzhq solution, here is another fix with postcss-loader:

Edit postcss.config.js to enable cssnano to remove duplicate CSS.

module.exports = {
  plugins: {
    autoprefixer: {},
    cssnano: {}
  },
};

Be aware compile and hot reload will become slower(around 1s on my laptop). Maybe fast-sass-loader is a better option considering efficiency.

P.S. Don't know if element-ui will fix it. Since duplication seems to be intended and is not a real bug. However "import-once" might fix the root casue of this issue once available https://github.com/sass/sass/issues/1094

@Pingren I tried the solution you mentioned but it didn't really work. :(
Will it only remove during build time or during development as well?

@Pingren I tried the solution you mentioned but it didn't really work. :(
Will it only remove during build time or during development as well?

During development as well. Try upgrade your Vue CLI first. According to changelog, it is a new feature introduced in version4.1.0-beta.0 (2019-11-09). Otherwhise you need to enable PostCSS manually.

https://github.com/vuejs/vue-cli/pull/4798

I already have Vue CLI 4.1.2 and I also have the postcss config file.

Excuse me, has this problem been solved? I met it too. It makes me feel egg pain...

I've tried all proposed here solutions but nothing works for me. I'm using vue cli and I came up with this solution (it isn't elegant but at least it works):

module.exports = {
  configureWebpack: {
    plugins: [
      new webpack.NormalModuleReplacementPlugin(
        /element-ui[\/\\]lib[\/\\]theme-chalk[\/\\](.*)\.css/,
        'node-libs-browser/mock/empty'
      ),
    ],
  }
}

I'm importing my scss with element variables only once in the application entry point.
Hope this will help someone.

@Tofandel 采用你的方案解决了我遇到的问题,感谢! 关键部分是base.scss文件的的引入

@andr-canandr Did you check your babel.config.js file for the following?

module.exports = {
  'presets': [
    '@vue/cli-plugin-babel/preset'
  ],
  'plugins': [
    [
      'component',
      {
        'libraryName': 'element-ui',
       // 'styleLibraryName': 'theme-chalk' //THIS should be 
        'styleLibraryName': "~src/plugins/theme.scss" //Path to your theme file
      }
    ]
  ]
}

I found all the correct info to setup a theme deeply burried in the custom-theme.md

The other documentation is completely incorrect and misleading

if you are using theme build tool:

https://github.com/ElementUI/element-theme

you could reference the issue , it solves the problem that removes all the duplicated css classes.

https://github.com/ElementUI/element-theme/issues/66

just add the arguments --minimize in your theme build command

yarn et  --minimize 

emmm...still exist

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fscardua picture fscardua  ·  3Comments

yorululu picture yorululu  ·  3Comments

zhguokai picture zhguokai  ·  3Comments

yuchonghua picture yuchonghua  ·  3Comments

akaylh picture akaylh  ·  3Comments