24

I want to override the vuetify style by class.

For example to change the background color of button from vuetify.

So, I create a button with class on it:

<div id="app">
  <v-btn class="some" color="success">Success</v-btn>
</div>

.some {
background-color:red;
}

But the background-color red is override by vuetify.

How to solve this issue without using important and themes?

Here is example: https://stackblitz.com/edit/vue-js-gpkj6k

Weved
  • 813
  • 2
  • 9
  • 20
  • Actually see this about CSS specificity: https://stackoverflow.com/questions/51717264/styling-vuetify-selectors/51728504#51728504 I put a duplicate flag initially, but wrong question. In the former question it was only a part of the answer that led to the second question. So you can just target it with `#app .some` for example. Of course use what is best for you once you learn these concepts. – Traxo Sep 13 '18 at 09:39
  • 1
    Possible duplicate of [Styling Vuetify selectors](https://stackoverflow.com/questions/51717264/styling-vuetify-selectors) – CalvT Sep 13 '18 at 14:16

8 Answers8

28

With vue and scoped elements, you will meet the /deep/, >>>, ::v-deep selectors. Everything is explained there. So if you want to override a style deep, this means a style of a child of your root vuetify component you will need to use ::v-deep selector along with scoped attribute.

This gives you:

<style scoped>
.parent-element >>> .vuetify-class {
  // values
}
</style>

<style lang="scss" scoped>
  .vuetify-class {
    ::v-deep other-class {
      // your custom css properties
    }
  }
</style>

Hope, this helps.

gabrielstuff
  • 1,286
  • 1
  • 13
  • 16
25

Having worked with Vuetify and it's various styling... eccentricities... I believe it's all boiled down to writing css that has more specificity than Vuetify.

It's never great practise to style element's directly (img), instead apply your own classes.

This way you could declare .my-card.v-card and win the specificity war, all the while keeping styles scoped (non scoped can the the devil to debug in vue files).

Some Vuetify style declarations use !important... so the only way I've found to override these are to also use !important on the override. IMO terrible decision from Vuetify to have any !important styles.

It's also good to get your head around >>>, /deep/, ::v-deep as can provide a solution where styles are not filtering through.

Kick Buttowski
  • 6,709
  • 13
  • 37
  • 58
4uroraskye
  • 440
  • 4
  • 11
  • 7
    Just introducing Vuetify into my project broke all kinds of styling, even when I have my styles loading after it in the pipeline. Perhaps the single most frustrating one is the fact that `input`, `select`, and `button` ALL have no borders now. In a form-heavy app, adding classes to every one of these elements is time-consuming. Even adding it to ` – trpt4him May 31 '19 at 17:59
  • 2
    I also make a habit to have global override stylesheets, targeting vendor styling. So, _not_ in your component files, but within a separate stylesheet that you would import into `main.js`. That is... only if you want to override *all* vuetify input styling, for example. This way you avoid adding classes etc to the vuetify elements too. – 4uroraskye Jun 01 '19 at 18:09
  • 2
    Going through process of customizing vuetify components - ` win the specificity war` is a great way of describing it haha – Be Kind Jul 26 '19 at 10:41
  • 2
    @trpt4him, you can pump up the specificity of any SCSS rules by wrapping them in `body:not(#_){ ... code here }` (assuming your `` element doesn't have `id="_"`). Obviously, you don't need to use `body` *per se* but it's a good practice to limit the assertion of `:not()` to as few elements as possible. If you want, it's a custom `!important` which doesn't cross the line of not being overrideable by inline styles (so it doesn't break JS styling) and, as you can see, it doesn't need to know any ancestor `id` or `class`. – tao Apr 12 '20 at 14:12
  • 1
    Plus 1 just for the "... eccentricities ...". Made my day since it is so true – Alex Sorokoletov Jul 08 '20 at 01:19
  • 1
    @AlexSorokoletov hahaha it's painfully true.. like... Why?! There's a whole load of ways to override styles without resorting to `!important` – 4uroraskye Aug 13 '20 at 13:57
  • 1
    That decision was made by vuetify team. They use !important and calc a lot :) – Alex Sorokoletov Aug 13 '20 at 14:59
  • @tao Thanks for the tip. I'm struggling because I'm primarily a Python guy and having to `body:not()` things is violating multiple points of our Zen. :) – trpt4him Aug 21 '20 at 12:28
  • I totally get it, but it's superior to `!important`. You only need to follow a simple rule: use only one element for `:not()` assertion (not all parents). It allows you to increase specificity of your rules without having to specify ancestor classes or ids. So `html:not(#_):not(#_) input` will override powerful selectors like: `#app input.form-control` or `#navbar input.search`, because it has specificity of `2×id + 1×element` vs `1×id + 1×class + 1×element`. The other option is to copy currently applying selectors and override them one by one with same specificity. Insane... ish. – tao Aug 21 '20 at 12:52
  • @trpt4him do you have a solution to the no border problem. I can't even get borders using my own classes. heeelp!!!!! :( – matt Nov 13 '20 at 18:00
  • @4uroraskye any chance you could give an example of a separate style sheet and how you import it ? – matt Nov 13 '20 at 18:07
5

Try not scoping your styles for example:

<body>
<img :src="userImg" alt="avatar">
</body>

This won't work

<style scoped>
.img {
  width: 120px;
  height: 120px;
  margin: 0 auto;
  border-radius: 50% !important;
  overflow: hidden;
}
.img img {
  width: 100%;
}
</style>

And this will work

<style>
    .img {
      width: 120px;
      height: 120px;
      margin: 0 auto;
      border-radius: 50% !important;
      overflow: hidden;
    }
    .img img {
      width: 100%;
    }
    </style>
Juan C. Feris
  • 67
  • 1
  • 6
  • 6
    This is fine, if you don't mind that your styles may bleed into other places. I find it best when working with Vue, to always scope styles - there is usually another way round styling elements without resorting to unscoping styles. – 4uroraskye Aug 02 '19 at 11:13
3

One workaround I have found is targeting the elements specifically in the custom CSS by giving the containing element an ID like below

<v-btn-toggle
 id="btnGroup"
 borderless
 dense
 group
 class="d-flex flex-column"
>
  <v-btn active-class="dnrSelected">
    <v-icon right class="mr-2">mdi-close</v-icon>
    <span>Do Not Recommend</span>
  </v-btn>
  <v-btn active-class="rSelected">
    <v-icon right class="mr-1">mdi-check</v-icon>
    <span>Recommend</span>
  </v-btn>
  <v-btn active-class="srSelected">
    <v-icon right class="mr-1">mdi-check-all</v-icon>
    <span>Strongly Recommend</span>
  </v-btn>
</v-btn-toggle>

And then using this id to specify target elements like below

#btnGroup .dnrSelected {
  background-color: #ef9a9a !important;
}
#recommendationBtnGroup .rSelected {
  background-color: #dcedc8 !important;
}
#recommendationBtnGroup .srSelected {
  background-color: #81c784 !important;
}
Meena Chaudhary
  • 9,909
  • 16
  • 60
  • 94
1

with Vuetify 3 you'll see a warning ::v-deep usage as a combinator has been deprecated. Use ::v-deep(<inner-selector>) instead for ::v-deep usage. The other methods didn't give my any single warning and didn't work.

The way to change the styling is, depending if you need to overwrite styling (add !important;), or simply append a new one (no need for !important;), is, with an example:

:deep() {
  .v-field__outline__end {
    border-radius: 25px!important;
    color: red;
  }
}
Daniel Danielecki
  • 8,508
  • 6
  • 68
  • 94
0

Not sure if this is/will be an issue you're having, but I was stuck on it for a long time.

If you use scoped styling (which you should), you'll have to use the deep selector >>> to target classes of child components. I could never get the deep selector to work with SASS though, so you'll have to either forgo using SASS or use both.

<style scoped>
.parent-element >>> .vuetify-class {
  // values
}
</style>

<style lang="scss" scoped>
  // SASS styling
</style>

You can read about the deep selector here: https://vue-loader.vuejs.org/guide/scoped-css.html#mixing-local-and-global-styles

Josh
  • 714
  • 2
  • 8
  • 20
0

For me, the easiest way was to add my custom-reset.css file where I have put my fixes. For example if you load vuetify css like this:

import 'vuetify/dist/vuetify.min.css'

You can import your custom-reset.css file after that line, as a result you imports will look line this:

import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import '<your_path>/custom-reset.css'
import '@mdi/font/css/materialdesignicons.css'

I had problems, vuetify styles broke AdminLte 2 styling. In my case, custom-reset.css file can look like this:

.row {
    display: block;
    margin-right: -15px;
    margin-left: -15px;
}

.row > .col, .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, 
.col-7, .col-8, .col-9, .col-10, .col-11, .col-12, 
.col-auto, .col-lg, .col-lg-1, .col-lg-2, .col-lg-3, 
.col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, 
.col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-auto, 
.col-md, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, 
.col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, 
.col-md-12, .col-md-auto, .col-sm, .col-sm-1, .col-sm-2, .col-sm-3, 
.col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, 
.col-sm-10, .col-sm-11, .col-sm-12, .col-sm-auto, .col-xl, .col-xl-1, 
.col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, 
.col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-auto {
    padding: 0px 0px 0px 0px;
    padding-right: 15px;
    padding-left: 15px;
}

select {
    -webkit-appearance: menulist; /* -webkit-appearance: none;  */
}
.v-application--wrap {
    min-height: auto;
}

Hope it will help someone!

0

htl div

In Vue 3 And Vuetify 3:

<div class="v-responsive v-img" style="width: 85vw;">
div:deep(.v-img) {
  overflow: visible;
}
Caro Pérez
  • 476
  • 4
  • 4