Vue.js CSS Styles Scoped vs Module

November 29, 2019

Scoped

<template>
  <div>
    <h1>Title <small>(small)</small></h1>
    <div>
      <div class="test">Test</div>
    </div>
    <p>Content 1</p>
    <p>Content 2</p>
  </div>
</template>

<styles lang="scss" scoped>
h1 {
  font-weight: bold;
}

.test {
  color: red;
}
</styles>

Generated CSS

h1[data-v-5b2d5ecc] {
  font-weight: bold;
}
.test[data-v-5b2d5ecc] {
  color: red;
}

Generated HTML

  • data-v-<HASH> is added to every HTML element (thus increase the size, to be noted if you are using server-side render).
  • the styles shall not propogate down to nested component
<div data-v-5b2d5ecc="">
    <h1 data-v-5b2d5ecc="">Title <small data-v-5b2d5ecc="">(small)</small></h1>
    <div data-v-5b2d5ecc="">
        <div data-v-5b2d5ecc="" class="test">Test</div>
    </div>
    <p data-v-5b2d5ecc="">Content 1</p>
    <p data-v-5b2d5ecc="">Content 2</p>
</div>

Module

<template>
  <div>
    <h1 :class="$style.h1">Title <small>(small)</small></h1>
    <div>
      <div :class="$style.test">Test</div>
    </div>
    <p>Content 1</p>
    <p>Content 2</p>
  </div>
</template>

<style lang="scss" module>
.h1 {
  font-weight: bold;
}

.test {
  color: red;
}
</style>

Generated CSS

.Test_h1_3IRd0 {
  font-weight: bold;
}
.Test_test_3ySCa {
  color: red;
}

Generated HTML

  • Guaranteed unique class name
<div>
    <h1 class="Test_h1_3IRd0">Title <small>(small)</small></h1>
    <div>
        <div class="Test_test_3ySCa">Test</div>
    </div>
    <p>Content 1</p>
    <p>Content 2</p>
</div>

What doesn’t work

I try to use module like scoped, but it wouldn’t work for nested class test as :class="$style.test" is required to make it work.

<template>
  <div :class="$style.module">
    <h1>Title <small>(small)</small></h1>
    <div>
      <div class="test">Test</div>
    </div>
    <p>Content 1</p>
    <p>Content 2</p>
  </div>
</template>

<style lang="scss" module>
.module {
  h1 {
    font-weight: bold;
  }

  .test {
    color: red;
  }
}
</style>

Generated CSS

.Test_module_2RonD h1 {
  font-weight: bold;
}
.Test_module_2RonD .Test_test_3ySCa {
  color: red;
}

Generated HTML

<div>
    <h1 class="Test_h1_3IRd0">Title <small>(small)</small></h1>
    <div>
        <div class="test">Test</div>
    </div>
    <p>Content 1</p>
    <p>Content 2</p>
</div>

Standard Nested CSS

<template>
  <div class="nested">
    <h1>Title <small>(small)</small></h1>
    <div>
      <div class="test">Test</div>
    </div>
    <p>Content 1</p>
    <p>Content 2</p>
  </div>
</template>

<style lang="scss">
.nested {
  h1 {
    font-weight: bold;
  }

  .test {
    color: red;
  }
}
</style>

Generated CSS

.nested h1 {
  font-weight: bold;
}
.nested .test {
  color: red;
}

Generated HTML

  • CSS will propagate to nested component
<div class="nested">
    <h1>Title <small>(small)</small></h1>
    <div>
        <div class="test">Test</div>
    </div>
    <p>Content 1</p>
    <p>Content 2</p>
</div>
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.