How to override scoped styles in Vue components?

47.8k Views Asked by At

Let's save I have a .Vue component that I grab off of Github somewhere. Let's call it CompB and we'll add a single CSS rule-set there for a blue header:

CompB.Vue (a dependency I don't own, perhaps pulled from Github)

<template>
  ...
</template>

<script>
  ...
</script>

<style lang="scss" scoped>
  .compb-header {
    color: blue;
  }
</style>

I plan to nest CompB into my own project's CompA. Now what are my options for overriding the scoped rule?

2

There are 2 best solutions below

0
On BEST ANSWER

After playing around a bit, I think I've got a good approach.

  1. Global overrides

    For situations where I want to override the rules in all cases for CompB I can add a rule-set with more specificity like this: #app .compb-header { .. }. Since we always only have one root (#app) it's safe to use an ID in the rule-set. This easily overrides the scoped rules in CompB.

  2. Parent overrides

    For situations where I want to override both the global and scoped rules. Thankfully VueJS allows adding both a scoped and unscoped style block into a .Vue file. So I can add an even more specific CSS rule-set. Also notice I can pass a class into CompB's props since Vue provides built-in class and style props for all components:

    // in CompA (the parent)
    
    <template>
      ...
      <!-- Vue provides built-in class and style props for all comps -->
      <compb class="compb"></compb>  
    </template>
    
    <script>
      ...
    </script>
    
    <style lang="scss">
      #app .compb .compb-header { 
        color: red; 
      }
    </style>
    
    <style lang="scss" scoped>
      ...
    </style>
    

    (note: You can get more specific and make the class you pass into CompB have a more unique name such as .compa-compb or some hash suffix so there is no potential for collision with other components that use CompB and a class .compb. But I think that might be overkill for most applications.)

  3. And of course CompB may provide its own additional props for adjusting CSS or passing classes/styles into areas of the component. But this may not always be the case when you use a component you don't own (unless you fork it). Plus, even with this provided, there is always those situations where you are like "I just want to adjust that padding just a bit!". The above two solutions seem to work great for this.

6
On

You will need to add more specificity weight to your css. You have to wrap that component in another class so you can override it. Here is the complete code

<template>
  <div class="wrapper">
    <comp-b>...</comp-b>
  </div>
</template>

<script>
import CompB from 'xxx/CompB'

export default {
  components: {
    CompB
  }
}
</script>

<style>
  .wrapper .compb-header {
    color: red;
  }
</style>