1

Consider a Child component with scoped styles, which internally uses foo class name:

<!-- Child -->

<template>
  <div class="foo">
    This is a child
  </div>
</template>

<style scoped>
.foo {
  color: blue;
}
</style>

and another Parent component with scoped styles, which internally uses foo class name as well, and also provides a slot:

<!-- Parent -->

<template>
  <div class="foo">
    <div>This is a parent</div>
    <slot></slot>
  </div>
</template>

<style scoped>
.foo {
  color: red;
  margin-bottom: 10px;
}
</style>

Nest Child component into Parent component as a slot:

<!-- App -->

<template>
  <div>
    <Parent>
      <Child />
    </Parent>
  </div>
</template>

<script>
import Parent from "./components/Parent";
import Child from "./components/Child";

export default {
  components: {
    Parent,
    Child
  }
};
</script>

Actual result

styles of the foo class from the Parent are also applied to an element with a foo class in the Child. Here is a screenshot of the actual DOM:

DOM snapshot

Expected result

I would expect that styles for a Child will be isolated from any parent. I wonder if it is by design or can be fixed without renaming the classes, because it will break the whole idea of isolation.


Here is a CodeSandbox to play around with the sources.

Michael Radionov
  • 12,859
  • 1
  • 55
  • 72
  • Wouldn't it be illogical to prevent parent styles from applying to a child element? – sliptype Mar 23 '18 at 21:49
  • @sklingler93 It is logical in terms of regular CSS where cascading is a core of applying the styles, but it terms of components I believe that child components should be unaffected and in no way influenced by the context they are used in, unless it is explicitly specified. – Michael Radionov Mar 23 '18 at 22:07

1 Answers1

1

This is a known behavior and how it is supposed to be. When you have a child with the same class from a parent, the child's class will overwrite the parent one. (which is what is happening in your example and the div at child is blue).

It is not completed isolated and would not make sense to be. Sometimes will be needed a parent component to overwrite the child component style, and that is why.

So, for example if you use the tag !important the parent component will overwrite the child component and this is a wanted behavior.

When having more complicated cases (like grand-parents or grand-grand parents) it is possible to use the deep scoped style which is discussed here: https://github.com/vuejs/vue/issues/4298

Then moved to vue-loader here: https://github.com/vuejs/vue-loader/issues/661

And it was implemented on the tag v12.2.0 of the vue-loader.

And after that, doing

.foo >>> .bar { color: red; }

we will have

.foo[data-v-xxxxxxx] .bar { color: red; }
Victor Oliveira
  • 1,109
  • 1
  • 12
  • 29
  • 1
    But in my case parent does not even try to target any child, it just happened that they both have the same class names. Why is the class applied to a child in the first place? Is it how `scoped` supposed to work? Is there any way to avoid it? – Michael Radionov Mar 24 '18 at 09:18
  • Well, I've found the answer - it is by design. That same question has already been asked on SO (https://stackoverflow.com/questions/45898865/how-to-correctly-use-scoped-styles-in-vuejs-single-file-components), so I'll close mine as a dup. Thanks for you help. – Michael Radionov Mar 24 '18 at 09:25