Scoping CSS in Rails Applications

So far, I’ve seen two ways to scope CSS:

  1. Add a class to the body tag in your application layout that you programmatically change depending on what page is being rendered.
  2. Create page or controller specific stylesheets. Don’t include these in your manifest file (so that they’re not loaded into application.css), and then have the application layout conditionally include them when appropriate.

I read somewhere that #1 is anti-pattern, but I can’t remember where I read that, and I don’t think they explained why. Maybe this starts to make your selectors too specific? I’d like to hear other people’s opinions about why this would be considered an anti-pattern.

Currently I’m using #2, but there are some aspects I feel are questionable. For one, I’m using Bootstrap, and I have included all of the Bootstrap stuff in application.css, but then a lot of my page specific stylesheets need the Bootstrap stuff (because I’m using their mixins and also extending Bootstrap classes into my own).

At first, I just required the specific Bootstrap stuff I needed, e.g. I might include bootstrap/mixins, bootstrap/forms, and bootstrap/buttons in one of the page specific stylesheet. This felt messy, and I already had all of this stuff included in my application.css which was getting loaded for every page. As a result, I was loading some Bootstrap stuff twice for every page just so I could use it in my page specific stylesheets. Because of this, I changed things so that all of my page specific stylesheets included application.css, and then modified my application layout to either (a) only load the page specific stylesheet or (b) load application.css if there was no page specific stylesheet.

####Background

I didn’t really feel the need to scope things like this until I started trying to move Bootstrap stuff out of my html. I want to have the classes I specify in my views be content specific, so I’ve been trying to move “style classes” like row, col-*-*, panel, btn-primary, etc. out of my views and instead use stuff like sign-up-form and then mixin the Bootstrap stuff (or extend it in if there is no mixin).

I want to have this separation because it will make easier to change things later. E.g. maybe I want to use wells instead of panels on a certain page, then I just need to make that change in one place. Or maybe I want to test out replacing Bootstrap with something else. It also feels nice to not have the Bootstrap “class bloat” in the HTML.

####tl;dr

  • In order to scope my CSS, I’ve created page specific stylesheets, but they all need stuff from application.css.
  • I feel like I’ve strayed to far from the Rail’s default of including everything into one stylesheet, and so I’m missing out on the performance benefits you get from that.
  • I’m thinking of scoping my CSS by adding a class to the body tag in my application layout, but I wanted to see if you guys have any thoughts regarding (a) why that could be harmful or (b) an alternative way to scope the stylesheets.

Is there a way to only include a file for the purposes of compiling the Sass into CSS, but not have the contents of the included file include in the output CSS (aside from what pulled from mixins, extensions, etc. into the selectors)?

For example, if you have

// base.scss
.red-background {
  background-color: red;
}
// page1.scss
section {
  @extend .red-background;
}

Then page1.scss is compiled into the following CSS file

section {
  background-color: red;
}

and not into

.red-background {
  background-color: red;
}
section {
  background-color: red;
}

I’m pretty new to Sass, so I could be misunderstanding how @extend or the compiling works.