Loading...
Menu

Make Bootstrap Themes

 

Preface

Bootstrap perhaps is the most popular frontend framework for developing mobile first projects on the web in recent years, its repository on github gets more than 100 thousands stars. Millions of websites are using it not only because it is easy to learn and use but the flexibility of customization. You can quickly start building a prototype or minimum viable product on the web by just including its 2 files (one is a CSS file and the other is a Javascript file), then do some customization later to make your web product stand out and look more professional.

In this book, we’ll focus on the customization part – build your own Bootstrap theme. At the time of writing this book, Bootstrap 4 is still in its alpha version, by “Bootstrap” here we are referring to Bootstrap 3. We will start with preparing a development workbench, and introducing Less (a CSS pre-processor Bootstrap uses), then walk through Bootstrap’s source code which will help us first get familiar with its code structure and later build themes by reusing it. Moreover, we will learn how to make additional styles and use plugins to polish our themes. Lastly we will touch on Bootstrap 4 a little and see how to use and customize it.

To learn something new, you need to practice, sometimes a lot. In this book I am following the “learn by doing” methodology: in most of chapters, I’ll put a “Practice” section. Usually those sections ask you to go to this book’s code repository (see the next section), open some files and learn the code inside. Some chapters will also contain a “Challenge” section, which will suggest you to make changes to the code we learned in that chapter. Those challenges usually are not hard to solve, and there for you to get your hands dirty, and help you have a better understanding.

Prerequisites

This book is not an introduction to how to use Bootstrap, nor is it for learning the basics of HTML, CSS and Javascript, there are already plenty of awesome books on such fields. In general, I will assume that you have some working knowledge of HTML, CSS and using Bootstrap, for example you should be able to understand the following code:

{color:#295646;}
bc. {color:#295646;}<div class="container container-fluid">
    <div class="row">
        <div class="col-xs-12 col-sm-10 col-md-8">
            some article content ...
        </div>
    </div>
</div>
pre

You should know what
bc. {color:#295646;}container,
bc. {color:#295646;}col-xs-12 ,
bc. {color:#295646;}col-sm-10 classes mean in Bootstrap. If not, I suggest reading through some tutorials about using Bootstrap before coming back to this book. If you are already familiar with the basis of HTML, CSS and Bootstrap usage, and want to go further to customize its theme, or even sell your own theme in the marketplaces, this is the book for you.

Code examples

Supplemental materials (code examples, exercises, etc) are available for download at: https://github.com/bofeng/make-bootstrap-themes

You should check the license before using the code examples and documentation. Usually it will not be a problem. Asking me for permission is not needed, but I do appreciate if you could include an attribution when using it, something like “From the book Make Bootstrap Themes By Bo Feng” would be great.

Feedback

If you find errors in this book or the code example repository, you may create an issue ticket on the Github repository page:

https://github.com/bofeng/make-bootstrap-themes/issues

Acknowledgments

This book would not have been possible without the help and support of many others. Thank you to my reviewer, Sabrina Wagner, for your time and perceptive feedback. Thanks also to Xin Ge for his help with designing this great book cover.

And many thanks are owed to my dear friends Melora Loffreto, Devon Loffreto and my girlfriend Sherry. They put up with me throughout this process and provided moral support and guidance. Thank you.

Chapter 1 – Setup Workbench

First things first, let’s get our workbench ready. We need 4 items:

#
bc. {color:#295646;}http-server : it will help us easily setup a local web server.

#
bc. {color:#295646;}less : we use it to compile code written in Less to plain CSS, Bootstrap uses Less for generating its final CSS file. When we make our own themes, we will also write some code in Less, then use the
bc. {color:#295646;}lessc command to convert it to plain CSS. Don’t worry if you are not familiar with Less for now, we will learn more about it in chapter 2.

#
bc. {color:#295646;}Bootstrap source code : we will learn how Bootstrap organizes its code and this will teach us how to follow its structure and utilize its code to make our themes.

#
bc. {color:#295646;}theme-styles.html : we need to make a web page to view all commonly used Bootstrap components (typography, buttons, panels, alerts, etc). We will have all of them on one page so that we can easily see the changes when we make some customizations for our themes.

The first two items above are software applications, and we can install them through
bc. {color:#295646;}npm.
bc. {color:#295646;}npm comes along with the
bc. {color:#295646;}Node.js installation package, so we will first install
bc. {color:#295646;}Node.js. The third and fourth items are already included in the code repository for this book ( https://github.com/bofeng/make-bootstrap-themes ). You can clone it:

{color:#295646;}
bc. {color:#295646;}$ git clone https://github.com/bofeng/make-bootstrap-themes.git
pre

Or you can download the zipped file at following address, then unzip it:

https://github.com/bofeng/make-bootstrap-themes/archive/master.zip

Once you get it, in the folder you should be able to see the following files:

For writing convenience, in the following chapters, when we mention in the code repository or code repository folder, we are referring to this make-bootstrap-themes folder.

1.1 Install Node.js & npm

We will cover the installation both for Windows and macOS. Fortunately the process is quite straightforward using an installer package.

Windows

Installation steps:

  1. Go to the Node.js website: https://nodejs.org
  1. On the home page, click the LTS version to download the installation file (ends with .msi) Depending on the version of Windows you use, you may see the buttons below slightly different from mine on the website.
  1. Double click this .msi file to run the installer and follow the prompts in it. You may need to first accept the license agreement, then click the “Next” buttons several times, during which you may use the default installation settings.

Now let’s test if it works: go to any folder, (for example, your Download folder or the code repository folder make-bootstrap-themes), hold the shift key and right-click your mouse. In the pop-up menu, click Open command window here :

A command-line window will be opened up, then type two commands: use
bc. {color:#295646;}node -v first to see the Node.js version you have installed; then type
bc. {color:#295646;}npm -v to see the
bc. {color:#295646;}npm version. (Notice that
bc. {color:#295646;}npm is installed along with Node.js, and we will use
bc. {color:#295646;}npm to install other applications later).

Tips: When you type the
bc. {color:#295646;}node and
bc. {color:#295646;}npm commands in the command window, if an error like “command not found” shows up, try restarting your computer then running the commands again.

macOS

If you are using a Mac with macOS, the process is quite similar:

  1. Go to the Node.js website: https://nodejs.org
  1. On the home page, you will see a download button like below. At the time of writing this book, the Long-Term-Support stable version is 6.9.2, click v6.9.2 LTS button and a node-v6.9.2.pkg file will be downloaded.
  1. Double click this node-v6.9.2.pkg and finish the installation.

To test if it works, go to “Applications > Utilities“, open the “Terminal” application, and then type
bc. {color:#295646;}node -v and
bc. {color:#295646;}npm -v. You should be able to see the version they print out like below (depends on the version you installed, you may see a different version number):

{color:#295646;}
bc. {color:#295646;}$ node -v
v6.9.2
$ npm -v
3.10.9
pre

If you used this “Terminal” application a lot, and are familiar with many Linux/Unix commands like
bc. {color:#295646;}cd,
bc. {color:#295646;}ls, etc, you may jump to the Install http-server and Less section; if not, let’s do one more step, it will help you quickly open a “Terminal” inside one folder:

  1. Open “System Preferences”, and go to “Keyboard” > “Shortcuts”;
  1. Click “Services” on the left, then scroll down a little to the “Files and Folders” section. Check “New Terminal at Folder”, then close the “System Preferences” window;

Let’s test it. Go find any folder (for example, your Desktop folder or the code repository folder make-bootstrap-themes), right-click on the folder, and in the pop-up menu, choose “New Terminal at Folder”. A Terminal will show up and its current directory is the folder you right-clicked, we will use this several times in the following chapters.

For writing convenience, in later content when we mention Open a command/terminal window at folder xxx, it means that, for a Windows user, go into this folder xxx, hold the shift key and right-click the mouse, and in the pop-up menu click “Open command window here”; for a macOS user, right-click on this folder xxx, and in the popup menu, click “New Terminal at Folder”.

1.2 Install http-server and Less

Now that you have
bc. {color:#295646;}npm installed, we will now install
bc. {color:#295646;}http-server and
bc. {color:#295646;}less through one command. For Windows users, open a command/terminal window at any folder, then type:

{color:#295646;}
bc. {color:#295646;}$ npm install http-server less -g
pre

It may take several seconds, when it is done, we will have both
bc. {color:#295646;}http-server and
bc. {color:#295646;}less installed. Now let’s test if they work:

Test http-server

Let’s create a folder named test first, then create an index.html file under it, the file content could be really simple:

{color:#295646;}
bc. {color:#295646;}<html>
   <body>
        Test http server
    </body>
</html>
pre

For Windows users, open a command window at this test folder, then simply type
bc. {color:#295646;}http-server. The system may show a prompt like below:

Click Allow access to continue, then the command window will show some information like this:

{color:#295646;}
bc. {color:#295646;}Starting up http-server, serving ./
Available on:
  http://127.0.0.1:8080
...
pre

Since we just created an index.html file at this folder, and the http-server is serving this folder, now if we use browser to visit
bc. {color:#295646;}http://127.0.0.1:8080, the browser will open index.html file by default, we should be able to see the file content in the browser:

For macOS users, the process is quite similar. Open a terminal window at this test folder, then type
bc. {color:#295646;}http-server to start a web server, some information will show up:

{color:#295646;}
bc. {color:#295646;}$ http-server
Starting up http-server, serving ./
Available on:
  http://127.0.0.1:8080
  ...
pre

Now use a browser to visit
bc. {color:#295646;}http://127.0.0.1:8080, you should be able to see the page content.

Tips

When you run the
bc. {color:#295646;}http-server command in the command/terminal window, if it shows an error message like “Error: listen EADDRINUSE 0.0.0.0:8080”, this means the port number 8080 is taken by some other application, you can find the application to terminate it first, or, you can use a different port number by using the
bc. {color:#295646;}-p option, for example:

{color:#295646;}
bc. {color:#295646;}$ http-server -p 4545
pre

The above command is using the port number 4545, but you can use other random numbers which roughly range from 2000 to 65,000. If no error shows up, visit
bc. {color:#295646;}http://127.0.0.1:4545, you should be able to see the page content.

Test less

The above
bc. {color:#295646;}npm install http-server less -g command also installs Less, a CSS pre-processor Bootstrap is using. What Less does basically is compiling the code written in Less syntax to plain CSS. Now let’s do a quick test to see if it works, don’t worry if you don’t understand the syntax of the following code, in chapter 2 we will learn more.

1) Create a
bc. {color:#295646;}test.less file at your test folder with the following code:

{color:#295646;}
bc. {color:#295646;}@color: #ff6600;
.mark {
    color: @color;
}
pre

2) Open a command/terminal window at this test folder, then use
bc. {color:#295646;}lessc command below to compile it:

{color:#295646;}
bc. {color:#295646;}$ lessc test.less test.css
pre

This will compile the Less code to plain CSS and save it in test.css file. Notice here we use
bc. {color:#295646;}lessc (there is an extra
bc. {color:#295646;}c at the end), which stands for less compiler.

3) Open this test.css file, it should contain the following code:

{color:#295646;}
bc. {color:#295646;}.mark {
    color: #ff6600;
}
pre

If you are able to see the code in test.css, you have successfully installed Less.

1.3 Get Bootstrap Source Code

Our theme-customization work will reuse some code from Bootstrap, so here we need to get its source code. If you downloaded the code repository for this book at the beginning of this chapter, it already includes the bootstrap-3.3.7 folder, so you are all set. Or if you want to download it separately, go to the following url to download the zip file and then unzip it:

https://github.com/twbs/bootstrap/archive/v3.3.7.zip

After unzipping it, you will have a [_ bootstrap-3.3.7_] folder. No matter which way you choose, under this folder you should be able to see a list of files like this:

1.4 theme-styles.html

When we are making a Bootstrap theme, a HTML page contains all the most commonly used Bootstrap components, like navbar, pager, panels, etc, which will help us quickly preview the changes and guide us for further customizations.

Here we name it theme-styles.html, and it contains the following components:

  • Typography

  • h1 to h6

  • p, em, strong, link (a), small, big, pre, code

  • blockquote

  • contextual text: text-muted, text-warning, text-info, text-danger, etc.

  • Navigation bar

  • navbar-default

  • navbar-inverse

  • Buttons
  • Forms
  • Tables
  • Images
  • Tabs & Pills
  • Breadcrumbs
  • Paginations
  • Pagers
  • Alerts

  • alert-warning, alert-danger, alert-success, alert-info

  • Labels & Badges
  • Media object
  • Progress bar
  • List groups
  • Panels
  • Wells
  • Modals
  • Popovers
  • Tooltips
  • Jumbotron
  • Carousel

It’s a lot but don’t worry, I already put this theme-styles.html in the code repository. You can find it under the chapter1 folder. Again, if you still didn’t download the code repo, please do it.

Now let’s preview how this page looks.

Practice

  1. Get the code repository folder make-bootstrap-themes from https://github.com/bofeng/make-bootstrap-themes , if you already did this in the beginning of this chapter, ignore this step.
  1. Open a command/terminal window at this make-bootstrap-themes folder;
  1. In this command/terminal window, type
    bc. {color:#295646;}http-server to start a web server.
  1. Visit http://127.0.0.1:8080/chapter1/theme-styles.html in your browser.
  1. Read the source code in the theme-styles.html file.

Below are some screenshots of the theme-styles.html page, in your browser you should be able to see all the components.

Congratulations! We have completed setting up our workbench! Before we do the theme customizations part, we need to learn more about Less and Bootstrap’s code structure, which will be included in the next 2 chapters.

Chapter 2 – Introduction to Less

Less is a CSS pre-processor which allows us to make CSS more maintainable and extendable. Currently there are 2 popular CSS pre-processors – Sass and Less. The CSS part of Bootstrap 3 is written in Less. It also provides a Sass version, but you may need to download that separately. If you check Bootstrap’s source code folder bootstrap-3.3.7 which we downloaded in chapter 1.3, it already includes a folder named less, so here we will focus on introducing Less instead of Sass. While Bootstrap 4 uses Sass, in chapter 5 we will take a glance at Bootstrap 4 and learn more on Sass.

In this chapter we will go through some commonly used features of Less to get us prepared for the next customization step. If you are already familiar with Less, you can skip this chapter and move on to the next.

2.1 Variable

The “variable” feature allow us to define a variable then use it everywhere. If we want to change its value, we only need to do it in one place.

{color:#295646;}
bc. {color:#295646;}@color: #ff6600;

.text-warn { color: color; } .panel-warn { color: #fff; background-color: color;
}
pre

Save it as test.less, then use the
bc. {color:#295646;}lessc command to compile it. If you forgot how to do this, go back to chapter 1.2 to review it.

{color:#295646;}
bc. {color:#295646;}$ lessc test.less test.css
pre

The above Less code will be compiled to plain CSS code and be saved in test.css file, it should have content like this:

{color:#295646;}
bc. {color:#295646;}.text-warn {
    color: #ff6600;
}
.panel-warn {
    color: #fff;
    background-color: #ff6600;
}
pre

You can see each place with the
bc. {color:#295646;}@color variable are now replaced by its definition
bc. {color:#295646;}#ff6600. This makes it more convenient to change both the text color in
bc. {color:#295646;}.text-warn class and the background color in
bc. {color:#295646;}.panel-warn class, since we only need to change one place: the definition of the
bc. {color:#295646;}@color variable. For example, say we want to change it to
bc. {color:#295646;}@ee3300:

{color:#295646;}
bc. {color:#295646;}@color: @ee3300;
…
pre

Both of the places will be replaced by this new value after compilation:

{color:#295646;}
bc. {color:#295646;}.text-warn {
    color: #ee3300;
}
.panel-warn {
    color: #fff;
    background-color: #ee3300;
}
pre

Variables can also be used in selector names, property names, URLs and
bc. {color:#295646;}@import statements. We call this variable interpolation. The format is
bc. {color:#295646;}@{variable-name} , for example:

{color:#295646;}
bc. {color:#295646;}@alertname: alert;
@staticpath: "../static";

[email protected]{alertname}-info { background-color: #339900;
}

[email protected]{alertname}-warn { background-color: #ff6600;
}

.thumbup { background: url(“@{staticpath}/img/thumbup.png”);
}
pre

After compilation:

{color:#295646;}
bc. {color:#295646;}.alert-info {
    background-color: #339900;
}
.alert-warn {
    background-color: #ff6600;
}
.thumbup {
    background: url("../static/img/thumbup.png");
}
pre

In this above example, since we defined
bc. {color:#295646;}@alertname to be
bc. {color:#295646;}alert, the class name
bc. {color:#295646;}[email protected]{alertname}-info becomes
bc. {color:#295646;}.alert-info with variable interpolation.

A variable can also be overridden. If we define one variable several times, only the last one is effective:

{color:#295646;}
bc. {color:#295646;}@color: #ff6600;

.mark { color: @color;
}

@color: #339900;

.info { color: @color;
}
pre

After compilation:

{color:#295646;}
bc. {color:#295646;}.mark {
    color: #339900;
}
.info {
    color: #339900;
}
pre

We can see that although we defined the
bc. {color:#295646;}.mark class before the second definition of the variable
bc. {color:#295646;}@color, both of the classes used the color
bc. {color:#295646;}#339900, which is the later one. Thus we can tell the compilation process is basically: Less first collects all of the variables, and during this process, one variable will override another if they have the same name. Then Less replaces all the places using that variable’s value.

This actually gives us the ability to override variables defined in Bootstrap’s source file. For example, Bootstrap has a variables.less file that defines almost all of the variables it uses, including font size, color, border color, etc. Thus we can redefine those variables’ values, and after recompilation, we will have a different theme with our customized variables. We will cover this more in chapter 3.

Another thing we should notice is that Less is a superset of CSS. We can write plain CSS code in a .less file, and it will generate the same content after compilation.

Practice

  1. In this book’s code repo, go to chapter2/2.1;
  1. Open a command/terminal window at this folder, then use
    bc. {color:#295646;}lessc to compile variable.less:
    bc. {color:#295646;}$ lessc variable.less ;
  1. Compare the compiled code with the source code in variable.less .

2.2 Comment

In plain CSS we can add comments by using
bc. {color:#295646;}/* … */. This is not very convenient when writing single-line comments. In Less we can use
bc. {color:#295646;}// to write single-line comments:

{color:#295646;}
bc. {color:#295646;}/*
    Multiple lines comment
    are supported
*/
// headings
// —————
@font-family-base: Arial, sans-serif;
h1, h2, h3 {
    font-family: @font-family-base;
    color: #333;
}
pre

All of the single-line comments will be ignored during the compiling stage, the code above will be compiled to:

{color:#295646;}
bc. {color:#295646;}/*
   Multiple lines comment
   are still supported
*/
h1,
h2,
h3 {
    font-family: Arial, sans-serif;
    color: #333;
}
pre

Notice in the generated CSS code,Less removes the single-line comments but keeps the multiple-line comments, since multiple-line comments are natively supported by plain CSS (CSS will ignore them after all), there is no need to remove them.

2.3 Arithmetical Operators

We can use arithmetical operators
bc. {color:#295646;}+ ,
bc. {color:#295646;}-,
bc. {color:#295646;}* ,
bc. {color:#295646;}/ on numbers and color codes. For example:

{color:#295646;}
bc. {color:#295646;}@size: 14px;
@width: 60%;
@color: #ff6600;

.text-lg { font-size: size * 2; color: color / 2;
}

.panel-lg { width: width + 20; color: color – #112200;
}
pre

Compiled to:

{color:#295646;}
bc. {color:#295646;}.text-lg {
    font-size: 28px;
    color: #803300;
}
.panel-lg {
    width: 80%;
    color: #ee4400;
}
pre

Practice

  1. Go to repo’s folder chapter2/2.3, open oper.less file and play with the code by adding some changes using
    bc. {color:#295646;}+ ,
    bc. {color:#295646;}-,
    bc. {color:#295646;}* ,
    bc. {color:#295646;}/ ;
  1. Start a command/terminal window at this folder, use
    bc. {color:#295646;}lessc to compile oper.less, and see how your changes affected the generated code.

2.4 Nested Rules

Suppose we have a
bc. {color:#295646;}

with the
bc. {color:#295646;}.article class. In this
bc. {color:#295646;}
we want to display the content of an article, including its title (we may use the
bc. {color:#295646;}

element), and several paragraphs (we use the
bc. {color:#295646;}

element). Commonly we write the CSS like this:

{color:#295646;}
bc. {color:#295646;}.article {
    font-family: Arial, sans-serif;
}
.article > h3 {
    font-size: 1.4em;
    margin-bottom: 1.2em;
}
.article p {
    margin-bottom: 1.2em;
}
pre

This is for the
bc. {color:#295646;}h3 and
bc. {color:#295646;}p tags under the
bc. {color:#295646;}.article element. We may need to define several classes under this element, so we would need to add the
bc. {color:#295646;}.article prefix to all of them, which is not very convenient. Less provides a better way to do it:

{color:#295646;}
bc. {color:#295646;}.article {
    font-family: Arial, sans-serif;
    > h3 {
        font-size: 1.4em;
        margin-bottom: 1.2em;
    }
    p {
        margin-bottom: 1.2em;
    }
}
pre

After complication:

{color:#295646;}
bc. {color:#295646;}.article {
    font-family: Arial, sans-serif;
}
.article > h3 {
    font-size: 1.4em;
    margin-bottom: 1.2em;
}
.article p {
    margin-bottom: 1.2em;
}
pre

We can see it generates exactly the same code as we did before. In this way we not only write less code but we have a more clear structure.

For this nested rule, another common use case is the media-query, if we write the following code in Less:

{color:#295646;}
bc. {color:#295646;}.lead {
    font-size: 16px;
    @media (min-width: 768px) {
        font-size: 20px;
    }
}
pre

After compilation:

{color:#295646;}
bc. {color:#295646;}.lead {
    font-size: 16px;
}
@media (min-width: 768px) {
    .lead {
        font-size: 20px;
    }
}
pre

The Less processor generates the correct media-query code, and our Less version code is much more readable and organized than the plain CSS version. We can easily tell the rules inside
bc. {color:#295646;}.lead – generally set the font size to 16px, but change it to 20px for devices whose width is larger than 768px.

2.5 Mixins

Mixins might be the most important feature in Less. If you are familiar with a programing language like Javascript, mixins are like self-defined functions:

{color:#295646;}
bc. {color:#295646;}.bordered {
    border: 1px dotted black;
}
.panel {
    background: #e1e1e1;
    .bordered();
}
pre

Compiled to:

{color:#295646;}
bc. {color:#295646;}.bordered {
    border: 1px dotted black;
}
.panel {
    background: #e1e1e1;
    border: 1px dotted black;
}
pre

In the
bc. {color:#295646;}.panel class, we “invoke” the
bc. {color:#295646;}.bordered function, it will include all the code inside
bc. {color:#295646;}.bordered.

Mixins with parameters

Mixins can also have parameters:

{color:#295646;}
bc. {color:#295646;}.border-radius(@radius) {
    -webkit-border-radius: @radius;
    -moz-border-radius: @radius;
    border-radius: @radius;
}

.btn { font-size: 14px; .border-radius(5px);
}

.panel { .border-radius(8px);
}
pre

Compiled to:

{color:#295646;}
bc. {color:#295646;}.btn {
    font-size: 14px;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
}
.panel {
    -webkit-border-radius: 8px;
    -moz-border-radius: 8px;
    border-radius: 8px;
}
pre

It can also have multiple parameters:

{color:#295646;}
bc. {color:#295646;}.box(@margin, @padding) {
    margin: @margin;
    padding: @padding;
}

.panel { .box(3px, 5px);
}

.quote { .box(5px, 10px);
}
pre

Compiled to:

{color:#295646;}
bc. {color:#295646;}.panel {
    margin: 3px;
    padding: 5px;
}
.quote {
    margin: 5px;
    padding: 10px;
}
pre

Mixins under namespace

We can group mixins together under a namespace. For example, if we want to make a mixin library for other developers to reuse, we can put our code under a namespace:

{color:#295646;}
bc. {color:#295646;}#mbt-lib {
    .box(@background, @border, @text-color) {
        background-color: @background;
        border: 1px solid @border;
        color: @text-color;
    }
}
// use it
.panel {
    #mbt-lib > .box(#f1f1f1, #cccccc, #555555);
}
pre

Compiled to:

{color:#295646;}
bc. {color:#295646;}.panel {
    background-color: #f1f1f1;
    border: 1px solid #cccccc;
    color: #555555;
}
pre

We put a mixin named
bc. {color:#295646;}.box inside
bc. {color:#295646;}#mbt-lib. Other developers can use this mixin with
bc. {color:#295646;}#mbt-lib > .box, while they can still define their own
bc. {color:#295646;}.box mixin, and since our version
bc. {color:#295646;}.box is under the namespace
bc. {color:#295646;}#mbt-lib, those two
bc. {color:#295646;}.box functions would not conflict with each other.

Another use case would be putting all similar functions inside a group. For example, in Bootstrap’s source code, it defines several gradient mixins under the
bc. {color:#295646;}#gradient group.

{color:#295646;}
bc. {color:#295646;}#gradient {
    .horizontal(@start-color, @end-color, @start-percent, @end-percent) {
        ...
    }
    .vertical(@start-color, @end-color, @start-percent, @end-percent) {
        ...
    }
    ...
}
pre

This
bc. {color:#295646;}#gradient group (or namespace) contains a horizontal gradient mixin and a vertical gradient mixin, for example our
bc. {color:#295646;}.panel will have a gradient background color by using the horizontal gradient mixin:

{color:#295646;}
bc. {color:#295646;}.panel {
    ...
    #gradient > .horizontal(#555, #333, 0%, 100%);
}
pre

Practice

  1. Go to code repository folder chapter2/2.5, and open a command/terminal window at this folder;
  1. Use
    bc. {color:#295646;}lessc to compile the mixins.less file:
    bc. {color:#295646;}$ lessc mixins.less, and see the generated code;
  1. Try to add your own mixin definitions in mixins.less, or change the current ones, e.g. add another parameter, add a namespace, etc. Then use
    bc. {color:#295646;}lessc to re-compile it to see the changes.

2.6 Parent Selector

The
bc. {color:#295646;}& operator will refer to its parent selector, for example:

{color:#295646;}
bc. {color:#295646;}.navbar {
    background: #333;
    &-default {
        .badge {
            background-color: #fff;
        }
        &:hover {
            background-color: #ff6600;
        }
    }
}
pre

Compiled to:

{color:#295646;}
bc. {color:#295646;}.navbar {
    background: #333;
}
.navbar-default .badge {
    background-color: #fff;
}
.navbar-default:hover {
    background-color: #ff6600;
}
pre

The first
bc. {color:#295646;}& is replaced by its parent selector’s name
bc. {color:#295646;}.navbar. The second
bc. {color:#295646;}& is replaced by
bc. {color:#295646;}.navbar-default .

Another example:

{color:#295646;}
bc. {color:#295646;}.input-sm {
    height: 30px;
    select& {
      line-height: 1.4em;
    }
}
pre

Compiled to :

{color:#295646;}
bc. {color:#295646;}.input-sm {
    height: 30px;
}
select.input-sm {
    line-height: 1.4em;
}
pre

Also notice that when we use this
bc. {color:#295646;}& operator along with mixins, the code inside the mixin will first be included, and then do the
bc. {color:#295646;}& replacement. For example:

{color:#295646;}
bc. {color:#295646;}.bg-warning {
    background-color: #ff9900;
    a&:hover,
    a&:focus {
        background-color: #ff3300;
    }
}

.well { .bg-warning();
}
pre

Compiled to:

{color:#295646;}
bc. {color:#295646;}.bg-warning {
    background-color: #ff9900;
}
a.bg-warning:hover,
a.bg-warning:focus {
    background-color: #ff3300;
}
.well {
    background-color: #ff9900;
}
a.well:hover,
a.well:focus {
    background-color: #ff3300;
}
pre

We have the
bc. {color:#295646;}& operator in
bc. {color:#295646;}.bg-warning, so
bc. {color:#295646;}a.bg-warning:hover and
bc. {color:#295646;}a.bg-warning:focus are generated. In the
bc. {color:#295646;}.well class, we included this
bc. {color:#295646;}.bg-warning mixin, so the
bc. {color:#295646;}.well code will first become:

{color:#295646;}
bc. {color:#295646;}.well {
    background-color: #ff9900;
    a&:hover,
    a&:focus {
        background-color: #ff3300;
    }
}
pre

Then the
bc. {color:#295646;}& sign will be replaced by its parent selector which is
bc. {color:#295646;}.well, thus we get
bc. {color:#295646;}a.well:hover and
bc. {color:#295646;}a.well:focus. Recall that the order is: first include the mixin, then do the
bc. {color:#295646;}& replacement. The order matters because if it is reversed, we will get
bc. {color:#295646;}.well a.bg-warning:hover and
bc. {color:#295646;}.well a.bg-warning:focus instead.

Practice

Suppose we have the following code:

{color:#295646;}
bc. {color:#295646;}.navbar() {
    background: #333;
    &-default {
        .badge {
            background-color: #fff;
        }
        &:hover {
            background-color: #ff6600;
        }
    }
}

.top { &-nav { .navbar(); }
}
pre

What code would it generate after compilation? Take a guess first, then compile it to see if your answer is correct:

  1. Go to repository folder chapter2/2.6, I already put the above code in the file test.less.
  1. Start a command/terminal window there, use
    bc. {color:#295646;}lessc to compile it:
    bc. {color:#295646;}$lessc test.less.
  1. Compare your answer to the generated code.

2.7 Builtin Functions

Less provides a list of builtin functions. You can use them to do operations on strings, lists, do some math, change color values, etc. We are going to list the most commonly used functions here, since this is not a complete Less reference, but it should be enough for us to make a Bootstrap theme.

Math functions

In Less, it is not uncommon to define font-size by using a base font size multiplying a decimal, for example, we may define our base font size as 14px, then for the
bc. {color:#295646;}h1 tag we use the font size as 2.2 times bigger; for the
bc. {color:#295646;}h2 we use 1.4 times bigger, etc. In this
bc. {color:#295646;}h2 case since 14 * 1.4 = 19.6, we may want to make it an integer. Depending on our use case, we may choose 19px or 20px. The
bc. {color:#295646;}floor and
bc. {color:#295646;}ceil functions can help us do the trick.

floor

The
bc. {color:#295646;}floor function will round a number down to the next lowest integer. It will pick the closest integer which is less than or equal to the original number. If you are familiar with Javascript, this function does exactly the same thing as
bc. {color:#295646;}Math.floor in Javascript.

Example:

{color:#295646;}
bc. {color:#295646;}small {
    font-size: floor(14px * 0.8);
}
h5 {
    font-size: floor(14px * 0.7);
}
h6 {
    font-size: floor(8.0px);
}
pre

In the above 3 cases:

  • 14px * 0.8 is 11.2px, the next lowest integer is 11;
  • 14px * 0.7 is 9.8px, the next lowest integer is 9;
  • the closest integer less than or equal to 8.0 is 8.

So after compilation it becomes:

{color:#295646;}
bc. {color:#295646;}small {
    font-size: 11px;
}
h5 {
    font-size: 9px;
}
h6 {
    font-size: 8px;
}
pre

ceil

This function will round a number up to the next highest integer. It will pick a closest integer which is greater than or equal to the original number. It does the same thing as
bc. {color:#295646;}Math.ceil in Javascript.

Example:

{color:#295646;}
bc. {color:#295646;}big {
    font-size: ceil(14px * 1.2);
}
h4 {
    font-size: ceil(14px * 1.3);
}
h5 {
    font-size: ceil(12.0px);
}
pre

In the above 3 cases:

  • 14px * 1.2 is 16.8px, the next highest integer is 17;
  • 14px * 1.3 is 18.2px, the next highest integer is 19;
  • the next integer which is greater than or equal to 12.0 is 12.

So after compilation it becomes:

{color:#295646;}
bc. {color:#295646;}big {
    font-size: 17px;
}
h4 {
    font-size: 19px;
}
h5 {
    font-size: 12px;
}
pre

Color functions

Less also provides a set of handy color operation functions.

lighten

This function increases the lightness of a color in the HSL color space by an absolute amount, we can think intuitively that it will make a color “brighter”.

This function takes 3 parameters:

  • color: A color object
  • amount: A percentage 0~100%
  • method: Optional, when set this value to “relative”, the amount of adjustment will be relative to the current value

For most use cases, you do not need the third parameter, here is an example:

{color:#295646;}
bc. {color:#295646;}@default-link-color: #000000;
@warning-link-color: #be4c0f;

a.default-link { color: default-link-color; } a.default-link:hover { color: lighten(default-link-color, 28%);
}

a.warning-link { color: warning-link-color; } a.warning-link:hover { color: lighten(warning-link-color, 15%);
}
pre

After compilation:

{color:#295646;}
bc. {color:#295646;}a.default-link {
    color: #000000;
}
a.default-link:hover {
    color: #474747;
}

a.warning-link { color: #be4c0f;
}
a.warning-link:hover { color: #ee6f2b;
}
pre

We can see the differences between before adding lightness and after:

The
bc. {color:#295646;}lighten function works like a charm, but you may wonder how it magically knows that changing our RGB color
bc. {color:#295646;}#be4c0f to
bc. {color:#295646;}#ee6f2b will make the color 15% brighter. The secret is that, when we pass an RGB hex value to this function, it will actually first convert the RGB value to the HSL color space, then increase a percentage on its lightness value, and then convert it back to the RGB space. Below is the pseudo code for this process:

{color:#295646;}
bc. {color:#295646;}rgb = #be4c0f;

// convert RGB color to HSL color
hsl = convertRGBtoHSL(rgb);

// get hue, saturation, lightness channels of this color
h = getHueOfColor(hsl);
s = getSaturationOfColor(hsl);
l = getLightnessOfColor(hsl);

// increase the lightness channel’s value
l = l + 15%;

// now convert this new hsl value to RGB hex value
newRGB = convertHSLtoRGB(h, s, l);
// newRGB now is #ee6f2b
pre

Here is another example: we defined two classes,
bc. {color:#295646;}.color1 and
bc. {color:#295646;}.color2. In the
bc. {color:#295646;}.color1 code, we directly use the
bc. {color:#295646;}lighten function, while in
bc. {color:#295646;}.color2 we first convert RGB to HSL color space with the
bc. {color:#295646;}hue,
bc. {color:#295646;}saturation and
bc. {color:#295646;}lightness functions, then we increase the lightness channel’s value, and finally use the
bc. {color:#295646;}hsl function to convert this HSL color back to an RGB color. After compilation they produce the same color result.

{color:#295646;}
bc. {color:#295646;}@mygreen: #80e619;

.color1 { color: lighten(mygreen, 28%); } .color2 { color: hsl(hue(mygreen), saturation(mygreen), lightness(mygreen) + 28);
}
pre

After compilation:

{color:#295646;}
bc. {color:#295646;}.color1 {
    color: #c7f49a;
}
.color2 {
    color: #c7f49a;
}
pre

Notice that in the
bc. {color:#295646;}.color2 class, we utilized other color functions in Less:

*
bc. {color:#295646;}hue : Get the hue channel of a color object in the HSL color space.

*
bc. {color:#295646;}saturation : Get the saturation channel of a color object in the HSL color space.

*
bc. {color:#295646;}lightness : Get the lightness channel of a color object in the HSL color space.

*
bc. {color:#295646;}hsl : Creates an opaque color object from hue, saturation and lightness (HSL) values, output is an RGB hex number.

Converting an RGB color to the HSL color space requires some mathematical calculations. Since it is beyond the scope of this chapter, we won’t cover it here. If you are interested, I included some Javascript code doing the conversion in Appendix A: RGB and HSL color space conversions, from where you can see how the algorithm works.

darken

The
bc. {color:#295646;}darken function does the reverse as
bc. {color:#295646;}lighten, it will decrease the lightness of a color. In the above example, after increasing the lightness of the color
bc. {color:#295646;}#80e619 by 28%, we get
bc. {color:#295646;}#c7f49a. If we decrease the lightness of this color
bc. {color:#295646;}#c7f49a by 28%, we can get the original color back:

{color:#295646;}
bc. {color:#295646;}@mygreen: #80e619;
@my-lightgreen: lighten(@mygreen, 28%);
.color1 {
    color: @my-lightgreen;
}
.color2 {
    color: darken(@my-lightgreen, 28%);
}
pre

After compilation:

{color:#295646;}
bc. {color:#295646;}.color1 {
    color: #c7f49a;
}
.color2 {
    color: #80e619;
}
pre

red, green, blue

These 3 functions will correspondingly extract the
bc. {color:#295646;}red ,
bc. {color:#295646;}green,
bc. {color:#295646;}blue channel of a color, below is a common use case: we generate a half-transparent color of an existing color:

{color:#295646;}
bc. {color:#295646;}@color: #ff6600;
@color-half-alpha: rgba(red(@color), green(@color), blue(@color), .5);

.bg-warn { color: @color-half-alpha;
}
pre

Compiled to:

{color:#295646;}
bc. {color:#295646;}.bg-warn {
    color: rgba(255, 102, 0, 0.5);
}
pre

fadein

The
bc. {color:#295646;}fadein function increases the opacity of a color, if a color is already opaque, this function won’t affect it.

The code snippet below first defines a black color
bc. {color:#295646;}@inner-color with 0.2 alpha transparency, then defines another color
bc. {color:#295646;}@outer-color based on the first color with an increasing 60% opacity to make it more opaque. The third color
bc. {color:#295646;}@font-color is already an opaque color: it only has R, G, B value with no Alpha channel (or we can say its alpha value is 100% by default), so the
bc. {color:#295646;}fadein function will not have an effect on it even we write the code as increasing its opacity by 50%.

{color:#295646;}
bc. {color:#295646;}@inner-color: rgba(0, 0, 0, 0.2);
@outer-color: fadein(@inner-color, 60%);
@font-color: #ff6600;

.popover { background-color: inner-color; border: 1px solid outer-color; color: fadein(@font-color, 50%);
}
pre

After compilation:

{color:#295646;}
bc. {color:#295646;}.popover {
    background-color: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(0, 0, 0, 0.8);
    color: #ff6600;
}
pre

fadeout

The
bc. {color:#295646;}fadeout function does the reverse of the
bc. {color:#295646;}fadein function: it decreases the opacity of a color, or we can say it increases the transparency of a color. Unlike
bc. {color:#295646;}fadein, it works on an opaque color, since an opaque color’s alpha value is 100%, and
bc. {color:#295646;}fadeout will decrease it.

{color:#295646;}
bc. {color:#295646;}@font-color: #ff6600;

.popover { color: fadeout(@font-color, 50%);
}
pre

After compilation:

{color:#295646;}
bc. {color:#295646;}.popover {
    color: rgba(255, 102, 0, 0.5);
}
pre

spin

The
bc. {color:#295646;}spin function rotates the hue angle of a color. The hue part of the HSL color space is a circle:

Say we have a yellow color, if we rotate it by -10 degrees, in the above picture it will go clockwise towards the red zone; if we rotate it by 10 degrees, it will go counter-clockwise towards the green zone.

For example, if you ever used the
bc. {color:#295646;}alert or
bc. {color:#295646;}alert-warning classes in Bootstrap before, your code looks like this:

{color:#295646;}
bc. {color:#295646;}<div class="alert alert-warning">
    <h4>Warning!</h4>
    <p>Warning message.</p>
</div>
pre

Under the default theme, this
bc. {color:#295646;}div looks like:

You can see the background and border have different colors. To generate the border color from the background color, Bootstrap uses this
bc. {color:#295646;}spin function along with the
bc. {color:#295646;}darken function, the code is defined like below:

{color:#295646;}
bc. {color:#295646;}@alert-warning-bg: #fcf8e3;
@alert-warning-border: darken(spin(@alert-warning-bg, -10), 5%);
.alert-warning {
    background-color: @alert-warning-bg;
    border: 1px solid @alert-warning-border;
    // ... other properties
}
pre

After complication:

{color:#295646;}
bc. {color:#295646;}.alert-warning {
    background-color: #fcf8e3;
    border: 1px solid #faebcc;
    // ... other properties
}
pre

We can see that to generate the border color, Bootstrap first spins the background color by -10 degrees (in the above hue picture, it will rotate this light yellow color
bc. {color:#295646;}#fcf8e3 towards the red zone by 10 degrees), then darkens this color by 5%. With these 2 steps we get a new color
bc. {color:#295646;}#faebcc. Bootstrap uses this trick for other alert states and panel states too, like
bc. {color:#295646;}.alert-success,
bc. {color:#295646;}.panel-warning,
bc. {color:#295646;}.panel-success, etc.

Practice

Go to repo’s folder chapter2/2.7, make some code changes in math.less and color.less, e.g. apply the
bc. {color:#295646;}floor,
bc. {color:#295646;}lighten,
bc. {color:#295646;}darken and
bc. {color:#295646;}fadein functions to some value, then use
bc. {color:#295646;}lessc to compile it to see how those values change.

2.8 Extend

The extend pseudo class can merge the selector in which it is located with the one that it references. For example:

{color:#295646;}
bc. {color:#295646;}.btn {
    background-color: #ff6600;
    color: #ffffff;
}
.btn-large {
    &:extend(.btn);
    padding: 5px 10px;
    font-size: 18px;
}
pre

Outputs after compilation:

{color:#295646;}
bc. {color:#295646;}.btn,
.btn-large {
    background-color: #ff6600;
    color: #ffffff;
}
.btn-large {
    padding: 5px 10px;
    font-size: 18px;
}

pre

See now the
bc. {color:#295646;}.btn-large class also has the CSS rule set as the
bc. {color:#295646;}.btn class.

If we have nested selectors, by default the
bc. {color:#295646;}&:extend directive won’t extend them. Example:

{color:#295646;}
bc. {color:#295646;}.header {
     padding: 10px;
     h3 {
         color: #fff;
    }
}

.nav-top { &:extend(.header);
}
pre

After compilation:

{color:#295646;}
bc. {color:#295646;}.header,
.nav-top {
    padding: 10px;
}
.header h3 {
    color: #fff;
}
pre

We can see the
bc. {color:#295646;}.nav-top class now has the
bc. {color:#295646;}padding: 10px rule, but the
bc. {color:#295646;}h3 is ignored. If we want to include all of the nested selectors, we need to add the
bc. {color:#295646;}all keyword.

{color:#295646;}
bc. {color:#295646;}.header {
     padding: 10px;
     h3 {
         color: #fff;
    }
}

.nav-top { &:extend(.header all);
}
pre

Compiled to:

{color:#295646;}
bc. {color:#295646;}.header,
.nav-top {
    padding: 10px;
}
.header h3,
.nav-top h3 {
    color: #fff;
}
pre

Now we have both of the
bc. {color:#295646;}.nav-top and
bc. {color:#295646;}.nav-top h3 selectors.

Extend VS Mixins

In our first
bc. {color:#295646;}.btn and
bc. {color:#295646;}.btn-large example, you may have noticed that we can achieve the same result by using mixins:

{color:#295646;}
bc. {color:#295646;}.btn {
    background-color: #ff6600;
    color: #ffffff;
}
.btn-large {
    .btn();
    padding: 5px 10px;
    font-size: 18px;
}
pre

Notice that we use
bc. {color:#295646;}.btn() to replace
bc. {color:#295646;}&:extend(.btn), and after compilation it becomes this:

{color:#295646;}
bc. {color:#295646;}.btn {
    background-color: #ff6600;
    color: #ffffff;
}
.btn-large {
    background-color: #ff6600;
    color: #ffffff;
    padding: 5px 10px;
    font-size: 18px;
}
pre

Now the
bc. {color:#295646;}.btn-large also has the rule set defined in
bc. {color:#295646;}.btn class, so if we can use mixins to do the same thing, why and when should we use
bc. {color:#295646;}&:extend?

Well, if we check the generated code in plain CSS, we can see by using
bc. {color:#295646;}&:extend we will have less code than using mixins. Generally because mixins copy the same CSS rule set in the place that calls it, while
bc. {color:#295646;}&:extend combines the selectors instead of doing code replication. So yes, using
bc. {color:#295646;}&:extend will help us remove unnecessary duplication and reduce the final CSS size, but does that mean we should always choose
bc. {color:#295646;}&:extend over mixins?

Let’s see another example:

{color:#295646;}
bc. {color:#295646;}.base-font {
    font-family: Arial, Verdana, sans-serif;
    color: #000;
}

h1 { &:extend(.base-font); font-size: 2em;
}

.panel-warning { &:extend(.base-font); background-color: #ff9900; color: #fff;
}

.alert-danger { &:extend(.base-font); background-color: #ff3300; color: #fff;
}
pre

We have a
bc. {color:#295646;}.base-font class which defined the font type and color, the other 3 selectors
bc. {color:#295646;}h1,
bc. {color:#295646;}.panel-warning and
bc. {color:#295646;}.alert-danger are using
bc. {color:#295646;}&:extend to use the CSS rule set in
bc. {color:#295646;}.base-font.

After compilation:

{color:#295646;}
bc. {color:#295646;}.base-font,
h1,
.panel-warning,
.alert-danger {
  font-family: Arial, Verdana, sans-serif;
  color: #000;
}
h1 {
  font-size: 2em;
}
.panel-warning {
  background-color: #ff9900;
  color: #fff;
}
.alert-danger {
  background-color: #ff3300;
  color: #fff;
}
pre

It clearly generates less code than using mixins like
bc. {color:#295646;}.base-font(), however, in the first part of the compiled CSS, while we let
bc. {color:#295646;}.base-font,
bc. {color:#295646;}h1,
bc. {color:#295646;}.panel-warning and
bc. {color:#295646;}.alert-danger share the same CSS rule set, they do not have any relationships. The code is a little confusing when we put those 4 selectors together to share a rule set, because it is like we are forcing a parallel relationship between those 4 unrelated selectors. However, our first
bc. {color:#295646;}.btn and
bc. {color:#295646;}.btn-large example is a great case to use
bc. {color:#295646;}&:extend, since
bc. {color:#295646;}.btn-large is a button (just a larger version), it has a relationship with
bc. {color:#295646;}.btn.

So when do we use
bc. {color:#295646;}&:extend and when do we use mixins? Personally I prefer to use
bc. {color:#295646;}&:extend when there is an
bc. {color:#295646;}is-a relationship between selectors, while I use mixins when there is a
bc. {color:#295646;}has-a relationship. For example,
bc. {color:#295646;}.btn-large “is-a”
bc. {color:#295646;}.btn, so we use
bc. {color:#295646;}&:extend;
bc. {color:#295646;}.panel-warning is not a
bc. {color:#295646;}.base-font, but “has-a”
bc. {color:#295646;}.base-font, so we should use
bc. {color:#295646;}.base-font(). In conclusion, though
bc. {color:#295646;}&:extend can generate less code, it doesn’t mean we should use it everywhere, we choose one over the other depends on the relationships they have to keep the generated CSS code readable and organized.

2.9 Import Files

In plain CSS we use the
bc. {color:#295646;}@import directive to import style rules from other style sheets like:

{color:#295646;}
bc. {color:#295646;}@import url("fineprint.css");
@import "custom.css";
pre

This
bc. {color:#295646;}@import in Less does about the same, but unlike in plain CSS where we have to put it ahead of all other types of rules, in Less we can put it anywhere in the file.

{color:#295646;}
bc. {color:#295646;}.text-warning {
    color: #ff6600;
}
@import "my-mixins.less";
pre

We can also omit the .less suffix:

{color:#295646;}
bc. {color:#295646;}@import "my-mixins.less";
// next line does the same thing
@import "my-mixins"
pre

If several files import the same file, by default, this file will only be included once. Suppose we have 3 files here:

color.less:

{color:#295646;}
bc. {color:#295646;}.text-warning {
    color: #ff6600;
}
pre

In next box.less file, we import this color.less :

{color:#295646;}
bc. {color:#295646;}@import "color";
.box-warning {
    .text-warning;
}
pre

We also include color.less in another file container.less:

{color:#295646;}
bc. {color:#295646;}@import "color";
@import "box";
.panel-warning {
    .text-warning;
}
pre

As shown below, color.less is included twice (directly and indirectly) in container.less:

Now if we compile container.less, we will have:

{color:#295646;}
bc. {color:#295646;}.text-warning {
    color: #ff6600;
}
.box-warning {
    color: #ff6600;
}
.panel-warning {
    color: #ff6600;
}
pre

We can see that although color.less is included twice, the final generated CSS code only contains the
bc. {color:#295646;}.text-warning class once.

This is also the default behavior of the
bc. {color:#295646;}@import directive but we can change it. If we want to include the same file multiple time, in container.less we can use:

{color:#295646;}
bc. {color:#295646;}@import (multiple) "color";
@import (multiple) "box";
pre

After compilation,
bc. {color:#295646;}.text-warning will be included twice:

{color:#295646;}
bc. {color:#295646;}.text-warning {
  color: #ff6600;
}
.text-warning {
  color: #ff6600;
}
.box-warning {
  color: #ff6600;
}
.panel-warning {
  color: #ff6600;
}
pre

Less support 7 types of import options, including reference, inline, less, css, once, multiple and optional, we have seen two of them, once (the default behavior) and multiple. For most cases, the default one should work well, if you want to check other 5 types, go to http://lesscss.org/features/#import-options for more details.

Practice

In the above
bc. {color:#295646;}@import code in container.less, we either use the multiple keyword for both lines:

{color:#295646;}
bc. {color:#295646;}@import (multiple) "color";
@import (multiple) "box";
pre

Or both without it:

{color:#295646;}
bc. {color:#295646;}@import "color";
@import "box";
pre

What if we use multiple only for one line like this:

{color:#295646;}
bc. {color:#295646;}@import "color";
@import (multiple) "box";
pre

What would the CSS code be after we compile it? Now try it yourself:

  1. Go to repo’s folder chapter2/2.9, open a command/terminal window
  1. Use
    bc. {color:#295646;}lessc to compile container.less:
    bc. {color:#295646;}$ lessc container.less

In the generated code, how many times the
bc. {color:#295646;}.text-warning class appears?

Further more, what happens if we change
bc. {color:#295646;}multiple to
bc. {color:#295646;}reference ?

{color:#295646;}
bc. {color:#295646;}@import (reference) "color";
@import (reference) "box";
pre

Chapter 3 – Customization

Now it’s time to do the customization part of making our own themes. To make a Bootstrap theme, essentially we are overriding its current CSS rules. For example, if we use Bootstrap’s
bc. {color:#295646;}.btn-warning class on a button:

{color:#295646;}
bc. {color:#295646;}<button class="btn btn-warning">Warning</button>
pre

Under its default theme, this button has a yellow-like background, the font size inside the button is 14px and its text color is white. If we want to customize it, we add another CSS rule to override it like this:

{color:#295646;}
bc. {color:#295646;}.btn {
    font-size: 16px;
}
.btn-warning {
    background-color: #a442f4;
}
pre

This will change the button’s background color to purple and the font size to 16px.

This is a key part of making a Bootstrap theme: we include Bootstrap’s default CSS ruleset, and we add more CSS rules to override some of them, then we will have our own theme.

Now suppose we want to change the navigation bar’s style, we need to override some of the CSS rules for it. How many of those rules do we need? What are they? To answer these questions, it would be better first to dive into Bootstrap’s source code, know how Bootstrap’s CSS is organized, and then we will have a clear picture.

3.1 Inside Bootstrap

In chapter 1 we downloaded the source code of bootstrap-3.3.7 (or you can find it in the code repo), it includes several folders and files:

  • dist: contains final compiled CSS and JS code
  • docs: the documentation folder
  • fonts: glyphicons
  • js: contains raw Javascript files
  • less: contains .less files, will finally be compiled to plain CSS

All other files are related to building or managing Bootstrap package, so we can ignore them for now. What we really need here is the less folder. We need to know how Bootstrap organizes its CSS code, then our customization needs to reuse some code from it. In this section we will mainly focus on the less folder.

Under this less folder, there are 41 .less files and one mixins folder. We can roughly split these to 4 parts:

  • bootstrap.less : the file to generate the final CSS.
  • theme.less : if we check Bootstrap’s getting-started page (http://getbootstrap.com/getting-started), we can see Bootstrap provides an additional theme. That’s what this theme.less is used for, we can compile theme.less to get this theme’s CSS file.
  • Other 39 .less files: each file is used for one module. For example, navbar.less is for the navbar component, breadcrumbs.less is for the breadcrumbs component, etc. bootstrap.less includes all of these 39
    bc. {color:#295646;}.less files by using the
    bc. {color:#295646;}@import directive.
  • The
    bc. {color:#295646;}mixins folder: this folder has 30
    bc. {color:#295646;}.less files which contain all mixins. For example,
    bc. {color:#295646;}gradients.less contains several mixins to help us create horizontal, vertical, radial gradient effect in CSS.

Let’s start with bootstrap.less. This file is used for generating Bootstrap CSS for the default theme. Let’s test it now:

First go to the folder bootstrap-3.3.7/less, and start a command/terminal window there. Then in the command/terminal window, type :

{color:#295646;}
bc. {color:#295646;}$ lessc bootstrap.less bootstrap.css
pre

It may take 1 or 2 seconds but when it is finished, we will have a new file named bootstrap.css inside the less folder. This means we just generated Bootstrap’s CSS file from its source code.

Recall in chapter 1 we created a theme-styles.html file, and in that file we link the CSS from Bootstrap’s dist folder like this:

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="/bootstrap-3.3.7/dist/css/bootstrap.css"/>
pre

Let’s change it to our own compiled version: first go to the code repository folder chapter3/3.1, then open the file theme-styles.html in that folder. At around line #5 change the CSS link from
bc. {color:#295646;}/bootstrap-3.3.7/dist/css/bootstrap.css to
bc. {color:#295646;}/bootstrap-3.3.7/less/bootstrap.css :

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="/bootstrap-3.3.7/less/bootstrap.css"/>
pre

Start a command/terminal window at the repository root folder make-bootstrap-themes, then type
bc. {color:#295646;}http-server to start a web server. Now visit theme-styles.html page at: http://127.0.0.1:8080/chapter3/3.1/theme-styles.html . This page should now look exactly the same as before, which means our self-compiled Bootstrap CSS works!

Now let’s try Bootstrap’s alternative theme using the theme.less file. At folder bootstrap-3.3.7/less start a command/terminal window, then type the following command to compile it to a plain CSS file:

{color:#295646;}
bc. {color:#295646;}$ lessc theme.less theme.css
pre

Then in theme-styles.html file, add another line to link to this theme CSS file:

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="/bootstrap-3.3.7/less/bootstrap.css"/>
<link rel="stylesheet" href="/bootstrap-3.3.7/less/theme.css"/>
...
pre

Now refresh theme-styles.html page at http://127.0.0.1:8080/chapter3/3.1/theme-styles.html. Do you see the changes? For example, all the buttons now have gradient color, so our self-compiled theme CSS works!

Now back to the other .less files under [_ bootstrap-3.3.7/less_]. If we check the source code in bootstrap.less, we can see that it uses the
bc. {color:#295646;}@import command to include all of the other 39 .less files, and all of those 39 files can be divided into 4 categories:

1) Global variables and mixins:

  • variables.less: Defines all of the variables, like colors, font family, font size, padding size, borders, etc.
  • mixins.less: Recall we have a mixins sub folder in the less folder. All of the mixins are defined in those files under the mixins folder, for example, background-variant.less, gradients.less, etc, and this mixins.less file includes all of those files by using
    bc. {color:#295646;}@import, like:
    bc. {color:#295646;}@import “mixins/background-variant.less”;,
    bc. {color:#295646;}@import “mixins/gradients.less”;

2) Reset and dependencies:

  • normalize.less: Normalizes styles of HTML elements and attributes for all major browsers, this file is taken from https://github.com/necolas/normalize.css. Recall in chapter 2, we mentioned that Less is a superset of CSS, though this
    bc. {color:#295646;}normalize.less ends with the
    bc. {color:#295646;}.less prefix, inside it there is just plain CSS code.
  • print.less: Defines CSS for printing.
  • glyphicons.less: Defines CSS for all glyphicons, like
    bc. {color:#295646;}.glyphicon-plus,
    bc. {color:#295646;}.glyphicon-envelope, etc.

3) Core CSS:

This group of files defines the basic classes, including typography, grid system, tables, forms,etc.

  • scaffolding.less: Sets default styles for
    bc. {color:#295646;}html,
    bc. {color:#295646;}body,
    bc. {color:#295646;}a,
    bc. {color:#295646;}img,
    bc. {color:#295646;}hr, etc. It also defines
    bc. {color:#295646;}img-responsive,
    bc. {color:#295646;}img-rounded,
    bc. {color:#295646;}img-thumbnail,
    bc. {color:#295646;}img-circle
  • type.less: Defines CSS related to typography. For example,
    bc. {color:#295646;}h1 ~
    bc. {color:#295646;}h6,
    bc. {color:#295646;}p,
    bc. {color:#295646;}.text-left,
    bc. {color:#295646;}text-primary,
    bc. {color:#295646;}bg-warning,
    bc. {color:#295646;}ul,
    bc. {color:#295646;}ol,
    bc. {color:#295646;}small,
    bc. {color:#295646;}big,
    bc. {color:#295646;}blockquote, etc.
  • code.less: Defines CSS for
    bc. {color:#295646;}code,
    bc. {color:#295646;}kbd,
    bc. {color:#295646;}pre.
  • grid.less: Defines the grid system, including the
    bc. {color:#295646;}.container class,
    bc. {color:#295646;}.row,
    bc. {color:#295646;}.col-sm-*, etc. It calls the
    bc. {color:#295646;}.make-grid,
    bc. {color:#295646;}.make-grid-columns function defined in mixins/grid-framework.less, and calls
    bc. {color:#295646;}.make-row function defined in mixins/grid.less. In most cases, we don’t need to worry about this part since when we make our own themes, we barely need to change the grid system.
  • tables.less: CSS for tables, like
    bc. {color:#295646;}.table-bordered,
    bc. {color:#295646;}.table-striped, etc.
  • forms.less: CSS for forms, for example,
    bc. {color:#295646;}form-control,
    bc. {color:#295646;}form-group classes are defined here.
  • buttons.less: CSS for buttons,
    bc. {color:#295646;}.btn,
    bc. {color:#295646;}.btn-primary,
    bc. {color:#295646;}.btn-danger,
    bc. {color:#295646;}btn-block,
    bc. {color:#295646;}btn-lg, etc.

4) Components:

This group of files defines the CSS for components, like button groups, navigation bar, etc, the file names are quite straightforward:

  • component-animations.less: Animations for components, includes
    bc. {color:#295646;}.fade,
    bc. {color:#295646;}.collapse, etc.
  • dropdowns.less: CSS for dropdowns.
  • button-groups.less: CSS for button groups.
  • input-groups.less: CSS for input groups.
  • navs.less: CSS for navigations, like
    bc. {color:#295646;}.nav-tabs,
    bc. {color:#295646;}.nav-pills,
    bc. {color:#295646;}.nav-stacked, etc.
  • navbar.less: CSS for navigation bars, including
    bc. {color:#295646;}.navbar-default,
    bc. {color:#295646;}.navbar-inverse and classes for its inner elements, like
    bc. {color:#295646;}.navbar-brand,
    bc. {color:#295646;}.navbar-form, etc.
  • breadcrumbs.less: CSS for breadcrumbs.
  • pagination.less: CSS for paginations.
  • pager.less: CSS for pagers.
  • labels.less: CSS for labels.
  • badges.less: CSS for badges, including common
    bc. {color:#295646;}.badge class,
    bc. {color:#295646;}.btn .badge class (an element with
    bc. {color:#295646;}.badge class inside another element with
    bc. {color:#295646;}.btn class),
    bc. {color:#295646;}.list-group-item > .badge class, etc.
  • jumbotron.less: CSS for jumbotron.
  • thumbnails.less: CSS for thumbnails, this
    bc. {color:#295646;}.thumbnail class is used for containers, this can be used for making a card-like container (check some examples here: http://getbootstrap.com/components/#thumbnails). Don’t confuse this with the
    bc. {color:#295646;}.img-thumbnail class, which is used for images.
  • alerts.less: CSS for alerts,
    bc. {color:#295646;}.alert,
    bc. {color:#295646;}.alert-warning, etc.
  • progress-bars.less: CSS for progress bars.
  • media.less: CSS for the media component, we also included this component in our theme-styles.html.
  • list-group.less: CSS for list groups.
  • panels.less: CSS for panels, for example,
    bc. {color:#295646;}.panel,
    bc. {color:#295646;}.panel-heading,
    bc. {color:#295646;}.panel-body,
    bc. {color:#295646;}.panel-warning are defined here.
  • responsive-embed.less: CSS for keeping ratio of embedded objects, it defines classes like
    bc. {color:#295646;}.embed-responsive,
    bc. {color:#295646;}.embed-responsive-4by3 and
    bc. {color:#295646;}.embed-responsive-16by9. In most cases we won’t need to change its code when making themes.
  • wells.less: CSS for wells.
  • close.less: CSS for the close button. If you have written some code using the
    bc. {color:#295646;}.alert or
    bc. {color:#295646;}.modal class before, you may have used this
    bc. {color:#295646;}.close class inside the container to display a close button.

5) Components with Javascript:

Those components usually are being used with Javascript. For example, when a user clicks a button, it may open up a modal or a tooltip component:

  • modals.less: CSS for modals
  • tooltip.less: CSS for tooltips
  • popovers.less: CSS for popovers
  • carousel.less: CSS for carousel

6) Other utility classes:

These 2 files below define some utility classes, and in most scenarios we don’t need to change them when making themes.

  • utilities.less: Defines
    bc. {color:#295646;}.clearfix,
    bc. {color:#295646;}.hide,
    bc. {color:#295646;}.show,
    bc. {color:#295646;}.text-hide,
    bc. {color:#295646;}.center-block,
    bc. {color:#295646;}.pull-right,
    bc. {color:#295646;}.pull-left classes.
  • responsive-utilities.less: Defines utility classes for showing and hiding content by device via media query, including
    bc. {color:#295646;}.visible-xs,
    bc. {color:#295646;}.visible-sm,
    bc. {color:#295646;}visible-sm-block,
    bc. {color:#295646;}.hidden-xs,
    bc. {color:#295646;}.hidden-sm , etc.

Practice

Find one component file, e.g. alerts.less, and check the source code to see how Bootstrap defines its classes in Less. Then try to answer the following questions:

  1. Does it use some variables? Where are those variables originally defined?
  1. Does it use the nested rules feature we learned in chapter 2.4?
  1. Does it use some mixins? Where are those mixins originally defined? For example, alerts.less uses a mixin called
    bc. {color:#295646;}.alert-variant, can you find out which file has its definition?

3.2 A small customization

We just learned Bootstrap’s code structure, so going back to the question at the beginning of this chapter: if we want to change the navigation bar’s style, we need to override some of styles, but what specific classes do we need to override?

Say we want to change the navigation bar to the following styles:

  • Remove rounded corners
  • Remove the 1px border
  • Add a 2px solid border at the bottom
  • Change the active navigation item’s background color
  • Do the above 4 for both the default style and the inverse style

In the previous section, we mentioned that navbar.less defines the CSS for the navigation bar, so we need to check this file and find the CSS rules to override. It contains around 650 lines code but for our modifications, we only need to examine
bc. {color:#295646;}.navbar,
bc. {color:#295646;}.navbar-default, and the
bc. {color:#295646;}.navbar-inverse parts.

Let’s create a my-navbar.less file. For the first 2 changes listed above, we want to override the
bc. {color:#295646;}.navbar class, so let’s put the following content in our my-navbar.less file:

{color:#295646;}
bc. {color:#295646;}.navbar {
    border-radius: 0;
    border: none;
}
pre

We set the border radius to be 0 to remove the rounded corners, and set border to none to remove its default 1px border. Next we want to add a 2px border at bottom for both
bc. {color:#295646;}.navbar-default and
bc. {color:#295646;}.navbar-inverse, since they are using different colors. Let’s define colors first:

{color:#295646;}
bc. {color:#295646;}@navbar-default-border-color: #70A1D7;
@navbar-inverse-border-color: #F35B25;
pre

Then we define the bottom border for both
bc. {color:#295646;}.navbar-default and
bc. {color:#295646;}.navbar-inverse

{color:#295646;}
bc. {color:#295646;}.navbar-default {
    border-bottom: 2px solid @navbar-default-border-color;
}
.navbar-inverse {
    border-bottom: 2px solid @navbar-inverse-border-color;
}
pre

Now let’s change the active navigation item’s style. Again, check the code in navbar.less. We can see that the .navbar-default class defines a sub class .navbar-nav inside it:

{color:#295646;}
bc. {color:#295646;}.navbar-nav {
    > li > a {
        color: @navbar-default-link-color;
        &:hover,
        &:focus {
            color: @navbar-default-link-hover-color;
            background-color: @navbar-default-link-hover-bg;
        }
    }
    > .active > a {
        &,
        &:hover,
        &:focus {
            color: @navbar-default-link-active-color;
            background-color: @navbar-default-link-active-bg;
        }
    }
    > .disabled > a {
        &,
        &:hover,
        &:focus {
            color: @navbar-default-link-disabled-color;
            background-color: @navbar-default-link-disabled-bg;
        }
    }
}
pre

It has the styles for a navigation item’s normal state, active state, and disabled state. In our case, to override the style for the active state, we only need to change the
bc. {color:#295646;}> .active > a part. Let’s add this to our
bc. {color:#295646;}.navbar-default and
bc. {color:#295646;}.navbar-inverse:

{color:#295646;}
bc. {color:#295646;}.navbar-default {
    border-bottom: 2px solid @navbar-default-border-color;
    .navbar-nav {
        > .active > a {
            &, &:hover, &:focus {
                color: #fff;
                background-color: @navbar-default-border-color;
            }
        }
    }
}

.navbar-inverse { border-bottom: 2px solid navbar-inverse-border-color; .navbar-nav { > .active > a { &, &:hover, &:focus { color: #fff; background-color: navbar-inverse-border-color; } } }
}
pre

Notice we nest
bc. {color:#295646;}.navbar-nav in the
bc. {color:#295646;}.navbar-default and the
bc. {color:#295646;}.navbar-inverse classes, and inside this
bc. {color:#295646;}.navbar-nav class, we nest
bc. {color:#295646;}> .active > a. Inside this
bc. {color:#295646;}a, we again nest the
bc. {color:#295646;}&, &:hover, &:focus classes, and then under this rule we set the font color and the background color.

Now our my-navbar.less file has 4 parts:

  • 2 variables for color:
    bc. {color:#295646;}@navbar-default-border-color and
    bc. {color:#295646;}@navbar-inverse-border-color

*
bc. {color:#295646;}.navbar class

*
bc. {color:#295646;}.navbar-default class

*
bc. {color:#295646;}.navbar-inverse class

Let’s compile the Less code to plain CSS:

{color:#295646;}
bc. {color:#295646;}$ lessc my-navbar.less my-navbar.css
pre

After compilation:

{color:#295646;}
bc. {color:#295646;}.navbar {
    border-radius: 0;
    border: none;
}
.navbar-default {
    border-bottom: 2px solid #70A1D7;
}
.navbar-default .navbar-nav > .active > a,
.navbar-default .navbar-nav > .active > a:hover,
.navbar-default .navbar-nav > .active > a:focus {
    color: #fff;
    background-color: #70A1D7;
}
.navbar-inverse {
    border-bottom: 2px solid #F35B25;
}
.navbar-inverse .navbar-nav > .active > a,
.navbar-inverse .navbar-nav > .active > a:hover,
.navbar-inverse .navbar-nav > .active > a:focus {
    color: #fff;
    background-color: #F35B25;
}
pre

Add this compiled
bc. {color:#295646;}my-navbar.css to the theme-styles.html:

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="path/to/my-navbar.css"/>
pre

Refresh page we can see the changes.

Practice

  1. In the code repo’s root folder make-bootstrap-themes, start a command/terminal window, then type
    bc. {color:#295646;}http-server command to start a web server;
  1. In your browser, visit http://127.0.0.1:8080/chapter3/3.2/navbar.html
  1. View and learn the source code in my-navbar.less. Also check the compiled CSS code in the file my-navbar.css.

Challenge

Can you add styles in my-navbar.less for the alert badges to change its background color? After you make the change, remember to use
bc. {color:#295646;}lessc to recompile it, then refresh the navbar.html page.

Hint: You can add a
bc. {color:#295646;}.badge class inside both the
bc. {color:#295646;}.navbar-default and the
bc. {color:#295646;}.navbar-inverse classes.

3.3 Utilizing Variables

Recall in the last section we saw Bootstrap’s
bc. {color:#295646;}.navbar-nav source code like this:

{color:#295646;}
bc. {color:#295646;}.navbar-nav {
    > .active > a {
        &,
        &:hover,
        &:focus {
            color: @navbar-default-link-active-color;
            background-color: @navbar-default-link-active-bg;
        }
    }
}
pre

You may have noticed that under the
bc. {color:#295646;}.navbar-nav selector, Bootstrap is using two variables
bc. {color:#295646;}@navbar-default-link-active-color and
bc. {color:#295646;}@navbar-default-link-active-bg to set the font color and background color for the active state, and their values are actually defined in Bootstrap’s variables.less code as a gray color like
bc. {color:#295646;}#555555. That’s why in Bootstrap’s default theme, the background color of the default navbar is gray. This gives us a hint: to achieve the same customizations as we did in the last section, can we just change the values of these 2 variables and recompile bootstrap.less file to generate a new CSS file? Then using this new CSS file, our navigation bar’s font color and background color should be changed, right?

The answer is yes, and this might be the easiest way to make a bootstrap theme. Also the good news is we already knew the key part: in chapter 2 we learned in Less we can override some variables (if two variables have the same name, the later one’s value will override former one’s), and in section 3.1 we learned how to use the
bc. {color:#295646;}lessc command to compile
bc. {color:#295646;}bootstrap.less to a plain CSS file, so to make our own theme, one method is:

  1. Create a my-variables.less file, inside it we redefine some variables.
  1. Create a my-theme.less file, inside it we first import Bootstrap’s bootstrap.less, then import our my-variables.less such that our variable’s value can override Bootstrap’s. In this my-theme.less file, we can also add some customizations for other components.
  1. Compile this my-theme.less to generate the CSS file, my-theme.css.
  1. In the theme-styles.html page, instead of linking to bootstrap.css, adding a link to my-theme.css.

Let’s do a quick test for our navigation bar to see if we can achieve the same result as we did in the last section:

1) Create a file named my-variables.less. Inside it we redefine some variables related to the navigation bar. In our case, we want to remove the border radius, and also override the active navigation item’s font and background color for both
bc. {color:#295646;}.navbar-default and
bc. {color:#295646;}.navbar-inverse. In Bootstrap’s source code file navbar.less, under the
bc. {color:#295646;}.navbar selector:

{color:#295646;}
bc. {color:#295646;}.navbar {
    ...
    @media (min-width: @grid-float-breakpoint) {
        border-radius: @navbar-border-radius;
    }
}
pre

It is using the
bc. {color:#295646;}@navbar-border-radius variable to define the navigation bar’s border radius, which means we can remove the border radius by redefining this variable’s value to 0. We also mentioned that under the
bc. {color:#295646;}.navbar-default .navbar-nav selector 2 variables are being used:
bc. {color:#295646;}@navbar-default-link-active-color and
bc. {color:#295646;}@navbar-default-link-active-bg, and for the
bc. {color:#295646;}.navbar-inverse .navbar-nav selector, there are another 2 variables:
bc. {color:#295646;}@navbar-inverse-link-active-color and
bc. {color:#295646;}@navbar-inverse-link-active-bg. So we need to override those 5 variables’ values. Let’s put the following 5 lines in the my-variables.less file:

{color:#295646;}
bc. {color:#295646;}@navbar-border-radius: 0;
@navbar-default-link-active-color: #fff;
@navbar-default-link-active-bg: #70A1D7;
@navbar-inverse-link-active-color: #fff;
@navbar-inverse-link-active-bg: #F35B25;
pre

2) Create the file my-theme.less. First import bootstrap.less then import my-variables.less (notice the order matters here, since the latter one overrides the former one’s variables, in our case we want the variables defined in my-variables.less to override the ones in bootstrap.less). We will also add code for
bc. {color:#295646;}.navbar to add a 2px border at bottom, and use different border colors for
bc. {color:#295646;}.navbar-default and
bc. {color:#295646;}.navbar-inverse:

{color:#295646;}
bc. {color:#295646;}@import "path/to/bootstrap-3.3.7/less/bootstrap.less";
@import "my-variables.less";

.navbar { border: none; border-bottom: 2px solid transparent; &-default { border-bottom-color: navbar-default-link-active-bg; } &-inverse { border-bottom-color: navbar-inverse-link-active-bg; }
}
pre

3) Compile my-theme.less to generate the CSS file my-theme.css:

{color:#295646;}
bc. {color:#295646;}$ lessc my-theme.less my-theme.css
pre

This my-theme.less file imported bootstrap.less, so after compilation my-theme.css will contain all of the CSS code of Bootstrap’s default theme, plus the customization code for the navigation bar.

4) Replace the link to the Bootstrap CSS file to our own my-theme.css (notice if your my-theme.css is located in a different path, make sure you use the right value for the
bc. {color:#295646;}href attribute) :

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="path/to/bootstrap-3.3.7/dist/css/bootstrap.css"/>
pre

Replaced by:

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="path/to/my-theme.css"/>
pre

Now refresh this page. We should be able to see the style changes in the navigation bar.

Practice

  1. At this book’s repository folder make-bootstrap-themes, open a command/terminal window, then use
    bc. {color:#295646;}http-server to start a web server.
  1. Visit http://127.0.0.1:8080/chapter3/3.3/navbar.html, you will see the default navigation bar:
  1. Go to the folder chapter3/3.3, learn the source code in my-variables.less and my-themes.less. Then at this folder start another command/terminal window, use
    bc. {color:#295646;}lessc to compile my-theme.less code:
    bc. {color:#295646;}$ lessc my-theme.less my-theme.css. This will generate our theme file with plain CSS code.
  1. Also in this folder, change the navbar.html file content to use our own theme file: at line 5, replace the line
    bc. {color:#295646;} with
    bc. {color:#295646;}.

Visit http://127.0.0.1:8080/chapter3/3.3/navbar.html again. Since it is using my-theme.css now, the navigation bar should be changed like this:

Challenge

Open my-theme.less and view the source code. Can you add some code to change the alert badge’s background color for both
bc. {color:#295646;}.navbar-default and
bc. {color:#295646;}.navbar-inverse?

Hint: you can add
bc. {color:#295646;}.badge class in both
bc. {color:#295646;}&-default and
bc. {color:#295646;}&-inverse selectors.

More on variables.less

Those 5 variables we defined in my-variables.less are originally defined in Bootstrap’s variables.less file, and around 387 variables are defined there in total.

We know those 5 variables are only related to the navigation bar, so to customize all of components in theme-styles.html, including typography, buttons, panels, etc., we need to override more variables. It’s better to first get to know what those variables are in variables.less and what they are used for.

The file variables.less groups those 387 variables into around 35 sections, from the basic font styles, brand colors to variables of components, including buttons, form controls, grid system, containers, navigation bars, etc. For example, we can find variables defined for the navigation bar in the
bc. {color:#295646;}navbar section:

{color:#295646;}
bc. {color:#295646;}...
@navbar-default-color:             #777;
@navbar-default-bg:                #f8f8f8;
@navbar-default-border:            darken(@navbar-default-bg, 6.5%);

// Navbar links
navbar-default-link-color: #777; navbar-default-link-hover-color: #333;
navbar-default-link-hover-bg: transparent; navbar-default-link-active-color: #555;
navbar-default-link-active-bg: darken(navbar-default-bg, 6.5%);
navbar-default-link-disabled-color: #ccc; navbar-default-link-disabled-bg: transparent;

// Navbar brand label
navbar-default-brand-color: navbar-default-link-color;
navbar-default-brand-hover-color: darken(navbar-default-brand-color, 10%);
@navbar-default-brand-hover-bg: transparent;

pre

The code is well organized. If we want to customize a component, we can easily find it in the corresponding section and then override its variables in our own my-variables.less. We won’t go through all the variables because that would be too many, but there are 6 sections we need to pay attention to, since those variables define the basic styles, and are widely used by components.

1) Gray color section

There are 6 levels of gray colors defined, they are all based on
bc. {color:#295646;}@gray-base color:

{color:#295646;}
bc. {color:#295646;}@gray-base: #000;
@gray-darker: lighten(@gray-base, 13.5%); // #222
@gray-dark: lighten(@gray-base, 20%);   // #333
@gray: lighten(@gray-base, 33.5%); // #555
@gray-light: lighten(@gray-base, 46.7%); // #777
@gray-lighter: lighten(@gray-base, 93.5%); // #eee
pre

Among those 6 variables,
bc. {color:#295646;}@gray-darker is not being used in any of Bootstrap’s .less files; the
bc. {color:#295646;}@gray-dark and the
bc. {color:#295646;}@gray colors are generally used for common text color;
bc. {color:#295646;}@gray-light and
bc. {color:#295646;}@gray-lighter are widely used for background color and the mouse hover color.

2) Brand contextual colors section

This section defines 5 contextual colors:

{color:#295646;}
bc. {color:#295646;}@brand-primary: darken(#428bca, 6.5%); // #337ab7
@brand-success: #5cb85c;
@brand-info: #5bc0de;
@brand-warning: #f0ad4e;
@brand-danger: #d9534f;
pre

Lots of components use those for their own contextual colors. For example, the button’s class
bc. {color:#295646;}.btn-primary uses
bc. {color:#295646;}@brand-primary as background color,
bc. {color:#295646;}.btn-success uses
bc. {color:#295646;}@brand-success as background color;
bc. {color:#295646;}.label-warning uses
bc. {color:#295646;}@brand-warning as background color;
bc. {color:#295646;}.progress-bar-danger uses
bc. {color:#295646;}@brand-danger as background color, etc.

3) Scaffolding

This section defines variables for some global styles. For example, the page body’s background color, the common text color, and a link’s normal state color and hover state color.

{color:#295646;}
bc. {color:#295646;}@body-bg: #fff;
@text-color: @gray-dark;
@link-color: @brand-primary;
@link-hover-color: darken(@link-color, 15%);
@link-hover-decoration: underline;
pre

4) Basic font style section

This section defines basic font styles, including font family, font size, line height, etc.

{color:#295646;}
bc. {color:#295646;}@font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif;
@font-family-base: @font-family-sans-serif;
@font-size-base: 14px;
@line-height-base: 1.428571429;
...
pre

5) Components’ common style section

This section defines common styles for components, including paddings, border radius, text and background color of active state, etc.

{color:#295646;}
bc. {color:#295646;}@padding-base-vertical: 6px;
@padding-base-horizontal: 12px;
@border-radius-base: 4px;
@border-radius-large: 6px;
@component-active-bg: @brand-primary;
...
pre

For example, the border radius variables are used by almost all components, including buttons, form inputs, navigation bar, progress bar, panels and wells, etc.

6) State contextual colors section

The brand contextual colors section above defines one group of contextual colors, this section defines another group.

{color:#295646;}
bc. {color:#295646;}@state-success-text:             #3c763d;
@state-success-bg:               #dff0d8;
@state-success-border:           darken(spin(@state-success-bg, -10), 5%);
@state-info-text:                #31708f;
@state-info-bg:                  #d9edf7;
@state-info-border:              darken(spin(@state-info-bg, -10), 7%);
@state-warning-text:             #8a6d3b;
@state-warning-bg:               #fcf8e3;
@state-warning-border:           darken(spin(@state-warning-bg, -10), 5%);
@state-danger-text:              #a94442;
@state-danger-bg:                #f2dede;
@state-danger-border:            darken(spin(@state-danger-bg, -10), 5%);
pre

Bootstrap’s alert and panel components use those variables. For example,
bc. {color:#295646;}.alert-warning uses
bc. {color:#295646;}@state-warning-text as text color,
bc. {color:#295646;}@state-warning-bg as background color, and
bc. {color:#295646;}@state-warning-border as border color.

Since those variables in the above 6 sections are widely used across all of components, we can just change those variables to get a customized theme. We will try this method in next section.

3.4 A light color theme

To choose which variable to override, usually some design work is involved: first pick some colors as the theme colors, then use software like Photoshop or Illustrator to draw the web page or components. During the process maybe some colors may need to be adjusted. Once you have finished the design, choose variables to override to make this theme. However, since this is not a design book, let’s simplify the process by focusing on the following questions:

  1. Page body’s background: do we use light color or dark color?
  1. Font styles: which font typeface do we use? How big for the base font size? how about the common text color?
  1. Contextual colors: for example, use which color as our brand primary color? Brand success color? How about success-state, warning-state and danger-state colors?
  1. For components, what padding size should we use? Do we want them to have round borders or not? Should we use gradient background color for components?
  1. After overriding variables, do we want to add more Less code to customize some other components?

For our first theme, I want to keep it simple, here are my choices:

  1. I’ll use light color, specifically, white, as body’s background color, so I don’t need to override any variables related to those colors, including colors defined in the gray color section, and the
    bc. {color:#295646;}@body-bg variable.
  1. I’ll use Sans Serif as my base font family, specifically, I’ll import a font named Nunito from Google Font and use it as the default.
  1. I’ll pick a group of colors as contextual colors (see below), then use them for both of the brand-contextual color group and state-contextual color group.
  1. For components, I’ll slightly change the padding value and set the border radius to zero, so no components will have rounded corners.
  1. I’ll also add some code to customize the navigation bar like what we did in section 3.2.

Let’s start coding this new my-variables.less, the first part is using the Nunito font as our default font-family:

{color:#295646;}
bc. {color:#295646;}@font-family-sans-serif: Nunito, Helvetica, Arial, sans-serif;
@headings-font-weight: 700;
pre

Here we also override the headings font weight to 700, because the weight of bold font in Nunito is 700, while the value is 500 by default in Bootstrap’s variables.less file.

Next, let’s define the brand contextual and state contextual colors:

{color:#295646;}
bc. {color:#295646;}// brand contextual colors
@brand-primary: #3B4A6B;
@brand-success: #52D681;
@brand-info: #22B2DA;
@brand-warning: #FFC24A;
@brand-danger: #F23557;

// state contextual colors
state-success-text: brand-success;
state-success-bg: lighten(state-success-text, 40%);
state-success-border: state-success-text;

state-info-text: brand-info;
state-info-bg: lighten(state-info-text, 45%);
state-info-border: state-info-text;

state-warning-text: brand-warning;
state-warning-bg: lighten(state-warning-text, 34%);
state-warning-border: state-warning-text;

state-danger-text: brand-danger;
state-danger-bg: lighten(state-danger-text, 40%);
state-danger-border: state-danger-text;
pre

Notice here for the state contextual text colors we just set their value to the brand contextual colors, and for the state contextual background colors, we are using the
bc. {color:#295646;}lighten function to make a slight change based on the contextual text colors.

Next, override the paddings value and border radius values for components:

{color:#295646;}
bc. {color:#295646;}@padding-base-vertical:     8px;
@padding-base-horizontal:   16px;

padding-large-vertical: 12px; padding-large-horizontal: 24px;

padding-small-vertical: 6px; padding-small-horizontal: 12px;

padding-xs-vertical: 2px; padding-xs-horizontal: 6px;

border-radius-base: 0; border-radius-large: 0;
@border-radius-small: 0;

@pager-border-radius: 0;
pre

Last, override some variables for navigation bar:

{color:#295646;}
bc. {color:#295646;}@navbar-height:                    60px;

navbar-default-color: brand-primary;
navbar-default-bg: #fff; navbar-default-link-color: #999;
navbar-default-link-hover-color: brand-primary;
navbar-default-link-hover-bg: transparent; navbar-default-link-active-color: brand-primary; navbar-default-link-active-bg: transparent;

navbar-inverse-color: gray-lighter;
navbar-inverse-bg: brand-primary;
navbar-inverse-link-color: gray-lighter;
navbar-inverse-link-hover-color: #fff; navbar-inverse-link-hover-bg: transparent;
navbar-inverse-link-active-color: navbar-inverse-link-hover-color;
@navbar-inverse-link-active-bg: transparent;
pre

That’s all for our my-variables.less file. We only overrode around 50 variables. Next let’s create my-theme.less, then import the Nunito font, Bootstrap’s Less file and our my-variables.less file:

{color:#295646;}
bc. {color:#295646;}@import url('https://fonts.googleapis.com/css?family=Nunito:400,600,700');
@import "path/to/bootstrap-3.3.7/less/bootstrap.less";
@import "my-variables.less";
pre

Also in my-theme.less, let’s add some more customizations to the navigation bar: remove its border, add a little shadow and change the alert badge’s background color.

{color:#295646;}
bc. {color:#295646;}.navbar {
    border: none;
    .box-shadow(0px 1px 1px 0px rgba(0, 0, 102, 0.1));
&-default { .badge { background-color: #F23557; } } &-inverse { .badge { background-color: #f67f55; } } } pre

Notice here we utilized a mixin named
bc. {color:#295646;}.box-shadow, this mixin is defined in Bootstrap’s vendor-prefixes.less file at less/mixins folder. The line
bc. {color:#295646;}@import “path/to/bootstrap-3.3.7/less/bootstrap.less”; imports all of those mixins, so we can directly use
bc. {color:#295646;}.box-shadow here.

That’s it! We completed my-variables.less and my-theme.less, let’s compile my-theme.less to the CSS file:

{color:#295646;}
bc. {color:#295646;}$ lessc my-theme.less my-theme.css
pre

Then link it in our theme-styles.html:

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="my-theme.css"/>
pre

Now let’s view the changes, here are some screenshots:

Under the default theme, the navigation bar and some buttons are:

Under our theme they are:

Recall we also changed the state contextual colors, which are used by components like alerts and panels. Under the default theme, the alerts are:

Under our theme they are:

The styles above look great, especially given we only have around 60 lines code in my-variables.less and 20 lines code in my-theme.less file. There are more changes on other components in this page, want to see all of them? Practice time!

Practice

  1. At this book’s repository folder make-bootstrap-themes, open a command/terminal window, then use
    bc. {color:#295646;}http-server to start a web server.
  1. Go to folder chapter3/3.4, at this folder start another command/terminal window, then use
    bc. {color:#295646;}lessc command to compile our theme’s Less file:
    bc. {color:#295646;}$ lessc my-theme.less my-theme.css.
  1. Visit web page at: http://127.0.0.1:8080/chapter3/3.4/theme-styles.html.
  1. Learn the code in my-variables.less and my-theme.less .

Challenge

Try to change the values of the 5 variables below in my-variables.less to your own colors:

{color:#295646;}
bc. {color:#295646;}@brand-primary: #3B4A6B;
@brand-success: #52D681;
@brand-info: #22B2DA;
@brand-warning: #FFC24A;
@brand-danger: #F23557;
pre

As a reference, here are 2 websites you can use to pick theme colors:

  • Pick predefined theme colors: http://colorhunt.co/
  • Pick predefined theme colors or generate them from your favorite picture: https://coolors.co/app

Once you replaced the above 5 colors with your own, save the file then use
bc. {color:#295646;}lessc to recompile my-theme.less:
bc. {color:#295646;}$ lessc my-theme.less my-theme.css. Now visit the web page at http://127.0.0.1:8080/chapter3/3.4/theme-styles.html, refresh the page to see the changes you made. Congratulations, now you have your first theme!

3.5 A dark color theme

In the last section we only wrote around 80 lines code in total and made a light-color theme. In this section we are going to override more variables and make a dark-color theme. Let’s start with creating 2 files: my-variables.less and my-theme.less. We will define variables in my-variables.less, and then do more customization in my-theme.less.

Like what we did in last section, my favorite process to make a theme is first set value for some global variables, then do more customization based on how it looks. So for this dark-color theme:

  1. Page body’s background color: I’ll use the color
    bc. {color:#295646;}#233142 for background color and
    bc. {color:#295646;}#e3e3e3 for the general text color.
  1. Font styles: I’ll use the “Roboto Condensed” font from Google fonts as the default font-family.
  1. Contextual colors: I’ll use
    bc. {color:#295646;}#ee6363 for
    bc. {color:#295646;}@brand-primary,
    bc. {color:#295646;}#62c462 for
    bc. {color:#295646;}@brand-success,
    bc. {color:#295646;}#5bc0de for
    bc. {color:#295646;}@brand-info,
    bc. {color:#295646;}#f0ad4e for
    bc. {color:#295646;}@brand-warning,
    bc. {color:#295646;}#C31207 for
    bc. {color:#295646;}@brand-danger. Additionally I’ll define a new variable named
    bc. {color:#295646;}@brand-secondary, assign its color to
    bc. {color:#295646;}#455D7A, I’ll use it for some components’ default background color. I’ll also set the state contextual color based on the brand contextual color. For those colors check the below picture:
  1. Padding size and border radius: I’ll set the vertical padding value to 8px and the horizontal padding value to 16px; I’ll enable the border radius for components, and set its default value to 2px.

Here is the first version of my-variables.less:

{color:#295646;}
bc. {color:#295646;}// Global settings
// ------------------------------
// ## font styles
@font-family-sans-serif:    "Roboto Condensed", Helvetica, Arial, sans-serif;
@headings-font-weight:      700;

// ## background color
body-bg: #233142; text-color: #e3e3e3;

// ## brand contextual colors
brand-primary: #ee6363; brand-success: #62c462;
brand-info: #5bc0de; brand-warning: #f0ad4e;
brand-danger: #C31207; brand-secondary: #455D7A;

// ## Link and hr color
link-color: brand-primary;
link-hover-color: darken(link-color, 10%);

hr-border: brand-secondary;

// ## state contextual colors
state-success-text: #fff; state-success-bg: brand-success; state-success-border: lighten(@brand-success, 5%);

state-info-text: #fff; state-info-bg: brand-info; state-info-border: lighten(@brand-info, 5%);

state-warning-text: #fff; state-warning-bg: brand-warning; state-warning-border: lighten(@brand-warning, 5%);

state-danger-text: #fff; state-danger-bg: brand-danger; state-danger-border: lighten(@brand-danger, 5%);

// ## border radius
border-radius-base: 2px; border-radius-large: 4px;
border-radius-small: 3px; pager-border-radius: 2px;

// ## paddings
padding-base-vertical: 8px; padding-base-horizontal: 16px;

padding-large-vertical: 12px; padding-large-horizontal: 24px;

padding-small-vertical: 6px; padding-small-horizontal: 12px;

padding-xs-vertical: 2px; padding-xs-horizontal: 6px;
pre

And in my-theme.less we have:

{color:#295646;}
bc. {color:#295646;}// Import "Roboto Condensed" font
@import url('https://fonts.googleapis.com/css?family=Roboto+Condensed:300,400,700');

// Import default bootstrap.less
@import “path/to/bootstrap-3.3.7/less/bootstrap.less”;

// Import our variables
@import “my-variables.less”;
pre

Let’s compile it:

{color:#295646;}
bc. {color:#295646;}$ lessc my-theme.less my-theme.css
pre

Link this compiled my-theme.css in our theme-style.html, then let’s view the page:

Typography:

Buttons:

Alert:

Looks good, doesn’t it? Notice now we only have around 60 lines of code, but clearly we need to do more work. Take a close look at the typography section in the screenshot above: the text contextual colors don’t work. For example, text with the
bc. {color:#295646;}.text-warning class still displays with a white color. Also some other components, like panels, look really bad:

But again, remember this is just our first step – defining some variables as global settings. Now let’s dig into each part to do more customizations.

Typography

If we check the screenshot above for typography part, there are several things we may want to change:

*
bc. {color:#295646;} and
bc. {color:#295646;}

 tag background color

  • border color of
    bc. {color:#295646;}
  • text color of text contextual color class like
    bc. {color:#295646;}.text-success,
    bc. {color:#295646;}.text-info
  • text color of background contextual color class like
    bc. {color:#295646;}.bg-success,
    bc. {color:#295646;}.bg-info, etc.

If we check Bootstrap’s variables.less file, there are some variables we can find which are used for defining colors for the
bc. {color:#295646;},
bc. {color:#295646;}

 and
bc. {color:#295646;}
tags, so let’s override those variables in our my-variables.less file:

{color:#295646;}
bc. {color:#295646;}@code-color:                @text-color;
@code-bg:                   @brand-secondary;
@pre-color:                 @text-color;
@pre-bg:                    @brand-secondary;
@pre-border-color:          darken(@brand-secondary, 20%);

// ## blockquote
blockquote-border-color: brand-secondary;
blockquote-small-color: text-muted;

// ## contextual text
text-muted: lighten(gray-base, 60%);
pre

For contextual text colors, you may notice we only defined the
bc. {color:#295646;}@text-muted variable, but where are other ones like
bc. {color:#295646;}@text-success,
bc. {color:#295646;}@text-warning ? If we check Bootstrap’s type.less file we can see those classes are originally defined as:

{color:#295646;}
bc. {color:#295646;}.text-success {
    .text-emphasis-variant(@state-success-text);
}
.text-info {
    .text-emphasis-variant(@state-info-text);
}
pre

It uses a mixin called
bc. {color:#295646;}.text-emphasis-variant and pass the color as parameter to define the text color. In the my-variables.less global settings section, we defined
bc. {color:#295646;}@state-success-text,
bc. {color:#295646;}@state-info-text as a white color
bc. {color:#295646;}#fff, so that’s why our text with
bc. {color:#295646;}.text-success,
bc. {color:#295646;}.text-info classes display as a white color. Since those
bc. {color:#295646;}@state-success-text,
bc. {color:#295646;}@state-info-text are already defined in our global settings, we don’t want to change them, so let’s override these classes in our my-theme.less:

{color:#295646;}
bc. {color:#295646;}// Typography
// ------------------------------
h1, h2, h3, h4, h5, h6 {
    text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
}

.text-primary, .text-primary:hover { .text-emphasis-variant(@brand-primary);
}

.text-success, .text-success:hover { .text-emphasis-variant(@brand-success);
}

.text-danger, .text-danger:hover { .text-emphasis-variant(@brand-danger);
}

.text-warning, .text-warning:hover { .text-emphasis-variant(@brand-warning);
}

.text-info, .text-info:hover { .text-emphasis-variant(@brand-info);
}
pre

Notice that we passed the
bc. {color:#295646;}@brand-success,
bc. {color:#295646;}@brand-info variables as the text color, and we also added a text shadow for our
bc. {color:#295646;}

to
bc. {color:#295646;}

heading tags to make those look prettier. We also want to override the text color of background contextual color classes, e.g.
bc. {color:#295646;}.bg-success,
bc. {color:#295646;}.bg-info, etc, currently they are using the default
bc. {color:#295646;}@text-color, which is a gray color
bc. {color:#295646;}#E5E5E5, as the text color. They don’t match well with our
bc. {color:#295646;}.bg-warning,
bc. {color:#295646;}.bg-success background color, so again in my-theme.less, let’s change the text color to white -
bc. {color:#295646;}#fff. This will make them stand out.

{color:#295646;}
bc. {color:#295646;}.bg-success {
    color: #fff;
}
.bg-info {
    color: #fff;
}
.bg-warning {
    color: #fff;
}
.bg-danger {
    color: #fff;
}
pre

OK, for this typography part, we made changes in both my-variables.less and my-theme.less, let’s recompile our theme:

{color:#295646;}
bc. {color:#295646;}$ lessc my-theme.less my-theme.css
pre

Refresh our theme-styles.html page, now our typography section looks like below:

Compared to the previous one, this one looks much better. That’s all we need for this typography section, now let’s move on to Navbar.

Navbar

Let’s take a look at its current appearance:

It’s not bad, but since we are making a dark-color theme, I think we should make the color of
bc. {color:#295646;}.navbar-default class match the dark background color, so let’s change the background color of
bc. {color:#295646;}.navbar-default to our
bc. {color:#295646;}@brand-secondary, and change the background color of
bc. {color:#295646;}.navbar-inverse to some gray-like color. We can find which variable to override in the “Navbar” section of Bootstrap’s variables.less file, then override them. Below are variables we add to my-variables.less:

{color:#295646;}
bc. {color:#295646;}// Navbar
// ------------------------------
@navbar-height:                    60px;

navbar-default-color: text-color;
navbar-default-bg: brand-secondary;
navbar-default-link-color: text-color;
navbar-default-link-hover-color: #fff; navbar-default-link-hover-bg: transparent;
navbar-default-link-active-color: #fff; navbar-default-link-active-bg: transparent;

navbar-inverse-color: body-bg;
navbar-inverse-bg: lighten(text-color, 5%);
navbar-inverse-link-color: brand-secondary;
navbar-inverse-link-hover-color: darken(brand-secondary, 10%);
navbar-inverse-link-hover-bg: transparent; navbar-inverse-link-active-color: navbar-inverse-link-hover-color; navbar-inverse-link-active-bg: transparent;

navbar-inverse-brand-hover-color: navbar-inverse-link-hover-color;
pre

And I’ll also change the input box and badge’s colors in both of these navbars, so let’s define some classes in my-theme.less file:

{color:#295646;}
bc. {color:#295646;}// Navbar
// ------------------------------
.navbar {
    border: none;
&-default { .badge { background-color: brand-primary; } .box-shadow(0px 1px 1px 0px rgba(0, 0, 102, 0.1)); input.form-control { background-color: lighten(brand-secondary, 5%); } } &-inverse { .badge { background-color: brand-secondary; } .box-shadow(1px 0px 6px 0px rgba(0, 0, 0, 0.6)); input.form-control { background-color: #eee; border-color: #ccc; &:focus { color: brand-secondary; } } } } pre

We are all set for these Navbar components, now it looks like below:

I really like it! Notice if you want to make more changes, you can first check the “Navbar” section in Bootstrap’s variables.less to find variables to override, then check the current Navbar’s classes defined in Bootstrap’s navbar.less file, pick some and change their CSS properties. This is also the method we used to make customizations in the above Typography section.

Buttons

We are going to apply the same method: first override variables related to buttons in my-variables.less, then make more customizations in my-theme.less if necessary. During this process, Bootstrap’s original variables.less and buttons.less files will be our reference.

Here are some variables we add in my-variables.less:

{color:#295646;}
bc. {color:#295646;}// Buttons
// ------------------------------
@btn-default-color:             #fff;
@btn-default-bg:                @brand-secondary;
@btn-default-border:            darken(@btn-default-bg, 5%);
pre

And in my-theme.less:

{color:#295646;}
bc. {color:#295646;}// Buttons
// ------------------------------
.btn {
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
&-link { text-shadow: none; box-shadow: none; } } pre

Notice I also added some text shadow and box shadow effects for buttons. Now let’s recompile my-theme.less to my-theme.css then view the changes, recall our button section’s previous appearance is:

After we made the change, now it looks like below:

Forms

The current look of the forms section:

It seems we need to change the input box’s background color, and apparently also add some changes to make
bc. {color:#295646;}.has-warning,
bc. {color:#295646;}.has-error, etc. classes work (notice currently the input boxes with those 2 classes look no different with the normal one). To make those changes, Bootstrap’s variables.less, forms.less and input-groups.less files are our reference. Here are the variables we override in my-variables.less:

{color:#295646;}
bc. {color:#295646;}// Forms
// ------------------------------
@input-bg:                  @brand-secondary;
@input-color:               @text-color;
@input-border:              darken(@brand-secondary, 5%);
@input-border-focus:        lighten(@brand-secondary, 10%);
@input-bg-disabled:         desaturate(@brand-secondary, 10%);

legend-color: text-color;
legend-border-color: brand-secondary;
pre

And in my-theme.less:

{color:#295646;}
bc. {color:#295646;}
// Forms
// ------------------------------
.has-warning {
    .form-control-validation(@text-color: @brand-warning; @border-color: @brand-warning; @background-color: @input-bg);
}

.has-error { .form-control-validation(text-color: brand-danger; border-color: brand-danger; background-color: input-bg);
}

.has-success { .form-control-validation(text-color: brand-success; border-color: brand-success; background-color: input-bg);
}

.input-group-addon:first-child { background-color: brand-secondary; color: text-color;
}
pre

In the above code, for the
bc. {color:#295646;}.has-warning,
bc. {color:#295646;}.has-error and
bc. {color:#295646;}.has-success classes, we use Bootstrap’s mixin called
bc. {color:#295646;}.form-control-validation .

Now let’s compile my-theme.less and view the changes:

Compare it with the previous screenshot, the new one looks great and totally matches our dark-color theme!

Tables

The table section’s current look:

We only need to add some variables in my-variables.less file like below (no extra code in my-theme.less):

{color:#295646;}
bc. {color:#295646;}// Table
// ------------------------------
@table-bg:                  transparent;
@table-bg-accent:           @brand-secondary;
@table-bg-hover:            lighten(@brand-secondary, 3%);
@table-bg-active:           @table-bg-hover;
@table-border-color:        lighten(@brand-secondary, 3%);
pre

Recompile our theme css file and view the changes:

If you want to make more changes, take a look at variables related to table in Bootstrap’s variables.less and tables.less file.

Tabs and Pills

This section’s current appearance:

To make the change, the “Navs” section in Bootstrap’s variables.less and its navs.less file will be our references. Let’s make changes in both my-variables.less and my-theme.less. In my-variables.less:

{color:#295646;}
bc. {color:#295646;}// Nav
// ------------------------------
@nav-link-hover-bg:                             @brand-secondary;

nav-tabs-border-color: brand-secondary;
nav-tabs-link-hover-border-color: brand-secondary;

nav-tabs-active-link-hover-bg: brand-secondary;
nav-tabs-active-link-hover-color: #fff; nav-tabs-active-link-hover-border-color: @brand-secondary;

nav-tabs-justified-link-border-color: brand-secondary;
nav-tabs-justified-active-link-border-color: brand-secondary;
pre

In my-theme.less:

{color:#295646;}
bc. {color:#295646;}// Nav
// ------------------------------
.nav {
    .open > a {
        &,
        &:hover,
        &:focus {
            background-color: @nav-link-hover-bg;
            border-color: @nav-link-hover-bg;
        }
    }
}

.nav-tabs { > li > a { color: text-color; &:hover { background-color: brand-secondary; } }
}

.nav-pills { > li > a { color: text-color; &:hover { background-color: brand-secondary; } }
}
pre

Recompile our theme CSS file, we now have:

Breadcrumb

For this component, the “Breadcrumbs” section in Bootstrap’s variables.less and its breadcrumbs.less file will be our references. Here I only want to make some changes for its color, so I just need to override some color variables in my-variable.less (no extra code in my-theme.less):

{color:#295646;}
bc. {color:#295646;}// Breadcrumb
// ------------------------------
@breadcrumb-bg:                 @brand-secondary;
@breadcrumb-color:              @text-color;
@breadcrumb-active-color:       @text-color;
pre

Previous appearance:

Now:

Pagination

Like the Breadcrumb component, I only want to change the color of pagination, so in my-variables.less I add:

{color:#295646;}
bc. {color:#295646;}// Pagination
// ------------------------------
@pagination-color:                  @text-color;
@pagination-bg:                     @brand-secondary;
@pagination-border:                 transparent;

pagination-hover-color: #fff; pagination-hover-bg: darken(brand-secondary, 5%); pagination-hover-border: transparent;

pagination-active-color: #fff; pagination-active-bg: brand-primary; pagination-active-border: transparent;

pagination-disabled-color: darken(text-color, 20%);
pagination-disabled-bg: desaturate(brand-secondary, 10%);
@pagination-disabled-border: transparent;
pre

Before:

After:

Again, if you want to make more changes, check the variables related to pagination in Bootstrap’s variables.less file and classes in pagination.less file.

List groups

Only some color variables need to be overwritten in my-variables.less:

{color:#295646;}
bc. {color:#295646;}// List group
// ------------------------------
@list-group-bg:                     @brand-secondary;
@list-group-border:                 lighten(@list-group-bg, 3%);
@list-group-link-heading-color:     @text-color;
@list-group-link-color:             @text-color;
@list-group-link-hover-color:       @text-color;
@list-group-hover-bg:               @list-group-border;
pre

Before:

After:

Panels

In the beginning we showed the current look of the Panels component:

Here are some variables I overrode in my-variables.less:

{color:#295646;}
bc. {color:#295646;}// Panels
// ------------------------------
// ## panel contextual color
@panel-success-text:            #fff;
@panel-success-heading-bg:      @brand-success;

panel-warning-text: #fff; panel-warning-heading-bg: @brand-warning;

panel-danger-text: #fff; panel-danger-heading-bg: @brand-danger;

panel-info-text: #fff; panel-info-heading-bg: @brand-info;

panel-bg: brand-secondary;

// ## Border color within panels
panel-inner-border: transparent; panel-footer-bg: darken(@brand-secondary, 5%);

panel-default-border: transparent; panel-default-heading-bg: darken(@brand-secondary, 5%);

panel-primary-border: transparent; panel-success-border: transparent;
panel-info-border: transparent; panel-warning-border: transparent;
@panel-danger-border: transparent;
pre

And code added in my-theme.less:

{color:#295646;}
bc. {color:#295646;}// Panels
// ------------------------------
.panel {
    border: none;
    &-default > .panel-heading {
        color: @text-color;
    }
}
pre

Recompile our theme file and view the change:

Like other components, if you want to make more customizations, take a look at the “Panels” section defined in Bootstrap’s variables.less and all classes defined in panels.less.

Wells

Current appearance:

I only need to change some color variables in my-variables.less:

{color:#295646;}
bc. {color:#295646;}// Wells
// ------------------------------
@well-bg:       @brand-secondary;
@well-border:   lighten(@brand-secondary, 5%);

pre

Now it becomes:

Modals

Current appearance:

I added some variables in my-variables.less:

{color:#295646;}
bc. {color:#295646;}// Modals
// ------------------------------
@modal-content-bg:                      @brand-secondary;
@modal-content-border-color:            transparent;
@modal-content-fallback-border-color:   transparent;

modal-backdrop-bg: #000; modal-backdrop-opacity: .5;
modal-header-border-color: body-bg;
modal-footer-border-color: modal-header-border-color;
pre

And classes in my-theme.less:

{color:#295646;}
bc. {color:#295646;}// Modals
// ------------------------------
.modal {
    padding: 0;
    &-header,
    &-footer {
        background-color: darken(@brand-secondary, 5%);
        border: none;
    }
}
pre

Its new appearance:

Beyond those components, I also added some other minor changes which are not listed above, but that’s all the major changes we made. Congratulations! To recap, to make a theme, the process we utilized is:

  1. Define some variables as global settings: which font typeface do we choose? what color do we use for background color and default text color? what color do we use for contextual colors? how about the padding values? do we need rounded corner for components? etc. You can review this part in the beginning of chapter 3.4 and 3.5;
  1. Once we set the global settings variables, now we can go through each section in theme-styles.html to do more customizations, and we can use Bootstrap’s variables.less and .less as our references. For example, if we want to customize the “panels” component, we may want to override variables related to panels defined in variables.less and classes defined in panels.less;
  1. After we go through each section or components listed in theme-styles.html, we will finally have our customized theme.

Practice

  1. At this book’s repository folder make-bootstrap-themes, open a command/terminal window, then use
    bc. {color:#295646;}http-server to start a web server.
  1. Visit web page at: http://127.0.0.1:8080/chapter3/3.5/theme-styles.html, then you can see what our new theme looks like.
  1. Learn the code in [_ my-variables.less_] and [_ my-theme.less_].

Challenge

Can you follow the method we learned in this section to make a whole new theme? As references, you can:

  • Pick fonts from Google font: https://fonts.google.com/
  • Pick colors from Colorhunt: http://colorhunt.co/

Chapter 4 – More Customizations

In chapter 3 we created 2 themes based on the existing classes defined by Bootstrap, and they look great. However, to apply a theme to a real product, or sell a theme package to customers, sometimes using those pre-defined classes in Bootstrap is not enough. We also need to create some extra classes and use some plugins to power it up.

In this chapter, we are going to first make a new theme using the method we learned in chapter 3, and this will help us get more familiar with the process of making a theme. Then we will add extra classes to this theme. These classes are not defined by Bootstrap, but they are very handy and will boost up our theme. We will also introduce some Javascript plugins which will make components look more professional. Lastly, we will touch a little on how to organize files if we want to sell our themes on the marketplace. Let’s get started.

4.1 Starter Theme

Let’s first make a simple theme and then later we will power it up with some extra CSS styles and Javascript plugins. To make this theme, we are going to use the same method we used in the previous chapter.

  1. Page body’s background color: since this theme will be a light-color theme, I’ll keep the body’s background as white.
  1. Font styles: I’ll use a font called “Dosis” as the main font type, it can be imported from Google Font. I’ll set the heading font weight to be 700 and the main font color to be
    bc. {color:#295646;}#333333.
  1. Contextual colors: I’ll use the color
    bc. {color:#295646;}#ed745e for the primary color,
    bc. {color:#295646;}#2eb872 for the success color,
    bc. {color:#295646;}#497cb1 for the info color,
    bc. {color:#295646;}#f89b20 for the warning color, and
    bc. {color:#295646;}#e03e36 for the danger color.
  1. Padding size and border radius: for components, I’ll set the base vertical padding size to be 8px, and horizontal padding to be 16px. I’ll also remove the rounded corners.
  1. Override variables for some specific components: I’ll change some variables for the navbar and pagination components.

Here are variables we defined in my-variables.less:

{color:#295646;}
bc. {color:#295646;}// font styles
@font-family-sans-serif: Dosis, Helvetica, Arial, sans-serif;
@headings-font-weight: 700;
@text-color: #333;

// brand contextual colors
brand-primary: #ed745e; brand-success: #2eb872;
brand-info: #497cb1; brand-warning: #f89b20;
@brand-danger: #e03e36;

// state contextual colors
state-success-text: #fff; state-success-bg: brand-success; state-success-border: lighten(@state-success-bg, 5%);

state-info-text: #fff; state-info-bg: brand-info; state-info-border: lighten(@state-info-bg, 5%);

state-warning-text: #fff; state-warning-bg: brand-warning; state-warning-border: lighten(@state-warning-bg, 5%);

state-danger-text: #fff; state-danger-bg: brand-danger; state-danger-border: lighten(@state-danger-bg, 5%);

btn-default-color: #333; btn-default-bg: #f9f9f9;
btn-default-border: darken(btn-default-bg, 10%);

btn-primary-border: brand-primary;

// Padding and border radius for components
padding-base-vertical: 8px; padding-base-horizontal: 16px;

padding-large-vertical: 12px; padding-large-horizontal: 24px;

padding-small-vertical: 6px; padding-small-horizontal: 12px;

padding-xs-vertical: 2px; padding-xs-horizontal: 6px;

border-radius-base: 0; border-radius-large: 0;
@border-radius-small: 0;

@pager-border-radius: 0;

// Navbar
@navbar-height: 60px;

navbar-default-color: brand-primary;
navbar-default-bg: #fff; navbar-default-link-color: #555;
navbar-default-link-hover-color: brand-primary;
navbar-default-link-hover-bg: transparent; navbar-default-link-active-color: brand-primary; navbar-default-link-active-bg: transparent;

navbar-inverse-color: #fff; navbar-inverse-bg: darken(brand-primary, 5%); navbar-inverse-link-color: #f5f5f5;
navbar-inverse-link-hover-color: #fff; navbar-inverse-link-hover-bg: transparent;
navbar-inverse-link-active-color: navbar-inverse-link-hover-color;
@navbar-inverse-link-active-bg: transparent;

// Pagination
pagination-disabled-color: #ddd; pagination-disabled-bg: #fafafa;
pre

Then in my-theme.less we have:

{color:#295646;}
bc. {color:#295646;}@import url('https://fonts.googleapis.com/css?family=Dosis:400,500,600,700');
@import "path/to/bootstrap-3.3.7/less/bootstrap.less";
@import "my-variables.less";
pre

So we imported the “Dosis” font and our own my-variables.less, after we compile it to my-theme.css, our theme-styles.html page looks like this:

It is not bad, but we still need to fix some styles and customize some components. For example, in the first screenshot, the font color of our contextual text classes, e.g.

{color:#295646;}.text-primary,
bc. {color:#295646;}.text-success are all white. We need to fix that, so we add following code to the [_my-theme.less_] file:
{color:#295646;}
bc. {color:#295646;}// Typography
.text-primary, .text-primary:hover {
    .text-emphasis-variant(@brand-primary);
}

.text-success, .text-success:hover { .text-emphasis-variant(@brand-success);
}

.text-danger, .text-danger:hover { .text-emphasis-variant(@brand-danger);
}

.text-warning, .text-warning:hover { .text-emphasis-variant(@brand-warning);
}

.text-info, .text-info:hover { .text-emphasis-variant(@brand-info);
}
pre

Also I’ll add some customizations for other components like Navbar and Alerts, but I’ll skip listing the code here, basically I am just following the process we did in chapters 3.4 and 3.5. Also, since in this chapter we will mainly focus on the “additional classes and plugins”, we will just make a simple theme in this section, if you check the code in my-theme.less file under the repository folder chapter4/4.1, there are only around 100 lines of code.

Although it is a simple theme, the final version we have still looks neat:

Practice

Start a server to see all the components under this theme:

  1. At the code repo folder make-bootstrap-themes, open a command/terminal window, then use
    bc. {color:#295646;}http-server to start web server.
  1. Visit web page at: http://127.0.0.1:8080/chapter4/4.1/theme-styles.html, then you can see what our new theme look like.
  1. Learn the code in [_ my-variables.less_] and [_ my-theme.less_].

4.2 Additional Classes

In this section we are going to add some power-ups. This includes some additional styles, components and animation effects. They are very helpful when we are building a real website using our theme. We will first create 2 files, my-mixins.less to save some extra mixins and my-extra-styles.less to save extra styles.

Since our my-extra-styles.less defines additional styles for the theme we make in section 4.1, let’s first import some files to set it up, at the beginning of file my-extra-styles.less let’s add the code below:

{color:#295646;}
bc. {color:#295646;}@import "path/to/bootstrap-3.3.7/less/variables.less";
@import "path/to/bootstrap-3.3.7/less/mixins.less";
@import "path/to/chapter4/4.1/my-variables.less";
@import "my-mixins.less";
pre

We imported Bootstrap’s variables.less and our own my-variables.less files, also imported Bootstrap’s mixins.less and our own my-mixins.less (though currently it is empty) files. Later we will use those variables and mixins to define some extra styles and components.

4.2.1 Top navigation bar

Suppose we are building a website for a real product, it is common that we design the index page like this: a navigation bar at the top, followed by a beautiful banner image, and after it there is a “product features” section, etc.

If you browsed the theme-styles.html page in section 4.1, you can see the current navigation bar under the starter theme:

So if we use this theme to build the index page, we may write the HTML code like this:

{color:#295646;}
bc. {color:#295646;}<nav class="navbar navbar-default navbar-fixed-top">
...
</nav>
pre

The page looks like below:

The navigation bar is on top of the banner image, it does not look bad but there is a better and more popular way. When the user first opens this web page, make the background of the navigation bar be transparent, so it looks like it is a part of the banner image. As the user scrolls down the page a little, we change the navigation bar’s background back to the non-transparent color. This makes the navbar look like it “pops up” from the banner, and make it stand out of the page.

For example, when the user opens the page, at first the screen looks like:

After user scrolls down a little:

To achieve this, we need do the following things:

  1. Define an extra class which defines a transparent background color and applies it to the navbar, here I name it
    bc. {color:#295646;}.navbar-menu-top.
  1. As the user scrolls down the page a little, we remove the
    bc. {color:#295646;}.navbar-menu-top class of the navbar so it will use the style defined in the class
    bc. {color:#295646;}.navbar-default; if the user scrolls up back to the top, we add the
    bc. {color:#295646;}.navbar-menu-top class back to the navbar. To detect the “scroll down/up” page event, we need some Javascript.
  1. In the second step, when we remove or add the
    bc. {color:#295646;}.navbar-menu-top class to the navbar, its style will change immediately, to make it more smooth, we want to add some transition animation, this will make it look more pretty and professional.

Let’s do it step by step, first is adding the
bc. {color:#295646;}.navbar-menu-top class:

{color:#295646;}
bc. {color:#295646;}.navbar {
    &-menu-top {
        background: transparent;
        color: #fff;
        padding-top: 25px;
        .box-shadow(none);
.navbar-brand { font-size: 1.6em; color: #f1f1f1; padding: 10px 15px; &:visited, &:hover { color: #f1f1f1; } } .navbar-nav > li { > a { font-size:1.1em; font-weight: 500; } > a:link, > a:visited { color: #f1f1f1; } > a:hover, > a:active { color: brand-primary; } &.active > a { color: brand-primary; } } } } pre

We add the
bc. {color:#295646;}.navbar-menu-top class, and also changed the
bc. {color:#295646;}.navbar-brand and
bc. {color:#295646;}.navbar-nav > li styles under it. After compiling this Less code to plain CSS, we apply it to our navbar:

{color:#295646;}
bc. {color:#295646;}<nav class="navbar navbar-default navbar-fixed-top navbar-menu-top" id="navbar-top">
...
</nav>
pre

We also assign an id named “navbar-top” to this navbar, which will be used in the second step: using Javascript to remove and add the
bc. {color:#295646;}.navbar-menu-top class when the user scrolls up and down the page:

{color:#295646;}
bc. {color:#295646;}<script>
    $(window).scroll(function() {
        if ($(this).scrollTop() > 80) {
            $("#navbar-top").removeClass("navbar-menu-top");
        } else {
            $("#navbar-top").addClass("navbar-menu-top");
        }
    });
</script>
pre

What this script does is, if the user scrolls the page down more than 80 pixels, we remove the navbar’s
bc. {color:#295646;}.navbar-menu-top class, otherwise, for example, if user the scrolls back up to the top, we add this class back to the navbar.

Lastly, as we remove and add this class to the navbar, the styles apply immediately. For example, when the navbar has
bc. {color:#295646;}.navbar-menu-top, it has a transparent background, when we use Javascript to remove this class, its background suddenly become non-transparent with a white color. We want to make this transition more smooth. Thanks to CSS3 transitions, we can achieve it by simply defining and applying some CSS:

{color:#295646;}
bc. {color:#295646;}.transition-eio {
    .transition(all 0.3s ease-in-out);
}
pre

Here we used a mixin
bc. {color:#295646;}.transition which is imported from Bootstrap’s mixins.less, after compiled the above code, it becomes:

{color:#295646;}
bc. {color:#295646;}.transition-eio {
    -webkit-transition: all 0.3s ease-in-out;
    -o-transition: all 0.3s ease-in-out;
    transition: all 0.3s ease-in-out;
}
pre

Then we can just add this class to our navbar:

{color:#295646;}
bc. {color:#295646;}<nav class="navbar navbar-default navbar-fixed-top navbar-menu-top transition-eio" id="navbar-top">
...
</nav>
pre

Now when the navbar uses or drops the
bc. {color:#295646;}.navbar-menu-top class, the browser will do a smooth transition for us. This
bc. {color:#295646;}.transition-eio we defined is quite handy. We can actually use it not only as a class but also as a mixin. We can apply it wherever we want to add a smooth transition for style changing. For example, we can use it as a mixin to the links in the previous navbar code written in Less :

{color:#295646;}
bc. {color:#295646;}.navbar {
    a {
        .transition-eio; // use it as a mixin
    }
   ...
}
pre

With this mixin, when the user puts their mouse over a link, instead of immediately changing the link color, the browser will do a smooth color transition in 0.3 seconds.

To recap, what we did here includes 3 parts:

  1. Define a
    bc. {color:#295646;}.navbar-menu-top class and apply it to navbar.
  1. Write Javascript to detect the “scroll down/up” event to remove/add
    bc. {color:#295646;}.navbar-menu-top class.
  1. Define a
    bc. {color:#295646;}.transition-eio class and apply it to the navbar to make the style transition more smooth.

4.2.2 Spacing Utilities

When we are making a web page, there is often a time when we want to add spaces between elements. For example, we put an icon and some text next to it, and we want a little spacing between this icon and the text. Instead of defining an inline
bc. {color:#295646;}margin-right style to that little icon in the CSS file, it will be handy if there are some predefined classes we can simply apply to this icon, so here we will define some spacing utility classes.

Take
bc. {color:#295646;}margin-right for example, we will add 5 classes for it:
bc. {color:#295646;}.mr-zero,
bc. {color:#295646;}.mr-xs,
bc. {color:#295646;}.mr-sm,
bc. {color:#295646;}.mr-md and
bc. {color:#295646;}.mr-lg. Specifically, they should be something like this:

{color:#295646;}
bc. {color:#295646;}.mr-zero {margin-right: 0px}
.mr-xs {margin-right: 5px}
.mr-sm {margin-right: 12px}
.mr-md {margin-right: 20px}
.mr-lg {margin-right: 30px}
pre

I set the pixels for xs to be 5px, sm to be 12px, but you can use different numbers. Then in the above example, we can apply it to the icon:

{color:#295646;}
bc. {color:#295646;}<i class="fa fa-bell mr-xs"></i> <span>Some Text Here</span>
pre

These are 5 classes for
bc. {color:#295646;}margin-right, and we will define similar classes for
bc. {color:#295646;}margin-left,
bc. {color:#295646;}margin-top,
bc. {color:#295646;}margin-right, also for
bc. {color:#295646;}padding-top,
bc. {color:#295646;}padding-bottom,
bc. {color:#295646;}padding-left and
bc. {color:#295646;}padding-right. Since each one has 5 classes and they are using the same pixels for
bc. {color:#295646;}*-xs,
bc. {color:#295646;}*-sm, etc., instead of manually writing every class, it will be helpful if we define a mixin first, then call it to generate those spacings. Specifically, let’s define a mixin called
bc. {color:#295646;}createSpacing in the my-mixins.less file:

{color:#295646;}
bc. {color:#295646;}@spacing-size: zero 0px, xs 5px, sm 12px, md 20px, lg 30px;

.createSpacing(prefix, property, iterator:1) when(iterator <= length(spacing-size)) { name: extract(extract(spacing-size, iterator),1); value: extract(extract(spacing-size, iterator),2); .{prefix}[email protected]{name} { {property}: value; } .createSpacing(prefix, property, (@iterator + 1));
}
pre

We use an iterator to loop through
bc. {color:#295646;}@spacing-size (if you are familiar with a programming language like Javascript, it is more like a recursive function call). To use it, we can write the code below in my-extra-styles.less:

{color:#295646;}
bc. {color:#295646;}.createSpacing(mt, margin-top);
pre

It is compiled to:

{color:#295646;}
bc. {color:#295646;}.mt-zero {margin-top: 0px}
.mt-xs {margin-top: 5px}
.mt-sm {margin-top: 12px}
.mt-md {margin-top: 20px}
.mt-lg {margin-top: 30px}
pre

We can do the same thing for other margins and paddings. Let’s add them in my-extra-styles.less:

{color:#295646;}
bc. {color:#295646;}// mt-zero, mt-xs, mt-sm, mt-md, mt-lg
.createSpacing(mt, margin-top);
.createSpacing(mb, margin-bottom);
.createSpacing(ml, margin-left);
.createSpacing(mr, margin-right);

// pt-zero, pt-xs, pt-sm, pt-md, pt-lg
.createSpacing(pt, padding-top);
.createSpacing(pb, padding-bottom);
.createSpacing(pl, padding-left);
.createSpacing(pr, padding-right);
pre

After compilation, there will be 40 classes generated for spacing, like
bc. {color:#295646;}.mt-xs,
bc. {color:#295646;}.mr-sm,
bc. {color:#295646;}.pt-md,
bc. {color:#295646;}.pl-lg, etc.

4.2.3 Contextual Outline Buttons

Currently, we have contextual buttons like this:

In this section we will add another group of outline buttons, including the
bc. {color:#295646;}.btn-default-outline,
bc. {color:#295646;}.btn-primary-outline,
bc. {color:#295646;}.btn-success-outline,
bc. {color:#295646;}.btn-info-outline,
bc. {color:#295646;}.btn-warning-outline and
bc. {color:#295646;}.btn-danger-outline classes.

{color:#295646;}
bc. {color:#295646;}.btn {
    .transition-eio;
&-default-outline { .button-outline(#555); } &-primary-outline { .button-outline(brand-primary); } &-success-outline { .button-outline(brand-success); } &-info-outline { .button-outline(brand-info); } &-warning-outline { .button-outline(brand-warning); } &-danger-outline { .button-outline(@brand-danger); } } pre

Here we use a mixin
bc. {color:#295646;}.button-outline which is defined in my-mixins.less, we also use
bc. {color:#295646;}.transition-eio as a mixin, such that when the user hover over the button, the background color changes smoothly with an animation.

Here is our outline buttons’ appearance:

4.2.4 Contextual Breadcrumb

In this section, let’s add some contextual breadcrumb classes including
bc. {color:#295646;}.breadcrumb-primary,
bc. {color:#295646;}.breadcrumb-success,
bc. {color:#295646;}.breadcrumb-info,
bc. {color:#295646;}.breadcrumb-warning and
bc. {color:#295646;}.breadcrumb-danger.

{color:#295646;}
bc. {color:#295646;}.breadcrumb-primary {
    .breadcrumb-contextual(@brand-primary);
}
.breadcrumb-success {
    .breadcrumb-contextual(@brand-success);
}
.breadcrumb-info {
    .breadcrumb-contextual(@brand-info);
}
.breadcrumb-warning {
    .breadcrumb-contextual(@brand-warning);
}
.breadcrumb-danger {
    .breadcrumb-contextual(@brand-danger);
}
pre

Each calls a mixin
bc. {color:#295646;}.breadcrumb-contexual which is defined in the my-mixins.less file. To use those classes, for example,
bc. {color:#295646;}.breadcrumb-primary, we can write code like below:

{color:#295646;}
bc. {color:#295646;}<ol class="breadcrumb breadcrumb-primary">
    <li><a href="#"><i class="fa fa-home"></i> Home</a></li>
    <li><a href="#">Users</a></li>
    <li class="active">Subscribers</li>
</ol>
pre

Our contextual breadcrumbs’ appearance:

4.2.5 Contextual Pagination

Similar to breadcrumbs, let’s add contextual paginations:

{color:#295646;}
bc. {color:#295646;}.pagination-primary {
    .pagination-contextual(@brand-primary);
}
.pagination-success {
    .pagination-contextual(@brand-success);
}
.pagination-info {
    .pagination-contextual(@brand-info);
}
.pagination-warning {
    .pagination-contextual(@brand-warning);
}
.pagination-danger {
    .pagination-contextual(@brand-danger);
}
pre

The
bc. {color:#295646;}.pagination-contextual mixin is also defined in my-mixins.less, you can check the source code there. We can use those pagination classes along with Bootstrap’s
bc. {color:#295646;}.pagination class like below:

{color:#295646;}
bc. {color:#295646;}<ul class="pagination pagination-primary">
...
</ul>
pre

Here are our contextual paginations appearance:

4.2.6 Contextual Panel Topping

Under the current theme we can use contextual panel classes like
bc. {color:#295646;}.panel-primary,
bc. {color:#295646;}.panel-success,
bc. {color:#295646;}.panel-warning, etc. along with the
bc. {color:#295646;}.panel class:

{color:#295646;}
bc. {color:#295646;}<div class="panel panel-primary">
    <div class="panel-heading">
        ...
    </div>
    <div class="panel-body">
        ...
    </div>
</div>
pre

Here I am going to add another group of contextual panel classes which only change the top border color, I name them as
bc. {color:#295646;}.panel-default-top,
bc. {color:#295646;}.panel-primary-top,
bc. {color:#295646;}.panel-success-top,
bc. {color:#295646;}.panel-info-top,
bc. {color:#295646;}.panel-warning-top and
bc. {color:#295646;}.panel-danger-top. To use them in the above example, we can just replace the
bc. {color:#295646;}.panel-primary class with the
bc. {color:#295646;}.panel-primary-top class.

{color:#295646;}
bc. {color:#295646;}<div class="panel panel-primary-top">
...
</div>
pre

Their appearance:

The code is also simple:

{color:#295646;}
bc. {color:#295646;}// Panel
.panel-default-top {
    .panel-contextual-pos(#555, top);
}
.panel-primary-top {
    .panel-contextual-pos(@brand-primary, top);
}
.panel-success-top {
    .panel-contextual-pos(@brand-success, top);
}
.panel-info-top {
    .panel-contextual-pos(@brand-info, top);
}
.panel-warning-top {
    .panel-contextual-pos(@brand-warning, top);
}
.panel-danger-top {
    .panel-contextual-pos(@brand-danger, top);
}
pre

You may notice that here we are using a mixin named
bc. {color:#295646;}.panel-contextual-pos. This mixin is also defined in the my-mixins.less file, and we can use it as well to define panel classes which only change the bottom border color, like this:

{color:#295646;}
bc. {color:#295646;}.panel-danger-bottom {
    .panel-contextual-pos(@brand-danger, bottom);
}
pre

Similarly, we can define the
bc. {color:#295646;}.panel-default-bottom,
bc. {color:#295646;}.panel-primary-bottom,
bc. {color:#295646;}.panel-success-bottom,
bc. {color:#295646;}.panel-info-bottom and
bc. {color:#295646;}.panel-warning-bottom classes. This should be easy and I’ll leave this as an exercise for you.

4.2.7 Contextual Outline Alerts

Like the outline buttons in 4.2.3, in this section we are going to define outline alerts:

{color:#295646;}
bc. {color:#295646;}// Alert
.alert-success-outline {
    .alert-variant(lighten(@brand-success, 53%), @brand-success, darken(@brand-success, 5%));
}
.alert-info-outline {
    .alert-variant(lighten(@brand-info, 48%), @brand-info, darken(@brand-info, 5%));
}
.alert-warning-outline {
    .alert-variant(lighten(@brand-warning, 43%), @brand-warning, darken(@brand-warning, 5%));
}
.alert-danger-outline {
    .alert-variant(lighten(@brand-danger, 43%), @brand-danger, darken(@brand-danger, 5%));
}
pre

The
bc. {color:#295646;}.alert-variant mixin above is imported from Bootstrap’s
bc. {color:#295646;}mixins.less, here we use it to define alerts with different background colors, border colors and text colors. We can compare the non-outline version and the outline version alerts:

Divs with the
bc. {color:#295646;}.alert and
bc. {color:#295646;}.alert-warning,
bc. {color:#295646;}.alert-success,
bc. {color:#295646;}.alert-danger,
bc. {color:#295646;}.alert-info classes:

Divs with the
bc. {color:#295646;}.alert and
bc. {color:#295646;}.alert-warning-outline,
bc. {color:#295646;}.alert-success-outline,
bc. {color:#295646;}.alert-danger-outline and
bc. {color:#295646;}.alert-info-outline classes:

4.2.8 Contextual List Group Item

The current list group item looks like this:

We are going to add 4 classes including
bc. {color:#295646;}.list-group-item-success,
bc. {color:#295646;}.list-group-item-info,
bc. {color:#295646;}.list-group-item-warning and
bc. {color:#295646;}.list-group-item-danger.

{color:#295646;}
bc. {color:#295646;}.list-group-item-success {
    .list-group-item-contextual(@brand-success);
}
.list-group-item-info {
    .list-group-item-contextual(@brand-info);
}
.list-group-item-warning {
    .list-group-item-contextual(@brand-warning);
}
.list-group-item-danger {
    .list-group-item-contextual(@brand-danger);
}
pre

The mixin
bc. {color:#295646;}.list-group-item-contextual is defined in my-mixins.less:

{color:#295646;}
bc. {color:#295646;}.list-group-item-contextual(@color) {
    background-color: @color;
    border: 1px solid @color;
    .badge {
        background-color: #fff;
        color: @color;
    }
}
pre

Then we can use it in HTML like this:

{color:#295646;}
bc. {color:#295646;}<div class="list-group">
    <a href="#" class="list-group-item list-group-item-success">
        <span class="badge">2</span> Link item 1
    </a>
    <a href="#" class="list-group-item"> Link item 2 </a>
</div>
pre

Their appearance:

4.2.9 Ribbon

Ribbon is an interesting and useful component, a common use case is adding it to a card to make the card stand out. In case you are not familiar with it, here is what we are going to make:

We need to add 3 classes:

#
bc. {color:#295646;}.ribbon-container: we will apply it to the card-like container, the key CSS property in this class is
bc. {color:#295646;}position:relative.

#
bc. {color:#295646;}.ribbon: a div which holds the actual ribbon, the key CSS properties in it are
bc. {color:#295646;}position:absolute; right:-1px; top:-1px; overflow:hidden. This div helps to locate the actual ribbon.

#
bc. {color:#295646;}.ribbon .text: class for the actual ribbon-look element. It includes the font color, background color properties, and most importantly, rotates the element 45 degrees. To achieve this, we can use CSS3’s property
bc. {color:#295646;}transform: rotate(45deg), or we can just call the
bc. {color:#295646;}.rotate(45deg) mixin which is imported from Bootstrap’s mixins.less.

{color:#295646;}
bc. {color:#295646;}.ribbon-container {
    position: relative;
}

.ribbon { position: absolute; right: -1px; top: -1px; z-index: 1; overflow: hidden; width: 75px; height: 75px; .text { font-size: 14px; font-weight: bold; color: #FFF; text-transform: uppercase; text-align: center; line-height: 20px; .rotate(45deg); width: 100px; display: block; background: #555; position: absolute; top: 15px; right: -25px; }
}
pre

Once these classes are defined, for contextual ribbons we only need to set the background color for the
bc. {color:#295646;}.text class, for example:

{color:#295646;}
bc. {color:#295646;}.ribbon-primary {
    .text {
        background: @brand-primary;
    }
}
.ribbon-success {
    .text {
        background: @brand-success;
    }
}
pre

Then in HTML we can use this ribbon component like this:

{color:#295646;}
bc. {color:#295646;}<div class="ribbon-container">
    <h3>Some Title</h3>
    <p>Some Description</p>
    <div class="ribbon ribbon-primary">
        <span class="text">HOT!</span>
    </div>
</div>
pre

4.2.10 Bookmark

Like ribbon, bookmark is another useful component to make card-like elements stand out. In this section we are going to make the contextual bookmark components:

We need to add following classes:

#
bc. {color:#295646;}.bookmark-container: Like the
bc. {color:#295646;}.ribbon-container class, we will apply this to the outer container, the key CSS property for it is
bc. {color:#295646;}position: relative.

#
bc. {color:#295646;}.bookmark: the actual bookmark. Here we will use a rectangle (e.g. a
bc. {color:#295646;}

tag) as the bookmark.

#
bc. {color:#295646;}.bookmark::after: this is a pseudo element, and we will define some CSS properties for it to create a white triangle at the bottom of the rectangle to simulate the bookmark’s shape.

{color:#295646;}
bc. {color:#295646;}.bookmark-container {
    position: relative;
}
.bookmark {
    display: inline-block;
    position: absolute;
    top: -1px;
    right: 12px;
    width: 28px;
    padding: 8px 0px 12px;
    color: #fff;
    background-color: #555;
    text-align: center;
&::after { content: “”; position: absolute; bottom: 0; left: 0; width: 0; height: 0; border-bottom: 6px solid #fff; border-left: 14px solid transparent; border-right: 14px solid transparent; } } pre

Then for the contextual bookmarks we only need to set the background color, for example, for the
bc. {color:#295646;}.bookmark-primary and
bc. {color:#295646;}.bookmark-success classes we have:

{color:#295646;}
bc. {color:#295646;}.bookmark-primary {
    background-color: @brand-primary;
}
.bookmark-success {
    background-color: @brand-success;
}
pre

To use this bookmark component, we can write HTML like this:

{color:#295646;}
bc. {color:#295646;}<div class="bookmark-container">
    <h3>Some Title</h3>
    <p> Some Description </p>
    <div class="bookmark bookmark-primary">
        <i class="fa fa-star"></i>
    </div>
</div>
pre

4.2.11 Image on hover animation

In this section we are going to add some animation effects for an image when the user moves the mouse onto it. We will add 4 types of animations:

  • Image changes its opacity, i.e. fade out a little;
  • Image changes its scale, i.e. zoom in a little;
  • Image changes its scale and rotate a small degree;
  • Image swings left and right;

The first one is simple:

{color:#295646;}
bc. {color:#295646;}.img-hover-fadeout:hover {
    .opacity(0.8);
}
pre

Here we use the
bc. {color:#295646;}.opacity mixin which is also imported from Bootstrap’s mixins.less file, then we can apply this class to an image like this:

{color:#295646;}
bc. {color:#295646;}<img src="img-source-url" class="img img-responsive img-hover-fadeout transition-eio" />
pre

Notice we applied both the
bc. {color:#295646;}.img-hover-fadeout and
bc. {color:#295646;}.transition-eio classes to the image, the
bc. {color:#295646;}.img-hover-fadeout will change the image’s opacity, and the
bc. {color:#295646;}.transition-eio class will make the change more smooth with an animation.

For the second one, changing an image’s scale is easy too:

{color:#295646;}
bc. {color:#295646;}.img-hover-scale:hover {
    .scale(1.2);
}
pre

The
bc. {color:#295646;}.scale mixin is imported from Bootstrap’s mixins.less file as well. But just using it with this class is not enough. We also need a container class such that when image zooms in, it will not exceed its container’s border:

{color:#295646;}
bc. {color:#295646;}.img-hover-container {
    overflow:hidden;
}
pre

To use this class, we can write HTML like below:

{color:#295646;}
bc. {color:#295646;}<div class="img-hover-container">
    <img src="url" class="img img-responsive img-hover-scale transition-eio" />
</div>
pre

The third one, scale and rotate:

{color:#295646;}
bc. {color:#295646;}.img-hover-scale-rotate:hover {
    .transform(scale(1.2) rotate(8deg));
}
pre

We set both the scale and rotate to the
bc. {color:#295646;}.transform mixin, this
bc. {color:#295646;}.transform mixin is defined in our own my-mixins.less file:

{color:#295646;}
bc. {color:#295646;}.transform(@string){
    -webkit-transform: @string;
    -moz-transform: @string;
    -ms-transform: @string;
    -o-transform: @string;
    transform: @string;
}
pre

Apply it to an image element:

{color:#295646;}
bc. {color:#295646;}<div class="img-hover-container">
    <img src="url" class="img img-responsive img-hover-scale-rotate transition-eio" />
</div>
pre

Then when we move the mouse over this image, it will both zoom in and rotate 8 degrees.

The last one, the swing, costs more work since CSS3 doesn’t have a pre-made swing animation. To make it work, we need first define
bc. {color:#295646;}@keyframes named “swing”:

{color:#295646;}
bc. {color:#295646;}@keyframes swing
{
    15% {
        .translate(5px; 0);
    }
    30% {
        .translate(-5px; 0);
    }
    50% {
        .translate(3px; 0);
    }
    65% {
        .translate(-3px; 0);
    }
    80% {
        .translate(2px; 0);
    }
    100% {
        .translate(0; 0);
    }
}
pre

The
bc. {color:#295646;}.translate mixin is imported from Bootstrap’s mixins.less file, the parameters of it are the horizontal offset and vertical offset. If you are interested, the
bc. {color:#295646;}.translate mixin is defined as below:

{color:#295646;}
bc. {color:#295646;}.translate(@x; @y) {
    -webkit-transform: translate(@x, @y);
    -ms-transform: translate(@x, @y);
    -o-transform: translate(@x, @y);
    transform: translate(@x, @y);
}
pre

Now for our swing class, we only need to use the keyframes we just defined:

{color:#295646;}
bc. {color:#295646;}.img-hover-swing:hover {
    .animation(swing 1s ease-in-out);
}
pre

The
bc. {color:#295646;}.animation mixin is also imported from Bootstrap’s mixins.less file:

{color:#295646;}
bc. {color:#295646;}.animation(@animation) {
    -webkit-animation: @animation;
    -o-animation: @animation;
    animation: @animation;
}
pre

Finally to use this
bc. {color:#295646;}.img-hover-swing class, we can write HTML like below, and when you move the mouse over on the image, it will swing left and right for 1 second, then stop:

{color:#295646;}
bc. {color:#295646;}<div class="img-hover-container">
    <img src="url" class="img img-responsive img-hover-swing" />
</div>
pre

Since screenshot cannot show the animations we made, you can check all 4 in a web page at the end of this section:

(When you move the mouse over on the third image, you can see it both zooms in and rotates 8 degrees)

4.2.12 Social Media Sign-in Button

In the last part we are going to include some social media sign-in buttons, it is very common to see those buttons like “Sign in with Twitter”, “Sign in with Facebook” in a website’s Sign-in and Sign-up pages. So here we will add 8 commonly used third-party sign-in buttons including for Twitter, Facebook, Google, Github, Instagram, LinkedIn, Dropbox and OpenID.

Let’s first define a
bc. {color:#295646;}.btn-social class which contains the common CSS properties for all of those sign-in buttons:

{color:#295646;}
bc. {color:#295646;}.btn-social {
    color: #fff;
    min-width: 200px;
    text-align: left;
&:hover { color: #fff; } & > .fa { margin-right: 10px; padding-right: 10px; border-right: 1px solid rgba(0, 0, 0, 0.05); width: 30px; } } pre

We defined its width, text color and the icon styles (here we are using font-awesome icons, so the
bc. {color:#295646;}.fa indicates the icon’s class), then we can just define the background color for different social media.

{color:#295646;}
bc. {color:#295646;}.btn-twitter {
    background: #55acee;
    &:hover {
        background: darken(#55acee, 10%);
    }
}

.btn-facebook { background: #3b5998; &:hover { background: darken(#3b5998, 10%); }
}
pre

We can use them in HTML like below:

{color:#295646;}
bc. {color:#295646;}<button class="btn btn-social btn-twitter">
    <i class="fa fa-twitter"></i>
    Sign in with Twitter
</button>


pre

Those 8 buttons’ appearances:

Practice

Start a server to see all the additional styles we defined:

  1. At this book’s repository folder make-bootstrap-themes, open a command/terminal window, then use
    bc. {color:#295646;}http-server to start web server.
  1. Visit web page at: http://127.0.0.1:8080/chapter4/4.2/additional-styles.html, then you can see all of our new styles and components.
  1. Learn the code in [_ my-extra-styles.less_] and [_ my-mixins.less_], also learn how we use those classes in the source code of [_ additional-styles.html_].

4.3 Plugins

In this section we will introduce some plugins that you can use along with Bootstrap, some of them are used for cool animations, some are for changing Bootstrap component’s appearance, etc.

4.3.1 Animations

Like we made the “swing” image in section 4.2, using CSS3 we can define some amazing animations. Here we are going to use a handy third-party CSS3 animation file, which is from http://www.justinaguilar.com/animations made by Justin Aguilar.

The CSS file (http://www.justinaguilar.com/animations/css/animations.css) defines several neat classes and we can simply apply them to an element to animate it. For example, suppose we have a
bc. {color:#295646;}div:

{color:#295646;}
bc. {color:#295646;}<div class="section">
    <h4>Some Title</h4>
</div>
pre

We can add a fadeIn class to it, then this div will show up with a fade-in animation:

{color:#295646;}
bc. {color:#295646;}<div class="section fadeIn">
...
</div>
pre

Even better, with Javascript we can dynamically add those animations. For example, for some elements not in the first screen, we can first set their visibility to be hidden:

{color:#295646;}
bc. {color:#295646;}<style>
    .slide-item {visibility: hidden}
</style>
...
<div class="section slide-item">
...
</div>
pre

Then as we scroll down the page a bit, we can use Javascript to add an animation class to this element, say we add a “slideUp” class to it:

{color:#295646;}
bc. {color:#295646;}$(".slide-item").each(function(){
    var itemTop = $(this).offset().top;
    var topOffset = $(window).scrollTop();
    if (itemTop < topOffset + 550) {
        $(this).addClass("slideUp");
    }
});
pre

This element (the second row in the above picture) will appear from bottom with a slide-up animation.

Above is an example for applying the “slideUp” class, but we can simply change it to other animation classes like “slideLeft”, “fadeIn”, and “expandUp” which are defined in that animations.css file.

4.3.2 Switch

It is common to use a checkbox as a switch, for example:

And on the mobile apps, people are getting used to the switch’s interface like this:

While Bootstrap3 doesn’t come with a nice-looking “switch” component like above, we can use a third-party library called Bootstrap Switch (http://bootstrapswitch.com/), which can help us easily change a checkbox to a switch-like component.

Say in HTML we have a checkbox:

{color:#295646;}
bc. {color:#295646;}<input type="checkbox" name="bs-switch" checked />
pre

To use the bootstrap-switch library, we need first import its CSS and JavaScript file:

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="switch/css/bootstrap-switch.min.css"/>
...
<script src="switch/js/bootstrap-switch.min.js"></script>
pre

Then write Javascript that simply calls the
bc. {color:#295646;}.bootstrapSwitch function:

{color:#295646;}
bc. {color:#295646;}$("[name='bs-switch']").bootstrapSwitch();
pre

There is an option parameter for this function, where we can change this switch’s size, on & off label texts, on & off colors, etc:

{color:#295646;}
bc. {color:#295646;}$("[name='bs-switch']").bootstrapSwitch({
    size: "small",
    onText: "Yes",
    offText: "No",
});
pre

Below are some examples I made. You can check the source code in file chapter4/4.3/plugins.html to see how it works.

4.3.3 Color picker

A color picker would be a useful component if your website provides some color customization features, for example, you can change the theme color of your Twitter account profile page:

In the above text input box, the user could either choose pre-made colors or type some RGB hex color code. Suppose your website has a the similar function, you may consider adding a color picker to let the user pick a color from a palette, which would be more convenient than manually typing a hex code.

So here is the plugin we are going to utilize, called Bootstrap Colorpicker (https://itsjavi.com/bootstrap-colorpicker/). Like the “switch” plugin, first we need to import its CSS and Javascript files:

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="colorpicker/css/bootstrap-colorpicker.min.css"/>
...
<script src="colorpicker/js/bootstrap-colorpicker.min.js"></script>
pre

Next let’s code the input box in HTML then use Javascript to turn it into a color picker:

{color:#295646;}
bc. {color:#295646;}<div class="input-group colorpicker-component cp">
    <input type="text" class="form-control" value="#00b2ff"/>
    <span class="input-group-addon"><i></i></span>
</div>
...
<script>
    $(".cp").colorpicker();
</script>
pre

The
bc. {color:#295646;}.colorpicker function also takes an option parameter, from where we can customize its alignment, format, etc. Here are some working examples, and you can check the source code for them in chapter4/4.3/plugins.html .

4.3.4 Date & Time picker

In this section we will cover 2 commonly used comports, date and time picker. They are from 2 different sources:

  • Date picker: https://bootstrap-datepicker.readthedocs.io
  • Time picker: https://jdewit.github.io/bootstrap-timepicker/

The usage is similar to the color picker. Take the date picker for example, first we need to include its CSS and Javascript files:

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="datepicker/css/bootstrap-datepicker3.min.css"/>
...
<script src="datepicker/js/bootstrap-datepicker.min.js"></script>
...
pre

Then call the
bc. {color:#295646;}.datapicker function on an element:

{color:#295646;}
bc. {color:#295646;}<div class="input-group date dp">
    <input type="text" class="form-control" value="04/16/2017">
    <span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
...
<script>
    $(".dp").datepicker();
</script>
pre

And below is a working example for the time picker. I’ll skip the its code here, but you can check the code in chapter4/4.3/plugins.html.

4.3.5 Lightbox Gallery

Lightbox is almost an indispensable component when you are trying to display a bunch of pictures, while Bootstrap provides the “modal” component which we can use along with some Javascript to make a lightbox. There is a plugin called Lightbox for Bootstrap (http://ashleydw.github.io/lightbox/) we can use directly.

First include its CSS and Javascript:

{color:#295646;}
bc. {color:#295646;}<link rel="stylesheet" href="lightbox/css/ekko-lightbox.min.css"/>
...
<script src="lightbox/js/ekko-lightbox.min.js"></script>
...
pre

Say in HTML we have a bunch of images. If we want to show them in a lightbox, make sure give them the same value for the
bc. {color:#295646;}data-gallery attribute:

{color:#295646;}
bc. {color:#295646;}<div class="col-xs-12 col-sm-3 text-center mb-lg">
    <h4 class="section-subtitle mb-md">Picture #1</h4>
    <a href="image1-full-size-url" data-toggle="lightbox" data-gallery="gallery-1">
        <img src="image1-thumbnail-url" class="img img-responsive">
    </a>
</div>
<div class="col-xs-12 col-sm-3 text-center mb-lg">
    <h4 class="section-subtitle mb-md">Picture #2</h4>
    <a href="image2-full-size-url" data-toggle="lightbox" data-gallery="gallery-1">
        <img src="image2-thumbnail-url" class="img img-responsive">
    </a>
</div>
pre

Then add Javascript such that when the user clicks any of those images, the lightbox will popup:

{color:#295646;}
bc. {color:#295646;}$("[data-toggle='lightbox']").click(function (evt) {
    evt.preventDefault();
    $(this).ekkoLightbox();
});
pre

Here are screenshots of a working example. We have 4 images with the same value of
bc. {color:#295646;}data-gallery attribute:

When clicking any of the images, a lightbox will popup, and we can use the left/right arrow keys to navigate back and forth.

These are all 5 plugins we introduced in this section, for more, please check “plugins” part in Appendix B.

Practice

Start a server to see all the plugins we added:

  1. At this book’s repository folder make-bootstrap-themes, open a command/terminal window, then use
    bc. {color:#295646;}http-server to start web server.
  1. Visit the web page at: http://127.0.0.1:8080/chapter4/4.3/plugins.html to view the plugins we used.
  1. Learn the code in the plugins.html file.

Challenge

You have seen how we applied the CSS animations to HTML elements. Those CSS animations are included from the file http://www.justinaguilar.com/animations. Can you write some other animations and use it to some elements?

  1. Generate a CSS3 animation from the website: http://animista.net/
  1. Include this animation class, then try applying it to some elements in the plugins.html page.

4.4 Pack up theme files

In this last section of this chapter, we are going to cover how to organize your theme files if you want to sell it in the marketplace.

The general rule here is that you may need to organize files clearly and include all the source files you made in case your customer wants to do more customizations. Here is a structure I am using:

  • A less folder which includes your .less files like the my-variables.less, and my-mixins.less, my-theme.less we coded in chapters 3 and 4.
  • An assets folder which contains 4 subfolders:

  • css folder: contains the compiled .css files from .less

  • js folder: contains your own Javascript files

  • images folder: contains some sample or placeholder images used in your theme’s web pages

  • plugins: contains third-party libraries

  • The theme-styles.html page which will give your customer an overview of how the components look like, if you also made additional-styles.html and plugins.html like we did in chapter 4, make sure to include them too.
  • If you have some design work, like drawn web pages using some design software, like Photoshop, Sketch, Illustrator, etc., you may also include the source files like .psd, .sketch or .ai;
  • Several template pages like index.html, signin.html, signup.html, etc., such that your customers can directly use the templates with slight modifications.
  • Last but not least, include a README file. Nowadays the Markdown format is very popular, so you can write in Markdown and save it as README.md. Your customer may not be a tech savvy, so writing it in plain text format and saving it as README.txt is good too. In this file you may need to include your theme’s name, description, your contact information, how your files are organized, how to compile your .less files to .css files, and most importantly, make sure you include some credit information to those third-party libraries you used.

To include what pages as templates, it depends on what kind of website you make, but in general you may want to include the sample pages below:

  • index.html
  • signin.html
  • signup.html
  • reset-password.html
  • features.html
  • download.html
  • pricing.html
  • contact.html
  • about.html
  • faq.html
  • blog-list.html
  • blog-details.html
  • 404.html
  • 500.html
  • blank-template.html

If you want your theme to be used for some e-commerce website, you may also include:

  • store-item-list.html
  • store-item-details.html
  • shopping-cart.html
  • check-out.html
  • invoice.html

If your theme is mainly used for an admin site, you may want to include:

  • dashboard.html
  • user-list.html
  • user-details.html
  • charts.html

There are some other ways to organize those files. As long as you keep those files in a clear structure, you will save your customers lots of time to use or do further customizations to your theme.

Moreover, if you are looking for popular marketplaces to sell your themes, I put some in the “Marketplace” section of Appendix B.

Chapter 5 – A glance at Bootstrap 4

At the time of writing this book, Bootstrap 4 is still in the alpha-test phase. Since it might have been officially released by the time you are reading this book, we will walk through some code of Bootstrap 4 to get you prepared for making themes for Bootstrap 4. Here we use its tag version v4.0.0-alpha.6, which is the latest version at this time. For the name convenience, in the following sections, by “Bootstrap 4” we mean “Bootstrap 4 at version v4.0.0-alpha.6”.

This version has lots of changes compared to version 3. Bootstrap 4 dropped lots of classes from Bootstrap 3, and introduced some new ones. For example, the
bc. {color:#295646;}.panel class is dropped, we can now use the new class named
bc. {color:#295646;}.card to implement the same look like
bc. {color:#295646;}.panel. Glyphicons are also dropped, using third-party icons like FontAwesome are recommended. Bootstrap 4 also uses flexbox for layout by default. We will cover those main changes in section 5.1.

For the CSS pre-processor part, Bootstrap 4 now use Sass instead of Less. Like we mentioned in chapter 2, Less and Sass are the most 2 popular CSS pre-processors, and Bootstrap 4 now opts to using Sass. Don’t worry if you are not familiar with Sass, it actually has very similar syntax to Less. If you have read chapter 2 about Less, you should be able to learn Sass very quickly. We will also cover an introduction on it in section 5.2.

Like we did for Bootstrap 3, knowing the source code structure of Bootstrap 4 will help us make customized themes, so in section 5.3 we will dive into Bootstrap 4’s source code. In the final section we will cover some customization tips for Bootstrap 4.

5.1 Use Bootstrap 4 theme

Bootstrap 4 has lots of changes compared to version 3, it deprecated some CSS classes and added some new ones, so we need to modify our code in theme-styles.html first to get us prepared for making themes.

If you are already familiar with Bootstrap 4, you can jump to the end of this section: in the practice part, you can set up a local server to preview our modified theme-styles.html with Bootstrap 4. Otherwise, if you are a Bootstrap 3 user, going through all of the content in this section will help you learn the changes in Bootstrap 4, and furthermore, learn how to use Bootstrap 4.

Typography

The first part in the typography section are the headings elements,
bc. {color:#295646;}h1 to
bc. {color:#295646;}h6. Bootstrap 4 removed their
bc. {color:#295646;}margin-top value and add
bc. {color:#295646;}margin-bottom: 0.5rem to all of them, so if we want to display them the same as Bootstrap 3, we need to add some
bc. {color:#295646;}margin-top values to them. Fortunately, we don’t need to define the same CSS classes ourselves, Bootstrap 4 comes with a bunch of utilities classes for spacing (like what we did in chapter 4.2), for example, for
bc. {color:#295646;}margin-top, it provides 6 classes:
bc. {color:#295646;}.mt-0,
bc. {color:#295646;}.mt-1,
bc. {color:#295646;}.mt-2,
bc. {color:#295646;}.mt-3,
bc. {color:#295646;}.mt-4 and
bc. {color:#295646;}.mt-5.
bc. {color:#295646;}.mt-0 will set
bc. {color:#295646;}margin-top value to be 0,
bc. {color:#295646;}.mt-5 will set it to
bc. {color:#295646;}3rem.

For example, we could add the
bc. {color:#295646;}.mt-4 class to
bc. {color:#295646;}h1,
bc. {color:#295646;}h2 and
bc. {color:#295646;}h3,
bc. {color:#295646;}.mt-2 to
bc. {color:#295646;}h4,
bc. {color:#295646;}h5 and
bc. {color:#295646;}h6 :

{color:#295646;}
bc. {color:#295646;}<h1 class="mt-4">Heading 1, h1</h1>
<h2 class="mt-4">Heading 2, h2</h2>
<h3 class="mt-4">Heading 3, h3</h3>
<h4 class="mt-2">Heading 4, h4</h4>
<h5 class="mt-2">Heading 5, h5</h5>
<h6 class="mt-2">Heading 6, h6</h6>
pre

The second part includes the
bc. {color:#295646;}

,
bc. {color:#295646;},
bc. {color:#295646;},
bc. {color:#295646;}, and
bc. {color:#295646;} tags. They are basically the same as Bootstrap 3. The only change is the
bc. {color:#295646;}

 tag, which doesn’t have a border or background color anymore.

The third part is the
bc. {color:#295646;}blockquote tag. We need to explicitly add the
bc. {color:#295646;}.blockquote class to it. Also, for footnotes, we need to add a
bc. {color:#295646;}.blockquote-footer class. Recall in Bootstrap 3 we have:

{color:#295646;}
bc. {color:#295646;}<blockquote>
    <p>
        Blockquote: quoted text here
    </p>
    <small>some celebrity</small>
</blockquote>
pre

Now we need to change it to:

{color:#295646;}
bc. {color:#295646;}<blockquote class="blockquote">
    <p>
        Blockquote: quoted text here
    </p>
    <footer class="blockquote-footer">some celebrity</footer>
</blockquote>
pre

The last part is contextual text including the
bc. {color:#295646;}.text-muted,
bc. {color:#295646;}.text-primary,
bc. {color:#295646;}.text-danger, etc. We don’t need to change them, but contextual background (like
bc. {color:#295646;}.bg-primary,
bc. {color:#295646;}.bg-danger, etc.) don’t set the text color by default anymore, so with the background color, the text doesn’t look very well:

But we may add a
bc. {color:#295646;}.text-white class to change the text color to white.

{color:#295646;}
bc. {color:#295646;}<p class="bg-primary text-white">Text inside p with bg-primary class</p>
<p class="bg-warning text-white">Text inside p with bg-warning class</p>
<p class="bg-danger text-white">Text inside p with bg-danger class</p>
...
pre

Navigation bar

There is no
bc. {color:#295646;}.navbar-default class in Bootstrap 4. Now we need to use
bc. {color:#295646;}.bg-* utility classes to set the navigation bars color. This actually gives us more flexibility since Bootstrap 4 provided 7
bc. {color:#295646;}.bg-* classes including
bc. {color:#295646;}.bg-primary,
bc. {color:#295646;}.bg-success,
bc. {color:#295646;}.bg-info,
bc. {color:#295646;}.bg-warning,
bc. {color:#295646;}.bg-danger,
bc. {color:#295646;}.bg-inverse and
bc. {color:#295646;}.bg-faded. We can use those along with the
bc. {color:#295646;}.navbar-light and
bc. {color:#295646;}.navbar-inverse classes: if the background is a light color (like
bc. {color:#295646;}.bg-faded), use
bc. {color:#295646;}.navbar-light, so the text color in the navigation bar will turn dark; if the background is a dark color (like
bc. {color:#295646;}.bg-danger), use
bc. {color:#295646;}.navbar-inverse, so the text color in the navigation bar will turn light. So now for the navigation bar we have it like this:

{color:#295646;}
bc. {color:#295646;}<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
...
</nav>
pre

For the link items in navigation bar, we need to add
bc. {color:#295646;}.nav-item to
bc. {color:#295646;}

  • tags and add
    bc. {color:#295646;}.nav-link to the
    bc. {color:#295646;} tag which is inside
    bc. {color:#295646;}
  • .

    {color:#295646;}
    bc. {color:#295646;}<ul class="navbar-nav mr-auto">
        <li class="nav-item active">
            <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
        </li>
        ...
    </ul>
    pre

    We also need to change the alert badge’s classes. Bootstrap provided 6 badge background colors:
    bc. {color:#295646;}.badge-default,
    bc. {color:#295646;}.badge-primary,
    bc. {color:#295646;}.badge-success,
    bc. {color:#295646;}.badge-info,
    bc. {color:#295646;}.badge-warning, and
    bc. {color:#295646;}.badge-danger. It also has a
    bc. {color:#295646;}.badge-pill class if we want to make the badge border more rounded. Here is our code for the badge:

    {color:#295646;}
    bc. {color:#295646;}<li class="nav-item">
        <a href="#" class="nav-link">Alerts
            <span class="badge badge-default badge-pill">3</span>
        </a>
    </li>
    pre

    The great part is now we can combine those
    bc. {color:#295646;}.bg-*,
    bc. {color:#295646;}.navbar-light/inverse, and
    bc. {color:#295646;}.badge-* classes to generate several different navigation bars, for example:

    The first one we use
    bc. {color:#295646;}.navbar-light and
    bc. {color:#295646;}.bg-faded for
    bc. {color:#295646;}