3.0.1
https://github.com/lionel-bijaoui/demo-order-css
Node 8.11.4 / npm 5.6.0 / Windows 10
Create a vue-cli project with scss support.
Create a basic component with a style block and add a class.
In this class, put the properties in non alphabetical order.
If you run npm run serve and inspect the style, they should be in the same order as what you wrote them.
If you run npm run build and inspect the style, they will be in alphabetical order
.someclass {
border-radius: 0;
border-bottom-right-radius: $radius;
border-top-right-radius: $radius;
}
.someclass {
border-bottom-right-radius: $radius;
border-radius: 0;
border-top-right-radius: $radius;
}
The CSS properties get reordered alphabetically and it can create unexpected side effects
The change in behavior was observed between v3.0-beta.10 and 3.0.1 but it might be older.
I guess it has something to do with minification, but I was unable to find any option or mention in the changelog.
EDIT: Added link to repo of demo
I changed cssDeclarationSorter option of CSSNano to false but it still change the order
Please provide a reproduction, especially demonstrating how you tried to change cssDeclarationSorter.
Also: Your code exmaples makes it seem as if the SCSS code would be sorted (it contains variables), but you say the final CSS is sorted. which is it.
Yes sorry about the variables, it just a bit of code from my project.
The SCSS variable are really not the problem.
Every CSS property get ordered alphabetically. I'm pretty sure you can test it on any of your projects.
It seem to be related to CSSNano (https://github.com/cssnano/cssnano/issues/592, https://github.com/Siilwyn/css-declaration-sorter/issues/55) more than anything.
How?
Let's take my example, I have a class with radius applied on all corner. Then I create another variation (BEM style) with only radius on the right corners.
$radius: 30px;
.some-class {
border-radius: $radius;
}
.some-class--half-radius-right {
border-radius: 0;
border-bottom-right-radius: $radius;
border-top-right-radius: $radius;
}
In dev mode, no problem, everything work as expected.
But if I build my project, I get that:
.some-class {
border-radius: 30px;
}
.some-class--half-radius-right {
border-bottom-right-radius: 30px;
border-radius: 0;
border-top-right-radius: 30px;
}
This break the style as border-bottom-right-radius will get overrided by border-radius.
So sure, this example can be fixed easily but it create other kind of problems.
Short-hand declaration can override simple declaration depending on order (or vice versa).
In short it can break the cascade.
When working with legacy code or large project, it become very hard to find and fix.
I just wish to disable this, but I can seem to be able to with cssDeclarationSorter set to false
Thank you for your time
@LinusBorg As requested, here is a repo that demonstrate the problem:
https://github.com/lionel-bijaoui/demo-order-css
npm run serve, observe the rectangle with radius applied only on the bottom. Inspect it and you will see the properties of.hello--bottom-corner-onlyare ordered like that:
````css
.hello--bottom-corner-only {
border-radius: 0;
border-bottom-left-radius: 30px;
border-bottom-right-radius: 30px;
}npm run build, open./dist/css/app.***.css. You will see that the properties are order differently, resulting in no radius on corners:
```css
.hello--bottom-corner-only[data-v-870f974c] {
border-bottom-left-radius: 30px;
border-bottom-right-radius: 30px;
border-radius: 0;
}
Hope that help !
EDIT: I pushed a change to set cssDeclarationSorter to false and prove it doesn't change a thing to the issue.
Here is an extract of the config produced by vue-cli-service inspect to show that the option is set correctly:
...
/* config.plugin('optimize-css') */
new OptimizeCssnanoPlugin(
{
sourceMap: false,
cssnanoOptions: {
safe: true,
autoprefixer: {
disable: true
},
mergeLonghand: false,
cssDeclarationSorter: false
}
}
),
...
Well, it is a bug in Vue CLI's default configuration, as we have set cssnanoOptions in the wrong way.
Current workaround:
// vue.config.js
module.exports = {
chainWebpack: config => {
config.when(process.env.NODE_ENV === "production", config => {
config.plugin("optimize-css").tap(args => {
args[0].cssnanoOptions = {
preset: ["default", {
autoprefixer: { disable: true },
mergeLonghand: false,
cssDeclarationSorter: false
}
]
};
return args;
});
});
}
};
Most helpful comment
Well, it is a bug in Vue CLI's default configuration, as we have set
cssnanoOptionsin the wrong way.Current workaround: