If you are new to vue-cli and its webpack template, you are probably in a situation where you do not really know how to declare global style rules for your project. This article will show you how to do this with standard CSS, but also with a preprocessor. We will use Stylus with stylus-loader.
Global CSS rules
One big strength of Vue.js is its modular nature. Just like the pieces of a puzzle, Vue allows you to build complex applications using components. Each component is ideally represented in a .vue
file which contains its own template, script and style. A single file component is a convenient way to encapsulate all the code of a specific building block. But what if we need some global CSS rules, for instance to set the default font family, background image or general media queries?
Unscoped style section in App.vue
Style rules declared in .vue
files are processed by Webpack thanks to vue-loader and PostCSS. When a style section is scoped, these rules only apply to the component in which they are defined. This means that you will not be able to style the body element from a scoped style section. <body>
is actually defined in your index.html
and is not part of any component template.
Suppose we are in App.vue
. This will not have any effect:
|
Now if we remove the scoped
attribute, the background color will be set! An unscoped style section for App.vue
is therefore a nice place to put some global CSS rules that are not specific to a component. However, App.vue
is a component itself, which may be a bit counterintuitive…
Imports in main.js
We have seen that style sections from single file components are processed by Webpack. But in fact, you do not really need a style section in a .vue
file to give some work to Webpack. You can simply import your CSS as a dependency in your main.js
file:
|
It works, but it looks weird. Moreover, in a Vue.js project, Webpack is mostly used to compile single file components. So when a stylesheet is not related to any specific component, it might be interesting to put it in the static
folder to distinguish it easily.
Static stylesheet
In the static
folder, resources are not processed by Webpack. If you put a style.css
in there, you will have to reference it manually in your index.html
like so:
|
Global Stylus variables
Webpack relies on loaders to process resources. If you use a CSS preprocessor like Sass, Less or Stylus, you will need the corresponding loader for Webpack: sass-loader
, less-loader
or stylus-loader
. For this particular example, we will use Stylus which is the most flexible and easiest to configure in a Vue.js project.
First of all, install Stylus and its loader in your project: npm i stylus stylus-loader -D
. We put these packages in dev dependencies because, of course, they will not be required in production.
If CSS preprocessors are part of your ordinary workflow, you probably like to create global files that contain some variables or mixins. For example, a common use case is to have all colors from a design in a single file using variables. It is useful since you can then use clear variable names in your code instead of a more obscure hexadecimal notation. In your Vue.js project, you may want to create such a file, named colors.styl
(in a stylus
folder), with the following content:
|
So far so good! There is still an important question, though: how do you include and use that file in your project?
Raw @import
rule in each style section
The most basic approach is to import your colors.styl
in the style section of each component using the following syntax:
|
Problem: it strongly violates the DRY (Don’t Repeat Yourself) principle because you will have to write this rule again and again… In large projects where there are lots of components, this is not a viable solution. If you move your file, you will have to modify your import everywhere.
@import
rule with a Webpack alias
A better approach is to use a Webpack alias to avoid repetitive modifications in case you move your styl
file. If you installed vue-router through vue-cli, you probably saw some @
in import paths. This is actually an alias that corresponds to src
. We can then apply the same logic to reference some global Stylus files!
In the resolve.alias
section of your build/webpack.base.conf.js
, add this code:
|
In your components, you should now be able to import your colors.styl
like so:
|
This is undoubtedly better, but what happens if you rename colors.styl
to variables.styl
? You will have to modify your imports in all components…
Import in all components from Webpack config
The best solution, by far, is to add a plugins
section at the end of your webpack.base.conf.js
(right after module
) with appropriate configuration to enable auto-import.
|
Restart your dev server.
You are now ready for the next battle!