• 15 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 4/13/21

Manage Styles in Your App

Log in or subscribe for free to enjoy all this course has to offer!

Configuring a Preprocessor

One of the many things that make Vue easy to work with is that it follows a philosophy of progressive enhancement. In other words, it doesn't force you to opt into things that you're not ready to use. On the other hand, when you are ready to use something, configuring it is simple. This is particularly useful when styling your app. Or in other words, how to manage CSS in your app.

When writing CSS, most front-end codebases these days use a preprocessor (SASS, LESS, etc.). In case you're not familiar with preprocessors, they help to extend CSS functionality like operators, functions, mixins, and many other things. And to utilize preprocessors, the styles are typically written in a specific file format:

  • SASS ⇒ *.sass or *.scss

  • LESS ⇒ *.less

There is an even easier way to utilize the power of preprocessors while also keeping them coupled with your component. All you need is the lang prop!

Assuming you've configured your Vue CLI app with the right preprocessor, then it's a matter of giving the lang prop to the  style  block with the desired preprocessor.

<template>
...
</template>
<script>
...
</script>
<style lang="scss">
.button {
&.is-small { ... }
&.is-large { ... }
}
</style>

And with that, you have the power of preprocessors at your fingertips!

Managing CSS

To understand how to mange your CSS, you must understand how the  style  block is compiled in production.

Global Styling - Default

When the  style  block is used with no additional configuration, the styles are applied globally whenever the component is rendered on the screen.

So if our component looks like:

<template>
<main>
<h1>Hello</h1>
<button>Click me!</button>
</main>
</template>
<script>
export default {
name: 'HomePage'
}
</script>
<style>
button {
background-color: blue;
}
</style>

The resulting HTML would look similar to:

<html>
<head>
<style>
button {
background-color: blue;
}
</style>
</head>
<body>
<main>
<h1>Hello</h1>
<button>Click me!</button>
</main>
</body>
</html>

Scoped Styles

One of the techniques that has recently become popular is scoped styles, which allows you to provide a  scoped  attribute to the  style  block so the CSS will only apply to elements of the current component. As far as how it attempts to do this, it appends a custom data attribute to the CSS class and HTML element to keep the styles scoped. By doing so, this minimizes any cascading effects by having a smaller scope.

Before
<style scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">hi</div>
</template>
After
<style>
.example[data-v-f3f3eg9] {
color: red;
}
</style>
<template>
<div class="example" data-v-f3f3eg9>hi</div>
</template>

CSS Modules

While the scoped style technique can be effective at times, one of its major drawbacks is that it is still susceptible to being affected by ones that have greater specificity. This is typically not a big problem for most styles but can be problematic when combined with third-party CSS when things like  .button  are common.

CSS Modules is a popular system for modularizing and composing CSS, as shown here:

<style module>
.red {
color: red;
}
.bold {
font-weight: bold;
}
</style>

Similar to scoped styles, add a  module  attribute to your  <style>  block, and it will append your styles with a random hash by default.

<style>
.red-vj29193 {
color: red;
}
.bold-vj2914 {
font-weight: bold;
}
</style>

However, using CSS Modules requires appending the CSS class with $style in a v-bind:class.

<template>
<h1 :class="$style.red">My Red Title</h1>
</template>
<style module>
.red {
color: red;
}
</style>

While the syntax does take some getting used to, the benefits of CSS Modules often outweighs the time it takes to onboard to the new way of writing classes. However, if you or your team don't need CSS Modules, you don't have to worry about this new syntax at all.

Strategies for Managing Styles

Keep Your Styles Coupled to Your Component

Rather than spend an inordinate amount of time trying to create a perfect design system, keeping your styles lower-level will allow you to ensure that future developers will know the context in which it was created. This improves long-term maintainability while also leveraging the intelligent code-splitting that Vue provides.

For example, in traditional CSS, you might write the styles for your button as:

style.css
.button {
background-color: blue;
color: white;
border-radius: 10px;
}

Even though this is only one CSS class, imagine what might happen if there were many more styles. Regardless of whether it was going to use the styles or not, users would download all of that data. Also, it would make life difficult when working with legacy code since it's hard to refactor without knowing the side effects.

If, on the other hand, you managed our styles using Vue:

src/components/CustomButton.vue
<template>
<button class="button">{{ text }}</button>
</template>
<script>
export default {
name: 'CustomButton',
props: ['text']
}
</script>
<style>
.button {
background-color: blue;
color: white;
border-radius: 10px;
}
</style>

It becomes easy for any developer to understand how the code is related with minimal concern for side effects. Isn't that convenient?

Generalize Styles Only When There Is a Proven Case of Reuse

Also, it can be tempting to stick with traditional methods of CSS as far as keeping everything in a shared file, but this is problematic since this file is unable to be intelligently parsed when the user visits a page. So unless you see a significant amount of style reuse across components, I suggest that you don't extract them into a generic CSS file.

Exercise

You will find the source code for the exercises in the course's GitHub repo in the  cafe-with-a-vue folder. To get started, check out the  P3C1-Begin  branch.

Instructions

  1. Migrate all of the styles from the static sites styles.css into the respective component files.

  2. Use your favorite pre-processor if you want!

Let's Recap!

In this chapter, you learned about:

  • Using preprocessors in a single-file component.

  • Strategies for managing styles with scoped styles.

  • Strategies for managing styles with CSS Modules.

  • Strategies for managing styles as you build components.

In the next chapter, we will take a deeper look into how components can communicate with one another.

Example of certificate of achievement
Example of certificate of achievement