`:deep` selector doesn't work properly with SASS nested parent selector
Vue version
v3.2.38
Link to minimal reproduction
https://codesandbox.io/s/sad-alex-uj6q2u?file=/src/components/HelloWorld.vue
Steps to reproduce
- Write a computed property that returns an HTML element with a BEM-like class name
- Output this property into a v-html in your component
- Write the style for that class in SASS nested parent selector notation:
.element {
&__block {
color: #aa8855;
}
}
- In order to make it work as a deep dynamic v-html element, wrap the style in the
:deep
selector:
.element {
:deep(&__block) {
color: #aa8855;
}
}
- It does not work as expected
What is expected?
The style is applied correctly to the deep dynamic element
What is actually happening?
The style is not applied. This is because the :deep
selector takes precedence to the SASS compilation phase, so the final CSS output to the browser is like
.element[data-v-ff5e6236] &__block { ... }
instead of
.element__block { ... }
System Info
System:
OS: macOS 12.5.1
CPU: (8) arm64 Apple M1
Memory: 82.27 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.16.0 - ~/.nvm/versions/node/v16.16.0/bin/node
Yarn: 1.22.19 - ~/git_tree/experimentation-platform/client/node_modules/.bin/yarn
npm: 8.11.0 - ~/.nvm/versions/node/v16.16.0/bin/npm
Browsers:
Firefox: 103.0.2
Safari: 15.6.1
npmPackages:
vue: ^3.2.38 => 3.2.38
Any additional comments?
No response
Yes, this is a problem since third party components have callback functions that allow users to add custom CSS classes into their components but the problem is that the inserted classes lack scoping therefore they never get "selected" by the scoped CSS when using SCSS/SASS and the :deep
selector in a nested class. This used to work with the previous ::v-deep
selector.
I found a workaround but it involves using an additional class as an anchor for the :deep
selector.
Using the above example from @arrudaje:
.element {
&__block {
color: #aa8855;
}
}
You can add a dummy class (eg .parent
):
:deep(.parent) {
.element {
&__block {
color: #aa8855;
}
}
}
This will produce the following CSS output
.parent .element__block {
color: ##aa8855;
}
Obviously, the drawback of this approach is that it introduces the need for an additional class which increases the size of the CSS generated as well as increasing the specificity of the CSS rule.
To use these classes you also need to use a new parent element or use an existing parent element and add the .parent
class to it.