Sharing Data Between Sass and JavaScript with JSON

Updates

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;

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 Sass. Just add it to your Gemfile:

gem 'sass-json-vars'

# Or within Rails under the asset group

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

Asset paths 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!

Nate Hunzaker

Nate is a senior developer working from New York City, where he focuses on client-side application development. Most days, you can find him neck-deep in JavaScript working with clients such as The Nature Conservancy and the Wildlife Conservation Society.

More articles by Nate