ElemeFE / element

A Vue.js 2.0 UI Toolkit for Web
https://element.eleme.io/
MIT License
54.12k stars 14.64k forks source link

[Feature Request] SCSS modules instead of plain .css files #2194

Closed Frondor closed 7 years ago

Frondor commented 7 years ago

This is a huge feature request. Just like https://github.com/twbs/bootstrap-sass does here, this way the import on demand becomes more "friendly" and easy to accomplish. Not to mention that projects like Laravel apps shall see a lot of benefits from this.

Actually, the need of extra webpack configuration to customize the styles is kind of a mess. Laravel user-base find this project really hard to implement on their apps. I strongly believe this is an important feature to work in.

liril-net commented 7 years ago

@Frondor Do u mean that u need a scss version of themes?

Frondor commented 7 years ago

@liril-net I mean to be able to @import each component's CSS just like https://github.com/twbs/bootstrap-sass does through this kind of files, so we create our own builds, and also it would be good to override theme _variables. Just SASS things.

Actually, if we want to customize the styles, we have to build our own theme with extra tools like babel-plugin-component, that's just not right in my humble opinion. webpack's sass-loader is all we would need and the process to import components on demand becomes way more easier with this approach (and cleaner in my opinion).

liril-net commented 7 years ago

@Frondor In my opinion, this can be solved by generating styles separately.

Now it is combined in https://github.com/ElemeFE/element/blob/dev/packages/theme-default/src/index.css.

However in this way, it is impossible to override _variables which already processed by postcss.

Frondor commented 7 years ago

@liril-net I believe you can get rid of postcss in this specific case, because sass works with libsass or something like that, I'm not that deep into preprocessors, so I can't argue about that.

In SCSS there's the !default flag which makes really easy to override $variables if you adopt the sass architecture (pretty similar to what ElemeFe has implemented here). Bootstrap, for example, declares its variables like $brand-primary: #00F !default; which means the variable won't be used unless it wasn't previously declared. This way you can have (talking about a build system obviously), let's say a main.scss file where you load the components' CSS (on demand) and a variables' file, preceded by your own variables file.

I can make a visual example of how it may look like, using some build system like Laravel's elixir. I'm taking bootstrap-sass project as an example because I consider its the best example of what I'm proposing here, and they (twbs) have done a really good and professional work in there.

liril-net commented 7 years ago

@Frondor I have used SCSS for a while, so i do know what u mean and how great the feature is.

I quite agree that we should have access to each component's style, so that we can use it on demand. The tool element-theme we have now is quite awkward to use, maybe we should introduce something awesome into it.

However, all these features you have talked about are based SCSS, we need SCSS build system to override SCSS variables. So maybe need a SCSS version(or something different) of these components' styles. What we have written now is deeply depended on the PostCSS plugin postcss-salad. It is not difficult for webapck to process postcss, in my opinion it maybe a good idea that we just expose original styles to users, and they can process it if needed.

Let's ask @QingWei-Li whether should we implement SCSS version?

QingWei-Li commented 7 years ago
  1. Actually, we can override variables just like SCSS using poscss-salad.
:root {
  --color-primary: #666 !important;
}

@import "element-ui/packages/theme-default/src/index.css";
  1. If we need SCSS version, I would like to be able to automatically generate.

https://github.com/jxnblk/css-scss

liril-net commented 7 years ago

@QingWei-Li I have tried css-scss, however it do not works quite good for me, can you explain when should we introduce into the tool during building?

  1. Before postcss: it can not even parse BEM.
  2. After postcss: We lost all variables.
  3. During postcss: i do not know if we can do this, maybe we should add this feature to postcss-salad?

Maybe my usage is not quite correct, can u show me an example?

QingWei-Li commented 7 years ago

@liril-net Sorry, I have not tested. I just considered whether we could implement a similar tool to generate SCSS version.

liril-net commented 7 years ago

@QingWei-Li So should we start another project to do this? It is not difficult to implement such a DSL.

Do u think that we can simply use RegExp to replace things like variables and BEM? I have only explored some of these styles, i think most of them are compatible to SCSS, aren't they?

QingWei-Li commented 7 years ago

@liril-net

https://github.com/ElementUI/theme-default I try to change the configuration using

{
  "browsers": ["ie > 8", "last 2 versions"],
  "features": {
    "sassColor": false,
    "partialImport": false,
    "precss": false,
    "bem": {
      "shortcuts": {
        "component": "b",
        "modifier": "m",
        "descendent": "e"
      },
      "separators": {
        "descendent": "__",
        "modifier": "--"
      }
    }
  }
}

We can get "CSS" like

@charset "UTF-8";
@import "./common/var.css";

.el-tag{

    background-color: var(--tag-fill);

    display: inline-block;

    padding: var(--tag-padding);

    height: 24px;

    line-height: calc(@height - 2);

    font-size: var(--tag-font-size);
   ....
}

I think we can write a plugin or directly use css-scss to deal with variables. If possible, we can add the feature into the CI that can automatically build and publish SCSS version.

liril-net commented 7 years ago

@QingWei-Li

I have tried ur suggestions with gulp, i find some problems that we should solve:

  1. How to deal with mixin? I have found that css-scss can not correctly translate mixin.
  2. How to deal with BEM? We lost the convenience.
  3. Change @import "foo.css" to @import "foo(.scss)?".
  4. How to deal with fonts? Maybe it is not a good idea to get duplicated fonts.
  5. The file structures? I have tried something like below:
.
├── README.md
├── gulpfile.js
├── lib
│   ├── fonts
│   │   └── xxx.tff
│   ├── css
│   │   └── xxx.css
│   └── scss
│       └── xxx.scss
├── package.json
├── salad.config.json
└── src

It may not be a good idea to use css-scss directly, so we should write our own plugin and we should also change our current file structures to fit new version(maybe u have a better solution). I think we can write some plugin for postcss, we can reuse some output during the process.

QingWei-Li commented 7 years ago

@liril-net

  1. I have no idea. RegExp?
  2. Dont worry about BEM, postcss-salad has been dealt with.
  3. Yes.
  4. We do not need to deal with fonts.
  5. Create a new project under the ElementUI organization, because the element-theme-default has been used in some projects. the repo will compile and push automatically via CI.
liril-net commented 7 years ago

@QingWei-Li

Can u create a new project now? I will fork it and try to implement these features.

QingWei-Li commented 7 years ago

@liril-net

Done https://github.com/ElementUI/theme-default-scss

Look forward to your contribution!

tylertyssedal commented 7 years ago

Implementing SASS would be of great help here and I would be happy to start using Element, but being unable to change the theme variables with ease (without installing a global cli tool) is a big hindrance.

I would like to echo that bootstrap-sass does it it well and may be a good inspiration.

liril-net commented 7 years ago

@metamet We have implemented one version of SCSS at theme-default-scss which is translated from PostCSS version.

whitetrefoil commented 7 years ago

Glad to know the scss version is coming!

Just FYI, in many projects I'm working in, the most difficult problem to replace bootstrap with elementui is also the variables in scss files. It's usual to share the variables (e.g. colors) between bootstrap's theme and each project's own components / styles, to create maintainable code in a very simple build workflow (e.g. a single webpack rule).

In order to achieve the same result, I'm now have to use a template of variable.scss + a template of element-variables.css + a directory file, then create some additional watch processes beside webpack, use tool like gulp-replace to generate those 2 variable file then build out the styles, then send them to webpack dev server...

Frondor commented 7 years ago

@liril-net I little bit of documentation on how to implement and use it would be cool :smile: Although I'm not sure if that project would get the job done :confused: I'd love to know how to integrate it with Laravel's Elixir

Btw, are all of them really needed? That's one hell of dependencies for this kind of project :laughing:

  "devDependencies": {
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-stage-2": "^6.18.0",
    "babel-register": "^6.18.0",
    "balanced-match": "^0.4.2",
    "chai": "^3.5.0",
    "cssmin": "^0.4.3",
    "del": "^2.2.2",
    "gulp": "^3.9.1",
    "gulp-babel": "^6.1.2",
    "gulp-changed": "^1.3.2",
    "gulp-mocha": "^3.0.1",
    "gulp-postcss": "^6.2.0",
    "gulp-rename": "^1.2.2",
    "gulp-sequence": "^0.4.6",
    "gulp-sourcemaps": "^2.3.0",
    "postcss": "^5.2.9",
    "postcss-property-lookup": "^1.2.1",
    "postcss-salad": "^1.0.6"
  }
liril-net commented 7 years ago

@Frondor Of course not, they are only used for development, we will publish this library to npm after enough test.

@whitetrefoil

All you need to do is just download theme-default-scss and import 'theme-default-scss' in your .js/vue or @import in your .scss.

If you want to try this version now, you should follow these steps:

  1. Download them-default-scss.
  2. npm install && gulp build
  3. import 'theme-defualt-scss(the directory you download)'

If documentation needed, maybe i will try to generate one.

liril-net commented 7 years ago

@metamet We have added !default in variables, so you can just override them if needed.

whitetrefoil commented 7 years ago

Trying to build a workflow around theme-default-scss now~ BTW, will we be able to use just npm i -S theme-default-scss then @import "~theme-default-scss/lib/button in near future? 🤗

liril-net commented 7 years ago

@whitetrefoil Of course, we will publish it to npm. @QingWei-Li Maybe you should publish it to occupy the name. 😄

QingWei-Li commented 7 years ago

@whitetrefoil @Frondor theme-default-scss is released.

qidaneix commented 7 years ago

In my opinion, it would be very nice if element-ui can provide the support of the popular preprocessor like Less, SCSS, Stylus and postcss. Just like awesome-font did, which provide the version of Less and SCSS.

In Chinese: 我觉得吧,要是element-ui可以支持一些主流的css预编译器比如Less,SCSS之类就爽歪歪了,就像awesome-font就提供了对Less和SCSS的支持。因为编译压缩过的css代码真的很难修改以及自定义样式(我们的网站都要和饿了么一个风格?)。况且现在vue2的.vue文件也对不同的css预编译器提供了支持(<style lang="scss">),用起来真的很方便。

谢谢了,各位大大们

Frondor commented 7 years ago

To be honest, I never used it because it wasn't implemented how I initially proposed. Plus, that repo does not run the latest CSS of this package. I wanted element-ui to be easy to use (on demand) on Laravel projects using Laravel-mix.

diemah77 commented 7 years ago

@Frondor So how do you use Element's stylesheet right now? Importing index.cssin your SCSS index file?

Frondor commented 7 years ago

@diemah77 I'm not using this package anymore, sadly. But I used to import only the CSS modules I needed, although I couldn't override any variable like I would if it supported SCSS.

diemah77 commented 7 years ago

What's your alternative ui lib then?

mheras commented 6 years ago

Hello, how can I use theme-default-scss with Nuxt.js?

chmcphoy commented 6 years ago

@mheras For nuxt you'd need the the sass-loader & node-sass webpack loaders as per the docs and then create a main.scss file in your assets dir where you can import scss files i.e — @import 'element-theme-default';. Then bringing in the main.scss file in your nuxt.config.js should do it. The nuxtjs.org site has a useful sass setup for reference.

hagemann commented 6 years ago

Is traffic being handled intelligently? I'm just checking the network traffic in dev tools and the whole source code bloats up to 1.1M and almost 50,000 lines using SCSS (compared to 100K and 3,000 lines with the conventional CSS import).