loading...
Cover image for How to share SASS variables with JavaScript code in VueJS

How to share SASS variables with JavaScript code in VueJS

pecus profile image Matteo Fogli Updated on ・3 min read

Having a single variable declaration that works across different coding languages is a goal every developer strives to reach, no matter the technology or framework they adopt. It brings together convenience (update the value once, see it working everywhere) with consistency and lower runtime error rates.

This post explains how to share variables between Sass and JavaScript in VueJS. It will be useful every time you have layout constraints that need to be shared with front-end logic. The opposite case, where business logic determines styles update, is mostly solved with inline styles on DOM elements and CSS Custom Properties. CSS Custom Properties are well supported, but if you are looking for a solution based on SASS, keep on reading.

Step 1: Export variables from SASS/SCSS

We can use a feature borrowed from CSS Modules to export SASS variables and make them available as imports to JavaScript code. We combine a syntax :export with a webpack loader CSS Loader that provides the exported values to JavaScript imports.

:export is implemented as a pseudo-selector and as such is completely transparent to SASS:

$your-sass-var: #663399;

:export {
  variablename: $your-sass-var;
}

This declares an SCSS variable and exports it under the variablename identifier.

Step 2: Import SASS/SCSS variables in JavaScript

The easiest way to import your exported SASS variables is to import the SASS file itself.

import exportedVars from './path/to/file.scss' 

But with Vue, we rarely author styles as independent SCSS or SASS files. Most of the time you’d author Single File Components, a custom VueJS file format that uses HTML-like syntax to describe a Vue component, usually including a template, a script and a style block.

So how do you import only the style code block from a SFC? It took me a while to find the answer, but the hint is "the same way webpack does". You ask Vue Loader to do it for you.

Vue Loader turns a single file into an export of three (or more) files. In doing so, it rewrites the source filename with a syntax that allows to address a specific block. Like this:

import exportedVars from './path/to/file.vue?vue&type=style&index=0&lang=scss' 

./path/to/file.vue is your usual reference to the target file. If you are importing from the style block within the same SFC, use ./yourcomponentname.vue. Next is the ?vue query string part. This allows Vue Loader to understand it has already destructured the SFC into parts and should provide the code block based on its type and index. &type=style, &index=0 and &lang=scss allow Vue Loader to fetch the correct block and pass it to the correct preprocessor.

The index parameter allows to address multiple style blocks that might be in an SFC.

Step 3: Use your imported variables

Sass variables are accessible as properties of the identifier used for import, e.g. identifier.variablename:

Here is a complete (and simplicistic) full example:

<template>
  <div>
    <p>Andy Kaufman {{ lyrics }}</p>
  </div>
</template>
<script>
import styles from './ManOnTheMoon.vue?vue&type=style&index=0&lang=scss'

export default {
  name: 'ManOnTheMoon',
  data() {
    return {
      lyrics: styles.lyrics,
    }
  },
}
</script>
<style lang="scss">
$lyrics: ' in the wrestling match';

:export {
  lyrics: unquote($lyrics);
}
</style>

Which will display the phrase: "Andy Kaufman in the wrestling match"1.

Note: that all variables are exported as strings. Use type casting and conversion if you need to coerce a value to number or boolean.

Wrapping up

This article focuses on VueJS, but this approach is valid with any framework or build pipeline that relies on webpack with css-loader.

CSS Custom Properties (AKA CSS Vars) provide an even smoother implementation: you can read and update custom properties via element.style.getPropertyValue() and element.style.setProperty() respectively, and I encourage you to make the switch and adopt CSS Custom Properties in place of SASS vars (even within SASS!). Yet, this solution can be useful if you already have a fully developed project built on SASS variables where refactoring to CSS Custom Properties is not an option.


  1. If you caught the reference in the example, I suspect that you’ll be singing "Yeah, yeah, yeah, yeah" in your head by now. At modo we can't miss a chance to drop an R.E.M. reference if we can 😬
  2. Cover Photo by Lucas Benjamin on Unsplash

Posted on by:

pecus profile

Matteo Fogli

@pecus

CEO of @madebymodo, dev, obssessed with performance, promoting a faster and universal Web

Discussion

pic
Editor guide