Skip to content

Support /deep/ selector #661

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
yyx990803 opened this issue Feb 20, 2017 · 18 comments
Closed

Support /deep/ selector #661

yyx990803 opened this issue Feb 20, 2017 · 18 comments

Comments

@yyx990803
Copy link
Member

moved from vuejs/vue#4298

@indooorsman
Copy link

looking forward to this feature !

@jsikorski
Copy link

👍

@tonypee
Copy link

tonypee commented Apr 19, 2017

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>

@jsnick
Copy link

jsnick commented May 22, 2017

@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.

@jordyvandomselaar
Copy link

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?

@yyx990803
Copy link
Member Author

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

@indooorsman
Copy link

indooorsman commented May 27, 2017 via email

@lucasm-iRonin
Copy link

lucasm-iRonin commented Jun 9, 2017

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

@yyx990803
Copy link
Member Author

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

@librae8226
Copy link

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. 😊

@jordyvandomselaar
Copy link

Scss parses>>> just fine =)

@MikaelEdebro
Copy link

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

@yangdm2015
Copy link

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; }

@michaelpumo
Copy link

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!

@mikeevstropov
Copy link

mikeevstropov commented Aug 9, 2017

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

@jordyvandomselaar
Copy link

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

@lucwj
Copy link

lucwj commented Nov 9, 2017

@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

@yyx990803
Copy link
Member Author

@lucduong please open a separate issue with a reproduction.

@vuejs vuejs locked and limited conversation to collaborators Nov 9, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests