How do I use /deep/ or >>> or ::v-deep in Vue.js?
Asked Answered
P

8

189

So, I've read here that in Vue.js, you can use /deep/ or >>> in a selector in order to create style rules that apply to elements inside of child components. However, attempting to use this in my styles, whether in SCSS or in plain old CSS, doesn't work. Instead, they are sent to the browser verbatim, and therefore have no effect. For example:

home.vue:

<style lang="css" scoped>
.autocomplete >>> .autocomplete-input 
{
// ...
}
</style>

generated css:

<style type="text/css">
.autocomplete >>> .autocomplete-input[data-v-2bda0c9a]
{
//...
}
</style>

what I want:

<style type="text/css">
.autocomplete[data-v-2bda0c9a] .autocomplete-input
{
//...
}
</style>

My webpack configuration pertaining to vue-loader looks like this:

// ...
{
    test: /\.vue$/,
    loader: "vue-loader",
    options: {
        loaders: {
            scss: "vue-style-loader!css-loader!sass-loader"
        }
    }
}
// ...

So my question is, how do I get this >>> operator to work?

I've already found this answer, but I'm doing exactly that and it doesn't work...

Pilch answered 30/12, 2017 at 7:41 Comment(4)
@connexo The Vue Loader itself supports a scoped modifier for CSS that is not related to the defunct native-to-CSS scoped modifier.Harlot
@connexo @RoyJ removing the scoped attribute and the >>> operator does indeed make the style rule work, but it's less than optimal. As Roy J pointed out, this scoped attribute has nothing to do with the W3C.Pilch
Did you get this working? With <style scoped>, >>> should work (.autocomplete >>> .autocomplete-input) and with <style lang="scss" scoped>, /deep/ should work (.autocomplete /deep/ .autocomplete-input) (tested with nuxt 1.4 / vue 2.5)Sternson
deep-selectors this should usefulOrator
I
443

Vue 2.0 - 2.6

The following also works in Vue 3 but is deprecated.

Sass:   Use ::v-deep

::v-deep .child-class {
    background-color: #000;
}

Not using Sass:   Use >>>

>>> .child-class {
    background-color: #000;
}

With either syntax, the <style> tag for this component must be scoped:

<style scoped>

Vue 3 (and Vue 2.7)

In Vue 3, the ::v- prefix is now deprecated and we no longer need >>>. We can use the unified :deep selector whether using Sass or not, but now it's recommended to use parentheses with the selector.

Use :deep(.child-class)

:deep(.child-class) {
    background-color: #000;
}

This also works in Vue 2.7 (final Vue 2 release)


Vue 3 new selectors

Additionally, in Vue 3, there is a new feature for components with a <slot> that enables styling passed slot content.

Slot content   Use :slotted(.child-class)

:slotted(.slot-class) {
    background-color: #000;
}

And lastly, in Vue 3, there is a new feature to register global styles even from a scoped component:

Global styles   Use :global(.my-class)

:global(.my-class) {
    background-color: #000;
}

With any syntax, the <style> tag for this component must be scoped:

<style scoped>

Summary

In Vue 2:

  • The /deep/ syntax is deprecated
  • Use ::v-deep with Sass, use >>> without Sass

In Vue 3:

  • ::v-deep .child-class is deprecated in favor of :deep(.child-class)
  • The ::v- prefix is deprecated in favor of :
  • The >>> syntax is deprecated
  • The /deep/ syntax is deprecated
  • There are new :slotted and :global selectors

With every version/syntax, the <style> tag for this component must be scoped:

<style scoped>
Intended answered 27/3, 2019 at 2:34 Comment(2)
Confirming :deep() syntax works in Vue 2.7Boak
@Dan. Thanks. How to write ::v-deep .custom-control-input.is-valid~.custom-control-label { color: black; } with :deep(). it is complaining ~ characterColossus
P
31

Avoid using /deep/ and instead use ::v-deep

Any scoped component's css can be changed by using deep selector but sooner /deep/ will get deprecated

Vue Github reference - https://github.com/vuejs/vue-loader/issues/913

Use ::v-deep in this case,and avoid deprecated /deep/

Reference - Deep Selector

Just inspect class of the rendered element which you want to modify using devtools in chrome or any browser console.

Then, In you consuming component, modify it

<style scoped>
::v-deep .custom-component-class {
   background: red; //
}
</style>
Pulsatory answered 21/6, 2019 at 7:4 Comment(1)
I have also just discovered that /deep/ breaks the build using Babel 7, so in Sass ::v-deep becomes the only optionLowry
S
26

I've successfully used /deep/ in Vue's scoped SCSS stylesheets with this structure:

.parent-class {
  & /deep/ .child-class {
    background-color: #000;
  }
}

Edit: /deep/ is being deprecated, if it no longer works for you please refer to the other answer that explains ::v-deep

Sulfate answered 18/9, 2018 at 3:43 Comment(1)
Please check the other answers "/deep/" is being deprecated!Demasculinize
M
8

::v-deep usage as a combinator has been deprecated. Use :deep() instead.

:deep(.child-class) {
    background-color: #000;
}
Metatarsal answered 17/1, 2022 at 14:28 Comment(3)
How to use it with multiple classes ?Superiority
You put :deep() around every comma-separated selector. What used to be ".button1, .button2", now becomes ":deep(.button1), :deep(.button2)".Jugate
Multiple :deep for 2+ selectors suck. I have wysiwyg editor and want to style p, h1, h2, h3, etc.Braces
S
3

For me, the only thing that worked was

<style scoped>.  // sass and scss didn't work
  >>> .deep-selector {
    ...
  }
</style>
Samford answered 22/3, 2020 at 16:54 Comment(1)
I agree: this is a nice and short answer that works in all use-cases. It's also the only one currently mentioned in the vue-loader docs.Wrac
M
3

Though it is not found in the Documentation, the answer is that the component you are attempting to reach cannot be the root component. Wrap your single component in a <div> and it should work using ::v-deep on scoped scss as others have explained.

Maculate answered 29/7, 2020 at 18:43 Comment(1)
I had this issue. :deep did not work for me until wrapping the whole thing in a <div>. The root component in this case was the one that also had the first div class on it in the component. For others, to verify this, try targeting the :deep on a second level down component. If that works either do that, or add a div in the parent where you set the :deep css.Malherbe
I
0

I solved this problem by adding

options: { styleIsolation: 'shared' }, // add this
methods: {
  yourFunc1 () {
  }
}
.pet-info{
  ::v-deep .title {
    width: 51px !important;
    background-color: red !important
  }
}

Config this in the components like the methods, it's the same level like methods.

Incongruent answered 15/7, 2021 at 3:30 Comment(1)
It's work for the uniapp / mpvue (WeChat mini-program) project. This config doesn't exist in vueJsDeprecate
M
0

To override the CSS properties of a specific element in Vue.js use Vuetify, below workded for me:

<style scoped>
::v-deep .v-overlay__content {
    contain: none !important;
}
</style>

OR

<style scoped>
>>> .v-overlay__content {
    contain: none !important;
}
</style>
Meuse answered 28/2 at 6:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.