Managing Styles with Sass on Heroku
I’ve generally found stylesheets to be the messiest part of any website. And I’m not surprised:
- Cross browser support means kludgy code
- Functionality usually takes the drivers seat to well thought out styles
- It’s someone else’s job
But organizing styles doesn’t have to be a mess and here’s one strategy that may make your life easier.
Since REST became the de facto way to design Rails apps, I’ve focused on organizing stylesheets by the same patterns. It just seemed natural that if you had a folder
/views/users/new.html.erb you should have a similiar folder
/stylesheets/users/new.css. Back in 2008, I wrote a two part post on how to do this nicely with Rails. Three years later, I’m not the only one who thinks that this is a decent idea.
So, it seemed like a great time to refresh the way I manage styles in my Rails apps.
Why Start from Scratch?
Simply put, this was a pain in the ass. Why was it harder than it should have been?
- I’m masochistic: I wanted it to work a certain way. I didn’t want to wrangle with a bloated framework or sacrifice on simplicity.
- Heroku: Heroku has a (mostly) read-only filesystem. Waaa, waaa!. Since Sass needs to be compiled, this poses a bit of a problem. There are a few workarounds that involve serving CSS from
/tmp, but I didn’t want a hack.
- Organization: I resisted Sass for a long time. I think by just organizing your selectors you can get a lot of the same benefits. My new setup had to have the same clarity.
- Packages: Everyone should know by now that the HTTP overhead of requesting multiple CSS files degrades client performance. But you can’t just pile them all into one file because you need to separate styles for print, screen, IE, or mobile. This problem had a solution, but not with Git based deployments on Heroku and the Amazon S3 workaround sounded like trouble.
Seriously, it shouldn’t be this god damn complicated.
- Sass: I was commited to porting to Sass, specifically because you don’t have to rewrite all your CSS to get started. Scss plays nice. It’s part of Haml, so throw it in your
- Migrate your CSS to Scss: Using the command line tool
sass-convertI migrated all my CSS to Scss. I know it needs a lot of refactoring to take advantage of Sass, but I’ll do that later.
- Organize: I wanted stylesheet packages to be derived by how styles were organized - not by a configuration file. So while it made sense to have the Sass files live next to my erb (remember, I have a one-to-one mapping of styles to my templates), Chris Powers noted that it was cleaner to store them in
/app/stylesheets/:package/. For me,
:packagewas just “desktop.” Later, I can easily create packages called “mobile,” “print,” or “ie” if I need to. See?
- Use Rack to do all the heavy lifting: Compiling Scss isn’t hard. Concatinating all the stylesheets isn’t hard either. Ryan Bates’ 222nd Railscast helped me write a Rack application that does the work:
- Add the route and reference it: With Rack doing all the hard work, I just point to it:
All together now!
- Instead of 15-some stylesheets being downloaded at ~50 KB, now I send the client one 8 KB file.
- No writing to disk! So Heroku’s happy.
- Varnish leverages HTTP to cache the compiled CSS.
- I can sleep again because all my styles are now served in one tight bundle.
- You get a nice free gist of the code to try for yourself.