Ruby
Article
By Pat Shaughnessy

Twitter Bootstrap, Less, and Sass: Understanding Your Options for Rails 3.1

By Pat Shaughnessy
Help us help you! You'll get a... FREE 6-Month Subscription to SitePoint Premium Plus you'll go in the draw to WIN a new Macbook SitePoint 2017 Survey Yes, let's Do this It only takes 5 min

Twitter Bootstrap and Rails

By now, we’ve all seen Twitter Bootstrap – it’s a great CSS and Javascript library open sourced by Twitter that makes it easy to produce a very polished looking site, with fantastic support for layout, navigation, typography, and much more. Twitter Bootstrap is based on Less.js, the popular dynamic CSS scripting language written by Alexis Sellier or @cloudhead. Less.js, like Node.js, is implemented completely with Javascript. While Less is based on Javascript and not Ruby, some great work has been done just in the last couple of months to make it easy to set up Twitter Bootstrap in your Rails 3.1 app using a variety of different approaches.

Twitter Bootstrap is a great way to
quickly build a very polished web site.

Today I’m going to review the basics of Twitter Bootstrap, and then take a close look at the following gems and libraries: less-rails-bootstrap, sass-twitter-bootstrap, bootstrap-sass and bootstrap-rails. With all of these different options available, it’s hard to know exactly how to get started using Twitter Bootstrap with Rails. Before you dive in and start building the next killer Twitter Bootstrap Rails 3.1 app, be sure to understand how these different gems work under the hood so you can decide which one is right for you and your app.

Twitter Bootstrap basics

On the surface, Twitter Bootstrap is simply a single CSS file, bootstrap.css, that provides all of the style and layout support, along with a few Javascript files that implement various dynamic features. This means the fastest and simplest way to get started using it is just to copy bootstrap.css into your Rails 3.1 app/assets/stylesheets folder like this:

$ git clone https://github.com/twitter/bootstrap.git
$ cp bootstrap/bootstrap.css path/to/app/assets/stylesheets/.

…and you’re off to the races! Use their online demo page as a guide to get started; you can even use “Inspect Element” or “View Source” right on that page to get a sense of what styles they’re using for each feature.

However, as I mentioned above, Twitter Bootstrap is based on the Less.js framework, and the bootstrap.css file is a actually a compiled version of the Less code contained in a series of “.less” code files:

Twitter Bootstrap files

Looking in the Twitter Bootstrap github repo, the Less code files are contained in the lib folder, while the compiled bootstrap.css file is right in the root folder.

If you’re not familiar with Less, it’s very similar to Sass: it provides an enhanced, more powerful language for authoring CSS style code. As with Sass, you can use variables, mixins, nesting, etc. Think of Less as Sass implemented with Javascript instead of Ruby. If you’re interested in learning more about Less take a look at lesscss.org; there’s also a great article out there by Jeremy Hixon, An Introduction To LESS, And Comparison To Sass, that compares the two languages.

Therefore, as explained on the Twitter Bootstrap introduction page, the best way to use Twitter Bootstrap in a Rails site is to use the Less source code written by the Twitter team directly, and not just the compiled CSS output. This allows you take advantage or override the styles provided by Twitter Bootstrap in a very straightforward way. But since Less isn’t supported by the Rails 3.1 asset pipeline, this is a bit of a problem…

Less-rails-bootstrap

Fortunately, Ken Collins did some great work during the past few months to solve this problem; he wrote a new gem called less-rails-bootstrap that adds support for Less into the Rails 3.1 asset pipeline. You can read his blog post or check out his Github readme page for the details. Another gem called twitter-bootstrap-rails by Seyhun Akyürek uses the same approach, although at first glance twitter-bootstrap-rails doesn’t appear to have any tests in it, while Ken’s less-rails-bootstrap does have an effective MiniTest::Spec test suite.

I’ll repeat the setup steps from Ken’s blog post here; first just add less-rails-bootstrap (or twitter-bootstrap-rails) to your Gemfile in the :assets group:

group :assets do
  gem 'less-rails-bootstrap'
end

And install it using “bundle install.” Then all you need to do is require the Twitter CSS code from your app/assets/stylesheets/application.css file like this:

/*
 *= require twitter/bootstrap
*/

As Ken explains, now you’re free to override and manipulate the Twitter Bootstrap Less code directly; for example if you add this code to a new file with a .css.less extension:

@import "twitter/bootstrap";

#foo {
  .border-radius(4px);
}

… you now have a cross-browser compatible CSS style that will apply a rounded border with a radius of 4 pixels. But how does this actually work? Let’s take a closer look:

What Gem does what?

In true Rails fashion, it turns out there’s a lot of “magic” going on here behind the scenes. Before using this approach in your application, it’s important to understand which gems are involved and what all of these gems are actually doing for you. Taking it from the top and diving down, here’s how less-rails-bootstrap works:

  • less-rails-bootstrap: Ken’s gem actually includes the Twitter Bootstrap Less code files (in the vendor/assets folder) and provides a Rails engine to make them accessible to your app. More on this in a minute…
  • less-rails: Ken wrote also wrote this gem, based on an earlier version by Karst Hammer, that helps integrate Less with the Rails 3.1 asset pipeline, providing extensions that Rails developers would expect. See Ken’s clarification on this in the comments.
  • less.rb: This gem, written by Charles Lowell, is a thin wrapper around the Less language compiler, allowing your Rails app to call it.
  • therubyracer: Also written by Charles Lowell, this gem provides Ruby programs, in this case your Rails 3.1 app, the ability to call the V8 Javascript engine.
  • libv8: This gem makes it easy to install or compile from source the actual V8 Javascript library, which itself is implemented mostly in C.

With so much code involved, you might ask: Will less-rails-bootstrap slow my application to a crawl? The good news here is that you only need the Javascript V8 engine and all of the other code above it to compile the Less code files into CSS. That is, you’ll only need all of this for development purposes while you’re writing or modifying the CSS styles. Before you deploy to production you’ll precompile your .css.less asset files, the same way you already do with your other CSS or Javascript files – and none of these gems will actually be used on your production web server.

Another important piece of magic that Ken has implemented is the way he packaged up Twitter’s Less code file using a Rails engine. Here’s how that works:

less-rails-bootstrap gem

If you’re not familiar with Rails engines, take a few minutes to watch Ryan Bates explain how they’re implemented in Rails 3.1. Less-rails-bootstrap implements the simplest kind of Rails engine, providing your Rails 3.1 app access to the Twitter code as additional, static asset files. When an HTTP request comes in from the user – in this case you, since you only use this code during development – it’s forwarded on by Rails to the engine in the less-rails-bootstrap gem. In practice, you don’t really need to worry about how this works, but it is good to know where the Twitter Less code files are located, in case you need to find a specific style definition or search for something else:

$ cd `bundle show less-rails-bootstrap`
$ find vendor
vendor
vendor/assets
vendor/assets/javascripts
vendor/assets/javascripts/twitter
vendor/assets/javascripts/twitter/bootstrap
vendor/assets/javascripts/twitter/bootstrap/alerts.js
vendor/assets/javascripts/twitter/bootstrap/buttons.js
vendor/assets/javascripts/twitter/bootstrap/dropdown.js
vendor/assets/javascripts/twitter/bootstrap/modal.js
vendor/assets/javascripts/twitter/bootstrap/popover.js
vendor/assets/javascripts/twitter/bootstrap/scrollspy.js
vendor/assets/javascripts/twitter/bootstrap/tabs.js
vendor/assets/javascripts/twitter/bootstrap/twipsy.js
vendor/assets/javascripts/twitter/bootstrap.js
vendor/assets/stylesheets
vendor/assets/stylesheets/twitter
vendor/assets/stylesheets/twitter/bootstrap.css.less
vendor/frameworks
vendor/frameworks/twitter
vendor/frameworks/twitter/bootstrap
vendor/frameworks/twitter/bootstrap/bootstrap.less
vendor/frameworks/twitter/bootstrap/forms.less
vendor/frameworks/twitter/bootstrap/mixins.less
vendor/frameworks/twitter/bootstrap/patterns.less
vendor/frameworks/twitter/bootstrap/reset.less
vendor/frameworks/twitter/bootstrap/scaffolding.less
vendor/frameworks/twitter/bootstrap/tables.less
vendor/frameworks/twitter/bootstrap/type.less
vendor/frameworks/twitter/bootstrap/variables.less
vendor/frameworks/twitter/bootstrap.less

Sass-twitter-bootstrap

While Ken’s done a great job with less-rails-bootstrap, you may prefer to use Sass instead of Less, because it’s already supported by Rails 3.1 out of the box, or because your application already contains a large amount of Sass code, or possibly just because you’re more familiar with it. At first glance, this seems to be a serious problem for Twitter Bootstrap: it’s not appropriate for a large portion of the Rails community that prefers Sass, since it was implemented with the Javascript-centric Less.js technology.

Don’t worry – some other great developers (John Long, Jeremy Hinegardner and others) ran into this dilemma already and came up with a solution: they translated Twitter Bootstrap’s Less code into Sass, and released that as a separate library on Github, called Sass-twitter-bootstrap.

Sass-twitter-bootstrap is not a gem, but instead is just a github repo containing Twitter’s translated code. To use it in your Rails 3.1 app, just clone the repo and copy the bootstrap css file into your app, like this:

$ git clone https://github.com/jlong/sass-twitter-bootstrap.git
$ cp sass-twitter-bootstrap/bootstrap.css path/to/app/assets/stylesheets/.

Of course, this isn’t really any different than copying the bootstrap.css file directly from the Twitter Bootstrap repo; instead what you should do is copy the Sass source files right into your application like this:

$ rm path/to/app/assets/stylesheets/bootstrap.css
$ cp -r sass-twitter-bootstrap/lib path/to/app/assets/stylesheets/twitter

And now since the Rails 3.1 asset pipeline supports Sass out of the box, we’re good to go… almost! If you run your app now, you’ll see an error:

ActionView::Template::Error (Undefined variable: "$baseline".
  (in /path/to/app/assets/stylesheets/twitter/forms.scss))

Thanks to Brent Collier, there’s a simple solution for this problem: the code in application.css by default uses “require_tree” to include all of the code under app/assets/stylesheets:

/*
 * This is a manifest file that'll automatically include all the stylesheets available in this directory
 * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
 * the top of the compiled file, but it's generally better to create a new file per style scope.
 *= require_self
 *= require_tree .
*/

As Brent explains, the problem with this is that Twitter Bootstrap’s Less code (and the translated Sass version) was designed to be included once using the bootstrap.scss file, which in turns includes all of the other files. Brent’s solution works perfectly: just remove “require_tree” and require bootstrap.scss directly:

/*
 * This is a manifest file that'll automatically include all the stylesheets available in this directory
 * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
 * the top of the compiled file, but it's generally better to create a new file per style scope.
 *= require_self
 *= require twitter/bootstrap
*/

Conceptually, here’s what this setup looks like:

Copying sass files

The benefit here is that now you have Sass code implementing Twitter Bootstrap directly inside your Rails 3.1 app! This means you can go ahead and use, override or modify the Sass to your heart’s content.

The obvious drawback here is the manual copy process involved. You’ll need to copy the Sass code files once into your Rails app to get started, but then you’ll have to repeat the copy each time Twitter releases a newer, better version of Twitter Bootstrap. While this won’t happen every day, why set yourself up for an ongoing maintenance problem?

Another drawback is that you’re using a second-hand, translated version of Twitter’s code, and you’ll have to trust the people who maintain sass-twitter-bootstrap to accurately translate the Less into Sass.

--ADVERTISEMENT--

Bootstrap-sass and bootstrap-rails

Like everything in the Rails world, there are always other good solutions out there you can take a look at, in this case the bootstrap-sass gem by Thomas McDonald and the bootstrap-rails gem by AnjlLab. Both of these gems combine the Sass translation approach with a Rails engine to avoid the manual copy maintenance headache.

Using bootstrap-sass (or bootstrap-rails) is a simple as adding it to your Gemfile:

group :assets do
  gem 'bootstrap-sass'
end

Run “bundle install” and then add a require statement to app/assets/stylesheets/application.css:

/*
 *= require bootstrap
*/

Similar to less-rails-bootstrap, this works by having Rails 3.1 load the Sass code from a Rails engine inside the gem:

Bootstrap sass and rails

So there’s no need to download and copy either the Twitter Bootstrap Less code, or its translated Sass version. As new versions of Twitter Bootstrap are released, presumably Thomas McDonald will re-translate the Less code into Sass, and re-release his gem. Then you’ll be able to just run “bundle update” to get the new Twitter code into your application!

Other options

Amazingly, there are even more options out there for integrating Rails 3.1 and Twitter Bootstrap that I don’t have time to cover today:

  • compass-twitter-bootstrap is similar to bootstrap-sass and bootstrap-rails, using a Rails engine to provide a translated version of the Twitter Bootstrap code, but is geared instead to the Compass CSS framework.
  • twitter_bootstrap_form_for implements a custom Form Builder object, the object yielded by form_for in your view, designed specifically for Twitter Bootstrap.
  • css-bootstrap-rails is similar to bootstrap-sass and bootstrap-rails, but uses a Rails engine to include only bootstrap.css without any Less or Sass files.

Six of one, half dozen of the other

All of these approaches will work equally well:

  • Using the original Less code via a Rails engine (less-rails-bootstrap or twitter-bootstrap-rails)
  • Copying in translated Sass code directly into your application (sass-twitter-bootstrap), or
  • Using a translated Sass version via a Rails engine (bootstrap-sass or bootstrap-rails).

Less and Sass are very similar, and using one language or the other is really a matter of personal preference. Similarly, using a Rails engine is a convenient way to include the Twitter Bootstrap code in your Rails 3.1 app and to manage upgrades smoothly. However, using a Rails engine adds some additional “magic” to your app and can be somewhat confusing when you need to find, inspect or search against the Sass code. There’s a simple elegance to the approach of just copying the Sass code right into your app, and you may not often need to update to a newer version of Twitter Bootstrap.

Which approach to take is up to you!

And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like Jump Start Rails.

Comments on this article are closed. Have a question about Ruby on Rails? Why not ask it on our forums?

Login or Create Account to Comment
Login Create Account
Recommended
Sponsors
Get the most important and interesting stories in tech. Straight to your inbox, daily.Is it good?