A Bootstrap 3 / LESS work-flow

Currently working on a project and on this occasion worked from the beginning by overwriting Bootstrap’s variables (as opposed to simply just overwriting its styles). My workflow, which will no doubt change as I discover new and better ways, for now it’s working out well.

By the way, I’m working in a fresh out-the-box Laravel 5 project which has the following folder structure for assets (LESS, CoffeeScript etc):

resources/
  coffee/
  less/
    bootstrap/
    app.less
    bootstrap.less
    ...
    variables.less

Getting setup

Everything within resources/less/bootstrap is all the bootstrap LESS files – unaltered. The purpose of the bootstrap.less file is to @import the various *.less files that the project requires (e.g. navbar.less, list-groups.less, panels.less), by default all are included. The variables.less contains a huge collection of well organised variables which control many aspects of styling such as colors, backgrounds, margins etc. Both of these files, as well as all files within the bootstrap/ directory I wish to leave as is. So I’ll create copies of bootstrap.less and variables outside the bootstrap/ directory:

resources/
  coffee/
  less/
    bootstrap/
    app.less
    bootstrap.less
    ...
    variables.less
  bootstrap.less (copy)
  variables.less (copy)

Within the bootstrap.less file, to begin with I commented out ONLY component less file imports. This allows me to import on those styles as and when I need them. I also changed the paths as this copy of bootstrap is outside the bootstrap directory (e.g. @import ‘bootstrap/navbar.less’) However, other core less files should be left as is:

less/bootstrap.less (copy)

// Core variables and mixins
@import "bootstrap/variables.less";
...
//
// Reset and dependencies
@import "bootstrap/normalize.less";
...
//
// Core CSS
@import "bootstrap/scaffolding.less";
...
//
// Components
// @import "bootstrap/component-animations.less";
// @import "bootstrap/dropdowns.less";
// @import "bootstrap/button-groups.less";
...

As for the variables.less copy, I commented out all variables:

less/variables.less (copy)

...
// @gray-base: #000;
// @gray-darker: lighten(@gray-base, 13.5%); // #222
// @gray-dark: lighten(@gray-base, 20%); // #333
...

I also imported a few additional colors to give me a more interesting color pallete for my new project. I took these colors from Bootstrap Flat UI (expect @white which is a color I came up with on my own 🙂

// //== Colors
// //
// //## Gray and brand colors for use across Bootstrap.
//
@white: #fff;
//
@turquoise: #1abc9c
@green-sea: #16a085
@emerald: #2ecc71
@nephritis: #27ae60
@peter-river: #3498db
@belize-hole: #2980b9
@amethyst: #9b59b6
@wisteria: #8e44ad
@wet-asphalt: #34495e
@midnight-blue: #2c3e50
@sun-flower: #f1c40f
@orange: #f39c12
@carrot: #e67e22
@pumpkin: #d35400
@alizarin: #e74c3c
@pomegranate: #c0392b
@clouds: #ecf0f1
@silver: #bdc3c7
@concrete: #95a5a6
@asbestos: #7f8c8d
...

Next, to use this file in my project, I imported it into my bootstrap.less copy AFTER bootstrap’s own variables.less file, so it acts to overwrite those variables but BEFORE any less files containing styles which make use of those variables:

// Core variables and mixins
@import "bootstrap/variables.less";
@import "bootstrap/mixins.less";
//
// my custom variables
@import "variables.less";
//
// Reset and dependencies
@import "bootstrap/normalize.less";

Lastly, ensure that my bootstrap.less copy (rather than the bootstrap/bootstrap.less) file is imported in my app.less file which defines all styles for this project:

app.less

@import "bootstrap";

Workflow

Changing variables (e.g. colors)

As all variables are commented out, I am using the standard Bootstrap variables as defined in bootstrap/variables.less. However, if I want to change these I can do so in my variables.less copy bu uncommenting out the desired variables, and changing it to what I want it to be:

variables.less (copy)

...
// @navbar-default-color: #777;
@navbar-default-bg: @orange;
...

I can also make site wide changes by changing Bootstrap’s global variables such as @brand-primary:

@brand-primary: @belize-hole;

Bring in components when required

I’d commented out all components in my bootstrap.less copy, so I need to bring them in as I incorporate them into my project. So, if I add a navbar to my layout, I want to uncomment @import “bootstrap/navbar.less”, re-compile my styles, and this component is available to the project. This helps to keep my CSS light.

I can also rewrite styles if needed by adding them from bootstrap/bootstrap.less to this file (after all the importing):

boostrap.less (copy)

// Utility classes
@import "bootstrap/utilities.less";
@import "bootstrap/responsive-utilities.less";
//
// altered classes:
//
// Interactive list items
//
// Use anchor or button elements instead of `li`s or `div`s to create interactive items.
// Includes an extra `.active` modifier class for showing selected items.
//
a.list-group-item,
button.list-group-item {
    // color: @list-group-link-color;
    //
    // .list-group-item-heading {
    // color: @list-group-link-heading-color;
    // }
    //
    // Hover state
    &:hover,
    &:focus {
        // text-decoration: none;
        // color: @list-group-link-hover-color;
        // background-color: @list-group-hover-bg;
        //
        h4 {
            color: @orange;
        }
    }
}

Conclusion

So far so good 🙂