A SASS with Bootstrap Workflow

So you’ve decided to start a project with Twitter Bootstrap, but you want to use SASS (SCSS)? Well, this is the post for you. Here are some tips from my current workflow for starting a SASS with Bootstrap project. DISCLAIMER: there many ways to slice this cake. So please, take what you like and leave what you don’t!

A Typical File Structure

In the stylesheets source folder, I generally only have one primary SASS file, that imports all others. If you are using a Rack app, do not use sprockets directives here, just SASS.

Depending on your stack, you will have some place where you have a stylesheets/ folder. Within that folder, I typically set up a basic folder structure that looks like this:

application.sass

/libraries

_variables.sass

_mixins.sass

/vendor

_bootstrap.scss

_bootstrap-responsive.scss

bootstrap/

_accordion.scss

_alerts.sass

_breadcrumbs.sass

etc…

/components

_tables.sass

_forms.sass

etc…

/sections

_homepage.sass

_product_detail.sass

_style_guide.sass

etc…

./libraries/: contains only variables and mixins: SASS that does not render any actual CSS, but is used later. Why? You’ll find out later!

./vendor/: Vendor framework libraries. In this case, only Bootstrap is here.

./components/: SASS patterns intended to be used across the site. Pretty much everything in here will be devoted a section in the live style guide.

./sections/: Layouts and other page-specific stylings. Anything that is not intended to be used in multiple places in a versatile way.

Bootstrap Source

I like the Bootstrap source SASS not hidden in a gem because I can want to control exactly which features are included. You don’t want to be in a situation where it feels like you can’t deprecate or evolve away from Bootstrap because you don’t control it. So, here is what I do:

EDIT: You have to do one fix to the files here. Copy the vendor/bootstrap/bootstrap.scss file up one level, and overwrite the vendor/bootstrap.scss file there. Do the same for bootstrap_responsive.scss

Open up the vendor/bootstrap/bootstrap.scss and comment out NEARLY EVERYTHING. Even the grid if you want to use a different grid. Uncomment features as you need them, when your user stories demand the functionality.

Include the vendor/bootstrap file in your ./application.sass file, and BOOM you’ve got a full controllable Bootstrap source.

When you need buttons, uncomment buttons. When you need wells, uncomment wells. Rinse and repeat.

Replicate this process for the javascript also, only including what you need when you need it.

(Note, this method also works if you don’t have Rails, or a rack app that can use gems, this still works for you. Yes, you can compile SASS with Bower and Grunt. Check out Sam Richard’s style guide prototyping stack)

Extending the Grid

With Bootstrap, you may typically insert its class selectors and elements into your markup to compose the, but some peepz do not desire this for semantic, SEO and other reasons.

SASS offers an attractive way to remove the clutter with the SASS @extend directive, however it has two performance pitfalls:

In Development: Using it in SASS nesting (more than two levels) may significantly slow down your compilation time, especially if that element is being @extend-ed a lot.

In Bootstrap in particular, it becomes tricky because you have to extend the grid class, as well as the wildcard class that applies the padding. For example, a Bootstrap element classed with .span3 will receive stylings from the .span3 selector, as well as a funky selector [class*=’span’]. For example, you can’t just do this:

.advertising-sponsor
@extend .span3

This misses the [class*=’span’] wildcard selector because @extend only scours literal selectors, not searching for anything that MAY apply. Therefore, you have to do this:

.advertising-sponsor
@extend .span3
@extend [class*='span']

The downside is the second @extend adds an extension to that target selector every time you use it, and a really long one if it is nested. Those hit the performance issues I described above, hard.

So, my process now is to create my own mixin that allows me to quickly pseudo-extend the grid class by calling the Bootstrap mixin that prints their styling. I place the following into my ./variables/_mixins.sass:

This essentially renders what bootstrap does for it’s span classes. This does duplicate CSS in the compiled result, but I have found that the performance impact of downloading more CSS pales in comparison to the pains suffered by @extend in development time, or in a more severe case, crashing or lagging the users’ browser.

Styling Bootstrap with Variables

Take a look at the ./vendor/bootstrap/_variables.sass. Notice how all the variables have !default after them? That means that SASS will NOT overwrite this variable if it is already defined. This allows you to create your own ./libraries/_variables.sass file, and include it in the load order before Bootstrap and effectively control those variables. This will be your primary way to style Bootstrap colors and such.

Using Compass or Bourbon with Bootstrap

Some people prefer Compass’ mixins. Some people like Bootstrap’s. Some like Bourbon’s. IMO, they are all good and I don’t mind using any, but it is a good idea to commit to one. For example, Bootstrap’s =Opacity() mixin takes a value from 0-100, while Compass’ function takes a value from 0-1. There is a variable order conflict with =transition(). I sometimes import pieces of compass, instead of the whole thing. For example, I like the ever-handy Compass =experimental() function. You can choose to import only specific files from Compass:

@import compass/css3/shared

Conclusion and Upcoming Topics

That’s it for now! Let me know if you have any topics you want me to expand on, or ideas for posts you want to see. I am currently doing a style guide using Groundwork-CSS, and hope to do a similar post later! Follow me on twitter for various nonsensical ramblings.

5 Comments

Nice structure, wouldn’t it even better to have sample repo to show this structure as an example :)

May 14, 2013 at 11:16 pm

Daniel Finnie says:

Good stuff! We really want to use this on a project but can’t because we depend on rails-admin which depends on the bootstrap-sass gem. Have you encountered this? Is there any way to use the bootstrap-sass gem without sending 2 copies of Twitter Bootstrap to the client?

June 17, 2013 at 3:59 pm

Nicholas Jayanty says:

Working on a rails app and am working through cleaning up the semantics of my html. When it says Include the vendor/bootstrap file in your ./application.sass file, and BOOM you’ve got a full controllable Bootstrap source, how would one go about doing this?

Total nube, so I know it’s a dumb question.

August 17, 2013 at 1:03 am

rttmax says:

This is very nice! Thank you. But I don’t understand how to do it for the javascript files. Do you use require.js?

January 8, 2014 at 5:37 am

b_d_m_p says:

Thanks. This was helpful.

I ended up doing it in CodeKit (You can download the Bower package for Bootstrap-sass-offical inside Codekit. I just changed the file structure to match yours.), but the principals were good to understand before attempting it. Thanks.