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.