Advanced Bootstrap Development Tools

Matt Lambert

December 2015

In this article by Matt Lambert, author of the book Bootstrap Site Blueprints Volume II, Although Bootstrap is the most popular CSS framework on the block, which polarizes web developers of all skill levels, one of the most heard-of complaints against it is that it's too large and hard to use. The primary goal of this book is to give you an advanced set of tools to make building websites with Bootstrap easier and even enjoyable. We'll start out by showing you how to create a development environment and workflow that is easy to set up and reuse in all your Bootstrap projects. From there on, we'll tackle a number of common website designs to get you comfortable with the advanced techniques. Finally, we'll include some JavaScript libraries and really take our Bootstrap projects to the next level. Sit back, fire up your code editor of choice, and get ready to dive into some advanced Bootstrap blueprints.

In this article, you'll learn:

  • How to create a development environment with Harp.js
  • How to run a localhost server with Node.js to preview your project
  • How to write templates with EJS and use variables and partials
  • How to set up your theme with less in the most efficient manner
  • How to compile your project for production

(For more resources related to this topic, see here.)

Theming is hard!@

I won't lie. Bootstrap theming can be really challenging. There is a large library of components that take some time to understand, and learning the best ways to customize them also takes time. But what if there was an easier way? I'm happy to say that I've designed a workflow using some modern frontend development tools that make it much easier to work with Bootstrap. The problem with frontend languages such as HTML and CSS is that they lack some core programming features, such as variables and includes. Thanks to tools such as less for CSS and Harp.js for templating, these missing features are now available for building static websites.

Harp.js – the static web server with built-in preprocessing

The title says it all, and it is taken from the official http://harpjs.com/ website. Harp is an open source project from some of the same people who brought us PhoneGap, and it is my tool of choice for any static website project I work on. Why is Harp so great? Here are just a few reasons. It includes automatic preprocessing of languages such as EJS, Jade, Markdown, CoffeeScript, Less, Sass, and Stylus.

  • Harp converts the aforementioned languages into vanilla HTML, CSS, and JavaScript and feeds it to the browser
  • It allows powerful templating through the use of common layouts and partials or includes for PHP people
  • It includes a lightweight web server that compiles your code in the background for quick and easy testing
  • It passes in custom metadata through JSON to save your time
  • It compiles all of your code into production-friendly files that you can deploy on your server

Creating a development environment

Everything that I outlined earlier basically creates a development environment for your Bootstrap websites. The advantage of using a development environment is that you can use tools such as Harp to make your website development faster and easier. It provides you with a working copy on your local computer, and you can use that copy to develop your projects. When you're done, you can compile it into the production version and deploy it on the Internet. It's a good idea to get into the habit of creating a development environment because it's a better coding practice and makes it easier to maintain your project in the future. This is because the production code is totally separate. Running a localhost server for testing also allows you to build new features without having to worry about negatively affecting your live production website.

Installing Node.js

The web server that is built into Harp runs on Node.js. Therefore, you will need to install Node on your computer before you can set up Harp. If you don't have Node already installed, head over to the following link to download the version you need:

http://nodejs.org/download/

Once you've downloaded and installed Node, you'll have to open and use the command line to test the installation. If you're on a Mac, I'd recommend that you use the terminal or an app such as iTerm to access the command line. If you're working on Windows, you can use Cygwin. Once you've opened up your command-line app, type in the following line:

$ node -v

If you have installed Node correctly, the number of the version you have installed should be printed on the terminal. You should see something like this:

$ v0.10.33

Great! Now we can move on to installing Harp.

Installing Harp.js

Actually, setting up Harp.js is really easy. If you have closed your terminal, open it again. Insert this command if you're on a Mac:

$ sudo npm install -g harp

If you're on Windows, use the following command:

$ npm install -g harp

After you execute this command, you should see a bunch of packages being installed in the terminal window. Once everything stops loading, Harp is installed. To verify that it has worked, enter the following in the terminal and hit Enter:

$ harp version

This should give you the version number, which means that Harp was successfully installed.

Since less preprocessing is included with Harp, we don't need to install anything special to use less. This is great news, because we don't need to rely on less.js or a standalone compiler app. Once we compile our Harp project and run the web server, any changes to less files will be picked up automatically. For now, just celebrate, and we'll cover compiling less in more detail a little later.

Setting up a boilerplate project

For the rest of this article, I'm going to teach you how to set up a Bootstrap boilerplate project in Harp. Moving forward, this boilerplate will be the basis for all the projects in the book. One of the great things about Harp is that you can simply copy and paste a project to create a new instance of it on your local machine. There are also some other commands that you can run to generate project scaffolding, and I welcome you to check them out at http://harpjs.com/docs/. However, for this book, we aren't going to take any shortcuts, and I'm going to show you how to manually set up a project. The best practice is to do it the hard way first so that you learn how it works. This will save you a headache down the road if you are troubleshooting a problem. The first thing you should do is navigate to a directory on your computer where you want to store your project. In the folder, create the following files and directories. For the time being, just leave the .json and .ejs files blank. We'll fill them in a little later.

Note that there is a project boilerplate available for download or forking from GitHub at https://github.com/cardeo/booterator.

This is the root of our project, and here we'll find everything at a high level:

  • /css: This directory will contain all our custom CSS and the Bootstrap framework CSS files.
  • /fonts: This directory will be for holding any web fonts or icon web fonts. The directory isn't totally necessary, but I always include Font Awesome with all my projects so that I have an icon library to pull from.
  • /img: This directory will hold all the images for the project. For the boilerplate, we won't actually need any images, but we're setting this up for future projects too.
  • /js: This directory will hold any custom libraries and the Bootstrap framework's JavaScript file.
  • /partial: This directory will hold the pieces of code that we want to reuse in our templates, such as our header and footer.
  • _data.json: This is the file in which we will define any metadata that we want to use in our template. An example of this could be the page title for each web page.
  • _harp.json: This is a file for setting global properties, such as the title of the website, which is used on all pages.
  • _layout.ejs: This file is the scaffolding for our page. It includes the <head> and <body> sections of our document. At the very least, you need one layout in every Harp project. It is possible to have multiple layouts if you want to load in JavaScript libraries to only some pages.
  • index.ejs: This file holds the actual code for our boilerplate home page. This is the body or content of the page minus the wrapping template pieces that are held in _layout.ejs.

The Embedded JavaScript (EJS) template language is very similar to HTML and is therefore really easy to grasp. The advantage of using EJS is that it allows the use of things such as variables.

Setting up the CSS

Now that the root of our project is set up, let's set up the subdirectories. We'll start with the CSS directory by adding the following files. Now would be a good time to download the latest version of Bootstrap from http://getbootstrap.com if you haven't done so already. Again, just leave theme.less blank for now.

Within the components directory, create a Less file and name it _variables.less. Leave this file blank for the time being.

Starting a file with an underscore in Harp will mark it as a template file that should not be a straight copy to the production directory. It is file that should be compiled into another to create a full HTML page or CSS style sheet.

Let's quickly walk through the files in the /css directory:

  • bootstrap.min.css: This is the Bootstrap CSS framework. When you download the Bootstrap package, there are a number of other CSS files. We don't need any of those files; we only need the minified version of the framework.
  • /components: This is a directory for storing Bootstrap component's less files. If you are customizing a Bootstrap component, you should create a less file for it and enter the custom CSS.
  • theme.less: This is the master file for our CSS. All our components should be imported into this file so that upon compilation, it will be a single theme.css file for our project.

Setting up the fonts

Bootstrap comes with Glyphicons out of the box, which is fine. I, however, prefer to use font awesome because their license is more flexible. To add font awesome to your project, head to http://fortawesome.io and download the package. Unzip it into your computer after downloading and copy the contents of the /fonts directory to your project's /fonts directory. Next, go the /css folder and copy font-awesome.min.css to your project's /css directory. For now, that's all you need to do; we'll hook up everything else a little later. The /fonts directory should now look like this:

Setting up the JavaScript

For our boilerplate, all that we need to do is copy bootstrap.min.js to our /js directory. Like the Bootstrap CSS, there are a few JavaScript files included in the download package. You can ignore the other files as we won't need them.

Setting up the partials

The last directory that we need to set up is our partials. If you come from the PHP world, note that partials are includes. They are little snippets of code that are reused across all or many of your pages, such as your header, footer, and navigation. Partials are one of the best features of Harp because you can update these template pieces in one place when changes occur, instead of updating on every page! For now, create two files in your /partial directory, called _header.ejs and _footer.ejs.

Now that we've finished setting up the basic structure of our project, we can move on to actually filling in some code for our .json and .ejs files.

Setting up _harp.json

I'm going to start with _harp.json before _data.json. This is because the first file deals with the global settings for our project. In this case, we're going to use _harp.json to set up a global variable that will map to the website name for our project. Later on, we'll insert this variable into our layout so that it appears on every page of our website. Enter the following code and save it:

{

  "globals": {

    "siteTitle": "My Bootstrap Boilerplate"

  }

}

What we've done here is set up a global variable named siteTitle and set its value to My Bootstrap Boilerplate. Once we insert this variable into our layout, the title will be shown on every page of our project.

This is only a fraction of what you can do here. Check out http://harpjs.com/docs/development/globals to learn more about globals.

Configuring _data.json

If _harp.json applies to all the pages in our website, _data.json contains page-specific data for our project. In this case, I'm going to set up a variable that can be used to insert the page name for each page of my project:

{

  "index": {

    "pageTitle": "Home"

  }

}

Here's how this data works:

  • The index refers to the name of my ejs template that I want to target. Currently, we have only one, called index.ejs.
  • The pageTitle is a variable I created for the title of each of my pages. We'll need to insert this variable into the layout later on.
  • Finally, I entered a value of Home for my variable.

Again, there is more that you can do with metadata in Harp, but at this point, this is all that we need. To learn more about Harp metadata, visit http://harpjs.com/docs/development/metadata.

Setting up the layout

As I mentioned previously, _layout.ejs is the wrapper file for my index.ejs page template. Layouts can be reused, and pages will always default to using _layout.ejs unless you tell them otherwise. If you want to create a second layout for use on a specific page, you simply have to create new file called something like _layout-two.ejs. Then, in your _data.json file, you have to add a second line to your template declaration that points to the new layout:

{

  "index": {

    "pageTitle": "Home",

    "layout": "_layout-two"

  }

}

When you're working with your .json file, file extensions are not required.

Now, that's an example of how to use multiple layouts. For our boilerplate, we'll need only one layout. A layout file can be written in mostly normal HTML, but we need to insert a yield property to tell Harp where to insert the content from the page file (index.ejs). We also need to insert the variables that we defined in _harp.json and _data.json. Open up your _layout.ejs file in the root of the project and insert the following <head> code:

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="utf-8">

  <meta http-equiv="X-UA-Compatible" content="IE=edge">

  <meta name="viewport" content="width=device-width, initial-
    scale=1">

  <title><%- pageTitle %> | <%- siteTitle %></title>

  <link rel="stylesheet" type="text/css" 
    href="css/bootstrap.min.css">

  <link rel="stylesheet" type="text/css" href="css/font-
    awesome.min.css">

  <link rel="stylesheet" type="text/css" href="css/theme.css">

  <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements 
  and media queries -->

  <!-- WARNING: Respond.js doesn't work if you view the page via 
    file:// -->

  <!--[if lt IE 9]>

    <script 
    src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js">
    </script>

    <script 
    src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js">
    </script>

  <![endif]-->

</head>

The preceding code is the standard Bootstrap header with a some small changes:

  • Always load the Bootstrap CSS first, as you may want to overwrite something in your theme
  • Include the font awesome CSS file so that you can use the icons in your projects
  • Insert your theme CSS file, which will contain all your custom CSS

Make sure you use the CSS extension here for all your files. Once theme.less is compiled, it will turn into theme.css. Therefore, we need to name it correctly so that it's picked up by the browser.

Inserting the variables

If you look at the <title> tag in <head>, you'll notice a couple of variables. These are the two variables that we set up in _harp.json and _data.json. On compiling, pageTitle and siteTitle will be inserted into the page layout. Depending on the page, the proper pageTitle variable will be inserted.

Now that we have the <head> element of our layout set up, let's enter the code for <body>:

<body>

  <%- partial("partial/_header") %>

  <%- yield %>

  <%- partial("partial/_footer") %>

  <!-- javascript //-->

  <script 
    src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

  <script src="js/bootstrap.min.js" 
    type="text/javascript"></script>

</body>

</html>

Now, the <body> code is going to look a little different from what we are used to with Bootstrap and HTML. Let me go through each part:

  • The header partial will include our header code, which we haven't set up yet.
  • The yield tag is the marker for loading in the contents of our pages. In this case, it will load index.ejs.
  • Like the header, the footer partial will be included wherever the tag is inserted.
  • At the bottom, I've included jQuery and a link to the Bootstrap JavaScript framework that is in our project.

Setting up the header

To set up the header, we need to edit the _header.ejs file that we created earlier in this article. Head to the /partial directory and open up _header.ejs. Then paste the following in the the Bootstrap navbar code:

<nav class="navbar navbar-default" role="navigation">

  <div class="container-fluid">

    <div class="navbar-header">

      <button type="button" class="navbar-toggle collapsed" data-
        toggle="collapse" data-target="#navbar1">

        <span class="sr-only">Toggle navigation</span>

        <span class="icon-bar"></span>

        <span class="icon-bar"></span>

        <span class="icon-bar"></span>

      </button>

     <a href="index.html" class="navbar-brand"><%- siteTitle 
       %></a>

    </div>

    <div class="collapse navbar-collapse" id="navbar1">

      <ul class="nav navbar-nav">

       <li><a href="index.html">Home</a></li>

      </ul>

    </div>

  </div>

</nav>

The code for the header is pretty straightforward, except for one thing; it's your standard Bootstrap navbar. One more thing that is different is that I've used the siteTitle global variable again so that siteTitle will automatically be inserted into the navbar brand for each page upon compilation. This is a simple example of how you can reuse variables in your templates.

Setting up the footer

Next, open up the _footer.ejs file, which is in the same /partial directory. Here, we'll just want to insert some super simple footer code that can be used as a placeholder. Notice how I'm wrapping my footer in a container-fluid class. It's a good idea to componentize the pieces of your theme so that they are easily interchangeable and don't rely on markup in other components or partials:

<div class="container-fluid">

  <div class="row">

    <div class="col-lg-12">

      &copy; 2015 Matt Lambert

    </div>

  </div>

</div>

As you can see, it is super simple! The last template or HTML/EJS work that we need to do is set up the body of our page, which lives inside of index.ejs. For our boilerplate, let's create a super simple piece of page content:

<div class="container-fluid">

  <div class="row">

    <div class="col-lg-12">

      <h1>Bootstrap Boilerplate</h1>

      <p>This is a Bootstrap starter template built with Harp, 
        Less, CSS, EJS, and HTML</p>

      <p>Made in Vancouver by <a 
        href="http://twitter.com/cardeo">@cardeo</a></p>

   </div>

  </div>

</div>

This chunk of code should be self-explanatory. I've purposely kept it simple so that you can easily see where the lines between page templates and partials are. Now that the base of our project is set up, let's compile and preview it!

Compiling for the first time

Now that our initial project is set up, it's time to compile it and test it out to make sure that everything works. When we compile our project for the first time, Harp creates a directory in the root of our project, called /www. Within this directory, it will dump all the compiled HTML, CSS, and JavaScript files. When you are ready to publish your project, simply upload the contents of this directory to your server. See how simple and clean it is? Your development and production files live in the same project directory but are totally separate.

You should never manually edit any of the files in your /www directory. If you do, on the next compilation, any changes you make will be overwritten.

The compilation of your project is done from the command line or terminal app. If you have closed it, open it again and navigate to your project directory. Once you get there, run the following command:

$ harp compile

If all goes well, a new line should appear in the terminal. If there is an error, Harp will give you an error message with a clue to the problem. Let's assume that all has gone well and everything has worked fine. Go to your project directory and look for the /www directory. If it's there, it means that the compile worked fine.

Running the local server

The next thing you'll want to do is actually test your project in a browser. To do this, we can use Harp's built-in web server to test the website locally. This is a great feature because you can test drive your project locally without having to upload it to the Internet. To fire up the server, enter the following command in the terminal from your project directory:

$ harp server --port 9000

This will deploy your project locally on port 9000. Open up a web browser and go to http://localhost:9000 to view the website.

Your page should look like this:

Now that you have the server running, you can take advantage of one of Harp's other awesome features. Every time you make a change to a template file, CSS file, and so on, you don't have to recompile your project. You can simply save the file and refresh the browser, and you'll see the updated version. This will save you so much time! One thing to remember, however, is to make sure you should compile when you're done so that the changes are applied to the /www directory.

I encourage you to memorize the preceding commands, but if you want something easier to remember, you can use $ harp server www to run the local server. The only problem with this command, however, is that I've found it to be a bit buggy. It will start the server but updates to templates in the background won't always be picked up. A more reliable method is to manually declare which port to use when you fire up the server. Now that our project is all set up and running, it's time to set up our less configuration to theme our project.

Configuring less

A great advantage of using Harp is that it has a built-in less compiler. When you run the $ harp compile command, it compiles both your .ejs templates and your .less files into regular HTML and CSS. This is much easier than using something like less.js, which you would have to remove from production. When you're compiling your project for the first time, ensure that you include some code inside your theme.less file. Otherwise, theme.css will not be written.

Defining your less variables

Head back to the css/components directory that you created earlier and open up the _variables.less file. Within this file, we'll configure what I call global CSS variables. Moreover, within this file, we'll define only those variables that apply across our entire website. Component-specific variables have no place in this file. I know that some developers like to have one big file for variables, but I prefer to keep the component-specific ones out in their own less files. We will see more on that later, when we dive into custom components. For now, let's start pasting the following code in _variables.less.

Colors

Let's start by inserting some color variables that can be used throughout all our Bootstrap projects:

@black: #000;
@dark-grey: #333;
@grey: #ccc;
@light-grey: #ebebeb;
@off-white: #f5f5f5;
@white: #ffffff;
@blue1: #3498db;
@blue2: #2980b9;
@red1: #e74c3c;
@red2: #c0392b;
@yellow1: #f1c40f;
@yellow2: #f39c12;
@green1: #2ecc71;
@green2: #27ae60;
@orange1: #e67e22;
@orange2: #d35400;
@aqua1: #1abc9c;
@aqua2: #16a085;
@purple1: #9b59b6;
@purple2: #8e44ad;
@navy1: #34495e;
@navy2: #2c3e50;

As you'll see, I like to define a fairly large color palette. But this doesn't mean that all my projects will use all of these colors. However, like a good typography, it's a good idea over time to develop a library of colors that work well together. We can then easily include them in all our projects so that we have colors that work well together right at our fingertips. When you are diving deep into theming, this is really valuable because you don't have to go and look for a new color palette with every new theme. You already have a collection of colors that you can pull from, which will speed up your theming process.

Backgrounds

Lets add the background variables:

@primary-background: @white;
@secondary-background: @off-white;
@third-background: @light-grey;
@fourth-background: @grey;
@inverse-background: @dark-grey;

The following is my boilerplate for backgrounds. Note how these colors use a variable name for their value and not a hexadecimal value. The reason that this is done is to speed up theming. Instead of having to change a color in two places, we only have to change it in one, and then it inherits throughout our other variables. Here are a few more key points about backgrounds.

The variable naming convention here is similar to that of Bootstrap, for consistency. This also makes it easier to remember a variable name, such as primary, as against something like white-background.

At the very least, you should have a primary, a secondary, and an inverse background. I like to include a couple more, but feel free to scale this back a bit if it makes it easier for you.

Text

As with our backgrounds, we are following the Bootstrap naming conventions for our text colors:

@primary-text: @dark-grey;
@light-text: @light-grey;
@loud-text: @black;
@inverse-text: @white;
@heading-text: @dark-grey;

Consistency is the key as it makes it easier to remember variable names. It is critical when you're dealing with a large framework that you make things as easy as possible to remember. Again, make sure you use color variables for the values here and not actual hexadecimal numbers.

Links

Defining the link colors is pretty straightforward:

@primary-link-color: @blue1;
@primary-link-color-hover: @blue2;

One thing that I'll point out here is that this is the first example where you'll see why you should have at least two versions of every color that you use in your palette. Things such as hover states usually require a base color and a darker or lighter version of the same color to indicate a change in hovering. You may want to expand this section to include a secondary or even third-link color variation.

Borders

The border variable is the first place where you'll see some values that aren't only color-based:

@border-color: @light-grey;
@border-size: 1px;
@border-type: solid;
@border-focus: @grey;
@secondary-border-color: @blue1;

In this case, you should always set your size to 1px. The reason for this is that you can use a less operation like the following to increase the size of your border. Starting from 1px makes your operations simple and easy to follow for other developers who may be maintaining or editing your code:

.good-class {

  border-size: (@border-size + 1);

}

 

.bad-class {

  border-size: 2px;

}

Never use pixel values in any of your custom CSS! You would want to use variables so that you can make any units relative and, therefore, controlled by a variable. This will allow you to quickly spin up a new theme by only editing the variable's less file.

Typography

@body-copy: "Helvetica Neue", helvetica, arial, verdana, sans-serif;
@heading-copy: "Helvetica Neue", helvetica, arial, verdana, sans-serif;
@base-font-size: 14px;
@font-size: 1em;
@base-line-height: 1.5;

When I set up typography for a theme, I like to follow a few simple rules:

  • Make sure you define at least a body and a heading copy variable.
  • Set the base font size as a pixel value.
  • Set the actual font size to 1em and use this variable throughout your custom CSS. In this way, you will be using a relative value that is easier with operations. This is exactly the same as the preceding border example.
  • I personally prefer to reset Bootstrap's line-height to 1.5 for easier math.

Layout

The only layout variables that you should be setting in your globals are margin and padding:

@margin: 1em;
@padding: 1em;

Both should be set to 1em for easy relative operations. This follows the same unit of measurement patterns set with borders and typography.

Mixins

The other element that I recommend including in your global less file is mixins. In my opinion, there are only two of them (and maybe only one) that you definitely need to include to speed up your Bootstrap theming.

Border radius

The border radius is by far the most important as it is used a ton through Bootstrap components:

.round-corners (@radius: 2px) {
  -moz-border-radius: @radius;
  -ms-border-radius: @radius;
  border-radius: @radius;
}

Make sure you set this up and use it for everything. If you are thorough, you can change the border radius of all elements in one place. An example of this would look like the following:

.btn {

  /* fill in the rest of the styles here */

  .round-corners;

}

Now, if I change my @radius value to a different pixel amount, it will inherit down to my button corners. Do this for all your Bootstrap components!

Animations and transitions

Another property that I use heavily in my themes is the animations or transitions property:

.transition (@transition: background .1s linear) {
  -moz-transition: @transition;
  -webkit-transition: @transition;
  transition: background @transition;
}

I find that a little transition, when added, can add a lot to a UI. Instead of defining this from the ground up on every component, use this simple mixin. It will speed up your theming time and also ensure that transitions are consistent across your entire theme. That's just good design and coding. Here's an example that shows you how to apply to a button:

.btn {

  /* fill in the rest of the styles here */

  .round-corners;

  .transition;

}

This completes your _variables.less file. Save the file and close it. Next, we'll cover the setup of the master theme file for our project.

Setting up your theme

Now that we've set up our variables file, we need to set up the master theme that we'll import it into. The master theme file, or theme.less, is the primary file that we will link in the <head> section of our pages. I've organized the theme using the Scalable and Modular CSS (SMACSS) system. Using a modular approach while coding the CSS will make the job easier and the code more maintainable over time.

Summary

In this article, you learned how to—and why it's important to—build a development environment with Harp.js. You also learned how to write templates in EJS using variables and partials. Lastly, you got to know how to set up your theme with less and compile your project for production.

Resources for Article:


Further resources on this subject:


You've been reading an excerpt of:

Bootstrap Site Blueprints Volume II

Explore Title