I’ve been spending a lot of time recently trying to harness the full power of Sass. I love the idea of CSS preprocessing, because it allows me to treat my frontend code like backend code, in a way.

JSON for Configuration

My own personal website runs on a custom backend I made using PHP and JSON. The JSON files hold objects that I use to configure my site, such as global settings (language, directories to my assets, etc) or metadata for blog posts that I write.

Here’s a simplified example of what my home.json file might look like:

  {
    "view": "home",
    "template": "basic",
    "meta": {
        "title": "Home",
        "description": "This is the home page, son"
    },
    "date": null,
    "author": null,
    "auth": null,
    "styles": null,
    "scripts": null
}

Now let’s do it with Sass.

Sass Maps

Sass 3.3 introduced a nifty new data structure called a map (more info for the curious). They look pretty much like JSON:

  $map: (
    'key':              'value',
    'another key':      'another value'
);

As a quick example of what I can do with a Sass map, let’s say I want a comment block at the top of my global stylesheet that has my name, the project name, and my website inside. With maps and a bit of magic, here’s what we get:

  $_metadata: (
    'author':           'Adam Blum',
    'project':          'My Cool Site',
    'site':             'http://website.com'
);

/***********************************

    #{map-get($_metadata, 'project')}

    Designed by #{map-get($_metadata, 'author')}
    Visit #{map-get($_metadata, 'site')}

***********************************/

Here’s the compiled result:

  /***********************************

    My Cool Site

    Designed by Adam Blum
    Visit http://website.com

***********************************/

Pretty awesome, right?

You can start to get crazy with it:

  $_settings: (
    'dev-mode':                     true,
    'image-path':                   "/assets/image/",
    'image-format':                 "png",
    'svg-path':                     "/assets/vector/",
    'svg-format':                   "svg",
    'webfont-path':                 "/assets/fonts/",
    'webfont-format':               "woff",
    'use-opentype':                 true,
    'use-font-smoothing':           false,
    'load-fonts': (
        'Linux Libertine',
        'Neue Comic Sans Pro',
        'Arial'
    )
);

Add a quick little function…

  @function setting($key) {
    @return     unquote(map-get($_settings, $key));
}

…and some conditionals in the <body>

  body {
    @if setting('use-opentype') {
        text-rendering:             optimizeLegibility;
    }
    @if setting('use-font-smoothing') {
        -webkit-font-smoothing:     antialiased;
        -moz-osx-font-smoothing:    grayscale;
    }
}

Doesn’t this at least look better than this:

  $dev-mode':                     true;
$image-path':                   "/assets/image/";
$image-format':                 "png";
$svg-path':                     "/assets/vector/";
$svg-format':                   "svg";
$webfont-path':                 "/assets/fonts/";
$webfont-format':               "woff";
$use-opentype':                 true;
$use-font-smoothing':           false;

Now they’re all associated with each other, and you don’t have to think about doing that pseudo-namespacing $_setting-var garbage anymore.

I’ve got a lot of other cool stuff I’ve figured out, but I’ll save it for another day.


6,860 2 27