Ruby on Rails, programming, and SEO
Check out my articles about Ruby on Rails, programming, and SEO. Weekly updates? Subscribe to my feed.

Leveraging Rails 3.1, SCSS, and the assets pipeline to differentiate your stylesheets

How to differentiate your stylesheets, and have different page styles using Rails 3.1, SCSS and the assets pipeline.

So, you’ve got different stylesheets and want to upgrade to the Rails 3.1 assets pipeline? The challenge by doing this is that all stylesheets will be compiled together in one file so therefore we need another method to differentiate our sites.

Here I will show how to use SCSS/CSS on the body-tag to differentiate between two different sites, and between the various pages on each site.

1. Differentiating your content

Let’s say that you are building a mobile and desktop site and want to differentiate your content sitewise. (If you’re building a mobile site, the actual server-side separation of the content can be done with a plugin like mobile-fu which works really great.)

Start by inserting a desktop and mobile class in your body-tags, like this:

<body class="desktop">

and for your mobile site:

<body class="mobile">

Next, add the following method to your application_helper.rb:

def find_named_routes
  routes = []

  Rails.application.routes.named_routes.each do |name, route|
    req = route.requirements
    if req[:controller] == params[:controller] && req[:action] == params[:action]
      routes << name
    end
  end

  routes
end

This method will find all named routes based on the current controller and action. It will also find duplicate routes and localized routes if you are using a route translation gem like i18n_routing.

Now you can add the method to your body-tags like this:

<body class="desktop <%= find_named_routes.join(" ") %>">

This way you’ll get body-classes like root, categories, category and so on. These can be used to differentiate your content later on. We will do this using SCSS.

2. Creating the CSS

SCSS is an extension to CSS which among a lot of other feature allows you to nest your content. Instead of:

.blah ul { ... }
.blah p { ... }
.blah a { ... }

In SCSS you can do it like this:

.blah {
  ul { ... }
  p { ... }
  a { ... }
}

And it will generate the exact same CSS. Neat, eh?

So now we can use this technique to differentiate our sites and individual pages. Like this, in desktop.css.scss:

body.desktop {
  margin: 20px;
  font-family: arial, helvetica, sans-serif;
  a { color: black }
  p { margin-bottom: 10px; }
  h1 { color: green; }
}

In categories.css.scss:

body.desktop.categories {
  h1 { color: red; }
}

And in mobile.css.scss:

body.mobile {
  margin: 10px;
  font-family: arial, helvetica, sans-serif;
  a { color: red }
  p { margin-bottom: 5px }
}

Pretty sweet. Now you just need to compile your assets, and you’re good to go.

Also see my other post about how to get your assets to work in Rails 3.1.

Update: And the answer to this Stack Overflow question: Using Rails 3.1 assets pipeline to conditionally use certain css

Related posts

Tags: , , ,

3 comments

  1. Paddy says:

    Interesting. I just noticed new rails projects were using these scss files. Is there any need to tell Rails to “watch” the existing scss files (so that they compile them and generate the css result each time the scss is modified ?).

    Cheers

  2. Paddy says:

    Well apparently no need for an extra step. In case it could be useful for other people :)

  3. Erin Parker says:

    Thank you so much!!! Great, simple, elegant solution. You’re awesome!

Leave a comment

 
Fork me on GitHub