CSS Variables With Rack Middleware
Before I continue, I should mention that this problem has [in one sense] already been solved. SASS, which is a completely different way of writing CSS (based on HAML, gives us as Rails developers, the ability to have the much-desired variables in our CSS. And, SASS definitely has it’s benefits: variables, nesting, etc. But, it all just seems like a bit of overkill; I don’t want to change the way I write CSS, I just want to add variables. Plus, I really don’t like the fact that it’s whitespace-sensitive and that I can’t mix in regular CSS.
Enter CSSVariables middleware. It’s pretty basic and, as I mentioned, pretty quickly put together (at the time of this post, I still need to add tests), but it does what you think: it allows you to use variables in your CSS files. Basically, it just parses your CSS “templates” with ERB. Eventually, I’ll do a better job of adding support for other parsers, but right now, I can only guarantee that ERB will work.
In development, the middleware will re-render your CSS file on every request. In production, it will render and write to disk the first time the file is requested, so the very_minor performance hit of rendering the template will only be felt the first time the file is requested.
Using the middleware is pretty straight forward:
config.middleware.use 'CSSVariables', :templates => "#{RAILS_ROOT}/app/views/css"
There are other configuration options, but the :templates setting is the only required one, and simply specifies the directory your templates reside in (check out the source for more options). Within your templates directory, you can also create a variables.rb file that will be loaded, and will give your templates access to any methods defined in the variables.rb file.
That’s about it. There’s some possibility that this would work better within a Rails project as Rails Metal (which is basically just fancy middleware) instead of just adding it to the middleware stack, but there are certain things that would need to be modified before it would work properly as metal (i.e. returning a 404 when the file isn’t found, instead of just sending the request up the middleware stack with @app.call).
I don’t currently have comments on this blog, so just drop me a line if you find a bug / have a suggestion / hate this idea. Or, you can find me on Twitter.
Posted by Phil Burrows on Mar 18, 2009
You might also be interested in CSS Dryer, a Rails plugin that gives you CSS variables as well as nesting. Best of all, there’s no new syntax to learn and you can mix in regular CSS.
http://github.com/airblade/css_dryer/tree/master
I’ve been planning to convert this from a Rails plugin to a Rack middleware for ages…your project has given me a nudge to get a move on!
Hehe...rack.