101

I have the following form component:

<template>
    <div>
        <form>
            <input placeholder="Recipe Name">
            <textarea placeholder="Recipe Description..." rows="10"></textarea>
        </form>
    </div>
</template>

<script>
export default {
    name: 'AddRecipeForm'
}
</script>

<style scoped>
form {
    display: flex;
    flex-direction: column;
}
</style>

The <style> uses the scoped attribute.

When applied, the CSS does not get loaded in. When scoped is removed, it does get applied.

However I want to keep it local to the component.

Why is the CSS not getting applied when the scoped attribute is present?

alanbuchanan
  • 3,993
  • 7
  • 41
  • 64

4 Answers4

108

It appears this was solved by doing a full-reload of the page. Hot reload should take care of scoped css.

However for future viewers, This is commonly asked when scoped CSS isnt being applied to a child component. This can be solved by using deep selectors. (e.g: Using a .selector >>> .desired-selector {})

EDIT: Since this is still getting activity, I'll bring my comment into the answer. ::v-deep also works depending on what preprocessor you're using.


Vue 3 Edit

Now that Vue 3 is stable and been in full release for a while, see the Vue 3 docs for deep selectors: https://vuejs.org/api/sfc-css-features.html#scoped-css

Namely, this syntax is now: :deep(.some-class). There are also some new features which can be read in the linked docs above.

Brandon Deo
  • 4,195
  • 4
  • 25
  • 42
  • 1
    Thanks, this fixed it for me as well. I couldn't get any css I was writing to hit the DOM until using the >>> Deep selector, now it all works! – ADP Feb 20 '18 at 20:05
  • 9
    Use `/deep/` (including slashes) when using SCSS instead of plain CSS, because the SCSS parser doesn't handle `>>>`. – Pistos Jun 18 '19 at 22:07
  • 3
    @RameshPareek try ::v-deep as well. It depends on your CSS loader – Brandon Deo Aug 05 '19 at 15:14
  • it worked. Please delete your comment. so as not to confuse future visitors. – Ramesh Pareek Aug 07 '19 at 04:12
84

For some reason, scoped styles don't get applied during hot reload when they are first added to the component. Full page reload fixes the issue, from there the styles, since they have been detected, get updated with consecutive hot reloads.

Adam Jagosz
  • 1,484
  • 14
  • 13
2

Precisely same symptoms as the OP but none of the recommendations here so far have worked and I need to move on so our solution is to rely on CSS selectors normally:

  • add a uniquely-named class to the top-level element below <template>
  • prefix all scoped (non-global) selectors with that uniquely-named class

which had the unexpected but welcome upside when live-debugging our CSS is that the origin of the CSS rule is now obvious in devtools.

MyComponent.vue

<template>
    <v-card class="MyComponent" ... >
        <div class="fancyBox" ... >
         /* ... */
    </v-card>
</template>

<style>
    .MyComponent .fancyBox { /* scoped to any MyComponent instance */ }
    .globalBox { /* we wouldn't put a global style here, obv */ }
</style>

Yes, it's a pain to prefix component-scoped styles this way, but, at least it's a familiar thing to do and you get the added benefit in devtools of tracing the source of a style back to the component that declared it.

Caveat is that, of course, parent-scoped CSS will also bleed down to child-scopes. This, at least, is familiar CSS behaviour.

storsoc
  • 309
  • 1
  • 7
0

Rebuilding the Vue App by running 'yarn serve' has fixed the problem for me.

Akash Kumar Seth
  • 1,651
  • 1
  • 18
  • 22