Vue-loader: Support /deep/ selector

Created on 20 Feb 2017  ·  18Comments  ·  Source: vuejs/vue-loader

feature request discussion

Most helpful comment

All 18 comments

looking forward to this feature !

👍

I've been encountering this issue. It would be great to have a solution, currently i just have to namespace everything, and not use scoped

currently scoped puts the scoping after the last element:

// output
<style>
  .parent .child[data-v-9922c9c] {
      color: blue
  }
</style>

It seems that a solution could be to use the :global modifier to move the scoping from the last element, further up the chain (to the root element of the child), but this seems to put the scoping in the incorrect place:

<style scoped>
  .parent {
     :global(.child) { color: blue }
  }
</style>

could become:

// output
<style>
  .parent[data-v-9922c9c] .child {
      color: blue
  }
</style>

unfortunately the current output is:

// output
<style>
  .parent [data-v-9922c9c].child { // notice the space after .parent
      color: blue
  }
</style>

@yyx990803
I really want to solve this..
the style of a component can be changed by each parent components.
But I have no way to modify scoped child component style from scoped parent component because the scope of parent component is not applied to child component deeply!
(but of course, we have !important keyword..)

for example..

<!-- Child component and style-->
<div class="my-child-component">
  <h1 class="my-child-component__title">I'm Child Component</h1>
</div>

<style scoped>
.my-child-component__title {
  color: red;
}
</style>



<!-- Parent component and style -->
<div class="my-parent-component">
  <my-child-component></my-child-component>
</div>

<style scoped>
.my-parent-component {
  & > .my-child-component__title {
    color: blue;
  }
}
</style>

output of parent component

<div class="my-parent-component" data-v-parenthash>
  <div class="my-child-component" data-v-parenthash data-v-childhash>
    <h1 class="my-child-component__title" data-v-childhash>I'm Child Component</h1>
    <!-- only child-hash applied, not parent-hash -->
  </div>
</div>


<!-- parent style output -->
.my-parent-component .my-child-component__title[data-v-parenthash] {
    color: blue; /* this is not applied cause title component has no parenthash attribute */
}

So my team don't use scoped attributes in all components.
Just name all class with a component prefix like my-child-component , my-parent-component in above example.

For single styles I've been using variables in css: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables, it works like a charm. For multiple styles you could use: https://tabatkins.github.io/specs/css-apply-rule/, the Polymer framework uses both and has polyfills for them (browsers are starting to support both features, but not all do so as of now.). Maybe Vue-loader could include said polyfills?

awesome!

2017年5月27日 18:48,"Evan You" notifications@github.com写道:

This is now implemented in 12.2.0: https://github.com/vuejs/vue-
loader/releases/tag/v12.2.0


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/vuejs/vue-loader/issues/661#issuecomment-304444477,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AEsQbU5w4U_yx_jOnE6qjB1uJoFylqNRks5r9_-EgaJpZM4MGQLS
.

It looks great. Does it work for lang="scss" too?

@lucasm-iRonin yeah, but you need to use /deep/ instead of >>> because SASS cannot parse the latter

Great, just encountered this issue then find this fix immediately.

.nav-badge >>> .nav-badge-style {
  width: 16px;
  height: 16px;
  font-size: 10px;
}

Compiled to =>

.nav-badge[data-v-2c25094c] .nav-badge-style {
    width: 16px;
    height: 16px;
    font-size: 10px;
}

Works like a charm to override muse-ui badge style. 😊

Scss parses>>> just fine =)

@jordyvandomselaar At least for me >>> does not work with SCSS. /deep/ is working fine though.

I'm using scss and neither >>> or /deep/ works for me

<style rel="stylesheet/scss" lang="scss" scoped> .main-paragraph /deep/ .test {color: red;} </style>
Compiled to =>
.main-paragraph /deep/ .test[data-v-3a3fa84f] { color: red; }

Can confirm that in SCSS, >>> does not work. Using /deep/ fixes this issue.

e.g. We can style a component with class name '.Another-Component' inside of our parent component with a class name of '.Filters'.

<style lang="scss" scoped>
.Filters {

  /deep/ .Another-Component {

    background-color: blue;

  }

}
</style>

Happy coding!

If you are using nested components (often) a "scoped" attribute is nothing. Look at following example:

parent-component.vue

<template>
    <div class="parent-component">
        <span class="label">My label</span>
        <child-component/>
    </div>
</template>

<style scoped>
    .parent-component >>> .label {
        color: red;
    }
</style>

child-component.vue

<template>
    <div class="child-component">
        <span class="label">My label from nested component</span>
    </div>
</template>

What you think about color property in .child-component .label, yes it will be red but do we want this?

What we can say about "scoped" attribute? Do u really use it? NO. You just adding fu*g prefix for all classes! This is dirty but we do it. So why vue-loader cant do it for us? Just add prefix for all classes if scoped attribute requested. Also we can define new directive (v-class as example) that will be used same as class attribute, but if defined a prefix will be added for class like this:

<template>
    <div v-class="parent-component">
        <span v-class="label">My label</span>
        <child-component/>
    </div>
</template>

output

<div class="parent-component_a9uipey1">
    <span class="label_a9uipey1">My label</span>
    <div class="child-component">
        <span class="label">My label from nested component</span>
    </div>
</div>

What you think? Thank you

Still wondering why we're not using the spec for this. (Css variables, mixins) would be much easier.

@yyx990803 Sorry for bothering you but In my case, it doesn't work as expected.

<style lang='scss' scoped>
.box-card {
  margin: 0;
  &.report-settings {
    .el-form {
      .el-form-item {
        /deep/ .el-form-item__label {
          line-height: 20px;
          padding: 0;
        }
      }
    }
  }
}
</style>

It rendered to

.box-card.report-settings .el-form .el-form-item /deep/ .el-form-item__label[data-v-edf5593e] {
    line-height: 20px;
    padding: 0;
}

What I expected is:

.box-card.report-settings .el-form .el-form-item[data-v-edf5593e] .el-form-item__label {
    line-height: 20px;
    padding: 0;
}

My HTML after rendering is:
scss_scoped_vue

@lucduong please open a separate issue with a reproduction.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

linde12 picture linde12  ·  3Comments

frangio picture frangio  ·  3Comments

NextSeason picture NextSeason  ·  3Comments

flashios09 picture flashios09  ·  3Comments

chrisvfritz picture chrisvfritz  ·  4Comments