With the coming of spring, I feel the need to inject a touch of colour into my Application. I actually need to tackle the overall look and feel to sort out my preferred application interaction patterns, but some of the ‘feel’ components are looking particularly challenging. So I’m starting with the ‘look’ as my semi-productive way to delay the inevitable brain drain until next week…
My challenge: How do I customise the default styles provided by Twitter Bootstrap, without creating a maintenance nightmare?
The short answer always sounds so easy: create my own stylesheet to hold all my overrides.
The longer answer needs more than a ‘monkey see monkey do’ approach (when something invariably goes wrong, this monkey gets confused) so I had to dig a little deeper to try and better understand how it all integrates. For example learning that @import is not the same as requires_tree. For example, learning that things behave differently in Dev vs Prod because of the clever way the asset pipeline and sprockets handle compiling in different modes. And a whole lot more. . .
Like all things in software, there’s ways and there’s better ways! So here’s my longer answer…
1. Knowing my target?
My App will be busy enough, so it definitely needs to stay simple and clean. And I don’t want it to look, well, bootstrappy. Using good-old-fashioned pencil and paper, I’ve mocked up the basic UI design and interaction styles (some of which are going to be tricky to implement). So, the initial target is sketched on paper – let’s go.
2. Selecting what to customise in Bootstrap?
While I know which bootstrap components I plan to use, making the ‘tweaks’ somewhere(s) in the +6000 rows of the bootstrap.css so they look like my App seemed to be a bit daunting initially. For this, I found Fancyboot to be useful. As a (late) newcomer to BS, Fancyboot gave me a quick way of mocking up the colouring and helped me figure out which of the BS components I wanted to take advantage of. Once I’d finished playing with the colour settings in Fancyboot, I was able to download the resultant .css to find which classes that I would want to override.
3. Prototype the Look.
To check how the proposed changes translate across the functionality that I’ve already developed, I wanted to do a quick and dirty prototype.
Working in a separate branch, I copied each of the customised Bootstrap classes from the file I downloaded from Fancyboot, into my BS stylesheets: scaffolds.css.scss and bootstrap_and_overrides.css.scss. I updated my layout views and partials (application.html.erb, _navigation .html.erb, and _message.html.erb) to directly use the classes I wanted (as per Bootstrap instructions).
Running the App in Chrome, I could check out whether I was happy with my settings, or take advantage of Chrome’s “Inspect Element”. It’s a great way to try out various settings on the fly, see the results real-time, and then apply the tweaks to my class overrides as appropriate.
Overall, my customisations run to around 400 rows in my overrides stylesheet with a handful of tweaks to the scaffold stylesheet, giving me a pretty good first cut prototype.
4. Decoupling the Look from the How.
While the prototype is quick, and could probably be used longer term, my App is completely tied to the Bootstrap. Looking ahead to the next Bootstrap version, stuff will break. In the prototype, many of the bootstrap classes (including my overrides) are embedded directly in my views (i.e. hard-coded in the html).
If I ever want to get rid of bootstrap – coupling to their class names will cause everything to break. I really liked The Nitty Gritty post on decoupling the styling from the App functionality (along their advice on using practical, semantic names.) So, sticking with the plan to ‘leverage’ bootstrap styling as my starting point, I’ve figured how I will decouple the bootstrap styles.
Now the real UI work starts – On y va!