Your friends at Viget present Extend, a Code & Technology Blog

Sharing Data Between Sass and JavaScript with JSON

Update

Jun 11, 2014

For those unable to easily import JSON into their JavaScript enviroment, Andy Matthews has come up with a gist for how to include it using grunt-contrib-concat. Also checkout grunt-json.

Traditionally stylesheets describe the majority of the presentation layer for a website. However as JavaScript becomes necessary to present information in a stylistically consistent way, it becomes troublesome to keep these mediums in sync. Data visualizations and break-point based interaction are prime examples of this; something I bumped into on my most recent project.

I should note that this is not an unsolved problem, and there are many interesting examples of this technique in the wild. However I wanted a simpler solution and I've been wanting to write a Sass plugin anyway.

The result of this curiousity is sass-json-vars. After requiring it, this gem allows JSON files to be included as valid @import paths; converting the top level values into any of the Sass data types (strings, maps, lists).

Usage

Consider the following snippet of JSON (breakpoints shortened for brevity):

{
    "colors": {
        "red"  : "#c33",
        "blue" : "#33c"
    },

    "breakpoints": {
        "landscape" : "only screen and (orientation : landscape)",
        "portrait"  : "only screen and (orientation : portrait)"
    }
}

sass-json-vars exposes the top level keys as values whenever a JSON file is included using @import.

@import "variables.json"; 

.element {
    color: map-get($colors, red);
    width: 75%;

    @media (map-get($breakpoints, portrait) {
        width: 100%;
    }
}

Similarly, these values can be accessed in JavaScript using a module system such as CommonJS with browserify. For example, if we need to determine if the current browser's orientation is at landscape:

var breakpoints = require("./variables.json").breakpoints;

// https://developer.mozilla.org/en-US/docs/Web/API/Window.matchMedia
var isLandscape  = matchMedia(breakpoints.landscape).matches;

if (isLandscape) {
    // do something in landscape mode
}

Integration

sass-json-vars can be included similarly to sass-globbing or other plugins that add functionality to @import. Simply include it as a dependency in your Gemfile:

gem 'sass-json-vars'

or within Rails:

group :assets do
    gem 'sass-json-vars'
end

Asset paths when using sass-json-vars with the Ruby on Rails asset pipeline should automatically be handled.

Final thoughts

sass-json-vars supports all of the data types provided by Sass. This could be used to describe media queries for the breakpoint Sass plugin, or store special characters for icons generated by IcoMoon.

Checkout the repo on Github and feel free to comment about how you use it!


Get More From Viget

Subscribe to get our monthly newsletter and occasional special announcements.