3

I need to modify some CSS properties of a Vue component, from its parent. It would override the CSS defined within the component.

I first expected that for a component <my-component>, I could directly style it from the parent, like any other element:

my-component {
    font-weight: bolder;
}

This does not work.

The second solution I tried is to pass a prop to the component, with the relevant information to be used in the styling. This works but I am still hoping for a solution closer to an inheritance mechanism (where the settings of the parent would have priority on the ones of the child, similarly to, say, styling a <b> element).

Is there such a mechanism?

WoJ
  • 27,165
  • 48
  • 180
  • 345
  • 1
    Add a class to the root element of the child component (like `class="my-component"`) then you could add styles from the parent scope using that class `.my-component`. – thanksd Nov 08 '17 at 19:10
  • @thanksd: I just tested your solution and it works perfectly, thank you!. Could you please turn that into an answer? Out of curiosity, would you know why the solution 1 in my question does not work (styling the component name) - since styling via its class is OK? – WoJ Nov 09 '17 at 07:20

2 Answers2

4

When Vue renders the template of a component, custom component tags get replaced with their template definitions. So, trying to select the custom component's tag in CSS won't work because that tag is not in the DOM.

Simply add a class attribute to the root element of the child component (since this is what gets inserted into the DOM in place of the custom component tag). For sanity's sake, I just make the class name the same name as the component. Then you can select the component anywhere in your CSS via .my-component.

Here's a simple example:

Vue.component('my-component', {
  template: `<div class="my-component">Foo</div>`,
})

new Vue({ el: '#app' })
.my-component { color: goldenrod; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
  <my-component/>
</div>
thanksd
  • 54,176
  • 22
  • 157
  • 150
3

For inspiration:

var comp = {
  template: '<p><slot></slot></p>'
}

new Vue({
  el: '#app',
  data: {
    inParent: true
  },
  components: {
    comp
  },
  methods: {
    change () {
      this.inParent = !this.inParent
    }
  }
})
.blue {
  background-color: blue
}
<div id="app">
  This button is in parent:
  <button @click="change">change child style</button>
  <comp :class="{blue: inParent}">This is child component</comp>
</div>

<script src="https://unpkg.com/vue"></script>