I am trying to upgrade my Vue
stack to support vite
because it generates a much faster codebase for use on the web. I have done this in several projects, but not on any that use sass
. Since vite
uses sass
instead of node-sass
, I have to migrate all my sass code as well. I am using a sass-heavy 3rd-party element toolkit and it is throwing the following error:
[plugin:vite:css] [sass] Top-level selectors may not contain the parent selector "&".
╷
71 │ &.el-select-dropdown.is-multiple
│ ^
╵
the block says:
@mixin select($type, $color) {
.select-#{$type}.el-select .el-input {
.el-input__suffix{
display: flex;
align-items: center;
}
}
/* more code goes here */
&.el-select-dropdown.is-multiple
.el-select-dropdown__item.selected{
&.select-#{$type}{
color: $color;
}
}
}
@include select('default', $default-color);
@include select('info', $info-color);
How would I refactor this to be compatible with the sass standard? Or, why/how is this working with node-sass?
Let's have a look at the mixin:
@mixin select($type, $color) {
.select-#{$type}.el-select .el-input {
.el-input__suffix{
display: flex;
align-items: center;
}
}
/* more code goes here */
&.el-select-dropdown.is-multiple
.el-select-dropdown__item.selected{
&.select-#{$type}{
color: $color;
}
}
}
It's made of two blocks
.select-#{$type}.el-select .el-input {
.el-input__suffix{
display: flex;
align-items: center;
}
}
This one is easy, when you do @include select('default', $default-color);
it will simply define the selector as: .select-default.el-select .el-input
:
.select-default.el-select .el-input {
.el-input__suffix{
display: flex;
align-items: center;
}
}
It will compile to:
.select-default.el-select .el-input .el-input__suffix {
display: flex;
align-items: center;
}
&.el-select-dropdown.is-multiple
.el-select-dropdown__item.selected{
&.select-#{$type}{
color: $color;
}
}
It's using the &
, this is the parent selector in sass:
The parent selector, &, is a special selector invented by Sass that’s used in nested selectors to refer to the outer selector. It makes it possible to re-use the outer selector in more complex ways, like adding a pseudo-class or adding a selector before the parent. Parent Selector - Sass lang
It will be replaced by the parent selector, if you are trying to use the mixin at the root level, you don't have a parent selector, that's why it's failing.
If you use it within a selector (parent selector):
.foobar {
@include select('default', $default-color);
}
The &
will be replaced by .foobar
.
.foobar.el-select-dropdown.is-multiple
.el-select-dropdown__item.selected{
&.select-default{
color: $default-color;
}
}
The mixin is perfectly fine, you just need to use it inside a parent selector.