Vuetify Styling Data-Table (next)

Hi,

this is probably the 100th question in that regard, so please forgive me.

I am trying to style my tds with a scoped style like this here

<style scoped>
.v-data-table > .v-data-table__wrapper > table > tbody > tr > td,
.v-data-table > .v-data-table__wrapper > table > tfoot > tr > td,
.v-data-table > .v-data-table__wrapper > table > thead > tr > td {
    font-size: 33px;
}
</style>

for a structure like the below

the definition for the data-table is below

        <v-data-table
            dense
            :headers="headers"
            :items="items"
            :items-per-page="15"
            class="elevation-1"
            loading-text="Loading"
        >

I a bit lost. as after loading the page I also can not find any reference to the value 33. I chose that the check if the style is loaded at all. But I can not find that when using the inspector in the web dev tools in my browser (Firefox)

Any help is greatly appreciated

I tinkered around and found the following

If I change my style to use the >>> (deep) selector then my style gets created and loaded into the browser (found at https://stackoverflow.com/questions/41321592/scoped-css-not-being-applied-within-the-component)

<style scoped>
.v-data-table >>> td {
    font-size: 0.8rem;
    background-color: red;
}
</style>

BUT

my style gets overwritten by another style later on as seen below

Also that style that overwrites mine is included 2x as seems


And the first that is included is also overwritten.

I am clueless to why this happens. I restarted my dev server just to make sure that those styles dont somehow accumulate

OK, I found a workaround. I wouldnt call it a solution as it feels like a bug - but I might be wrong on this and there is good reason for the behavior observed

So if I define my scoped style like this

<style scoped>
.item-size >>> td {
    font-size: 0.8rem !important;
}
</style>

that is I need to use the >>> (deep) selector and I have to define !important.

The first action ensures that my style is loaded at all. The second that it is not overwritten by another style.

Like I said doesnt feel right thou.

Why the same style is being loaded twice I don’t know but it doesn’t seem to be directly related to your problem.

When it comes to applying styles, browsers apply the standard rules for selector specificity. They don’t know anything about Vue and don’t care where the styles came from.

Your selector gets compiled down to:

.v-data-table[data-v-6c726ee9] td {
  /* ... */
}

That selector has one class, one attribute and one element.

The built-in styles use:

.v-data-table > .v-data-table__wrapper > table > tbody > tr > td {
  /* ... */
}

The > are irrelevant from a specificity perspective. The selector has 2 classes and 4 elements. That’s much more specific than the previous selector so it takes precedence.

I believe the reason Vuetify uses such a bizarre selector is to allow tables to be nested. By using all those > it ensures that only the immediate children are styled and not deeper descendants within a nested table. However, for that to work it has to go through all the levels to get to the td, so it ends up with a selector with very high specificity.

If you don’t want to use !important then you’re going to need to bump up your selector’s specificity. You could try to emulate the selector that Vuetify uses. Or, if that feels like a lot of effort, you can just repeat the class:

.v-data-table.v-data-table.v-data-table >>> td {
  /* ... */
}

3 classes should be enough to overpower the Vuetify selector.

1 Like

Thanks for the explanation about the specificity. Makes much more sense now.