 
# 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:

    <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>

You should know what `container`, `col-xs-12` , `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:

  1. `http-server` : it will help us easily setup a local web server.
  2. `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 `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.
  3. `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.
  4. `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 `npm`. `npm` comes along with the `Node.js` installation package, so we will first install `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:

    $ git clone https://github.com/bofeng/make-bootstrap-themes.git

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>
  2. 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.

  3. 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 `node -v` first to see the Node.js version you have installed; then type `npm -v` to see the `npm` version. (Notice that `npm` is installed along with Node.js, and we will use `npm` to install other applications later).

**Tips** : When you type the `node` and `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>
  2. 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.

  3. 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 `node -v` and `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):

    $ node -v
    v6.9.2
    $ npm -v
    3.10.9

If you used this "Terminal" application a lot, and are familiar with many Linux/Unix commands like `cd`, `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";
  2. 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 `npm` installed, we will now install `http-server` and `less` through one command. For Windows users, open a command/terminal window at any folder, then type:

    $ npm install http-server less -g

It may take several seconds, when it is done, we will have both `http-server` and `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:

    <html>
       <body>
            Test http server
        </body>
    </html>

For Windows users, open a command window at this _test_ folder, then simply type `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:

    Starting up http-server, serving ./
    Available on:
      http://127.0.0.1:8080
    ...

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 `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 `http-server` to start a web server, some information will show up:

    $ http-server
    Starting up http-server, serving ./
    Available on:
      http://127.0.0.1:8080
      ...

Now use a browser to visit `http://127.0.0.1:8080`, you should be able to see the page content.

#### Tips

When you run the `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 `-p` option, for example:

    $ http-server -p 4545

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 `http://127.0.0.1:4545`, you should be able to see the page content.

### Test less

The above `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 `test.less` file at your _test_ folder with the following code:

    @color: #ff6600;
    .mark {
        color: @color;
    }

2) Open a command/terminal window at this _test_ folder, then use `lessc` command below to compile it:

    $ lessc test.less test.css

This will compile the Less code to plain CSS and save it in _test.css_ file. Notice here we use `lessc` (there is an extra `c` at the end), which stands for _less compiler_.

3) Open this _test.css_ file, it should contain the following code:

    .mark {
        color: #ff6600;
    }

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.
  2. Open a command/terminal window at this _make-bootstrap-themes_ folder;
  3. In this command/terminal window, type `http-server` to start a web server.
  4. Visit <http://127.0.0.1:8080/chapter1/theme-styles.html> in your browser.
  5. 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: #ff6600;

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

Save it as _test.less_ , then use the `lessc` command to compile it. If you forgot how to do this, go back to chapter 1.2 to review it.

    $ lessc test.less test.css

The above _Less_ code will be compiled to plain CSS code and be saved in _test.css_ file, it should have content like this:

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

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

    @color: @ee3300;
    ...

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

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

Variables can also be used in selector names, property names, URLs and `@import` statements. We call this _variable interpolation_. The format is `@{variable-name}` , for example:

    @alertname: alert;
    @staticpath: "../static";

    .@{alertname}-info {
        background-color: #339900;
    }

    .@{alertname}-warn {
        background-color: #ff6600;
    }

    .thumbup {
        background: url("@{staticpath}/img/thumbup.png");
    }

After compilation:

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

In this above example, since we defined `@alertname` to be `alert`, the class name `.@{alertname}-info ` becomes `.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: #ff6600;

    .mark {
        color: @color;
    }

    @color: #339900;

    .info {
        color: @color;
    }

After compilation:

    .mark {
        color: #339900;
    }
    .info {
        color: #339900;
    }

We can see that although we defined the `.mark` class before the second definition of the variable `@color`, both of the classes used the color `#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_ ;
  2. Open a command/terminal window at this folder, then use `lessc` to compile _variable.less_ : `$ lessc variable.less ` ;
  3. Compare the compiled code with the source code in _variable.less_ .

## 2.2 Comment

In plain CSS we can add comments by using `/* ... */`. This is not very convenient when writing single-line comments. In _Less_ we can use `//` to write single-line comments:

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

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

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

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 `+` , `-`, `*` , `/` on numbers and color codes. For example:

    @size: 14px;
    @width: 60%;
    @color: #ff6600;

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

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

Compiled to:

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

#### Practice

  1. Go to repo's folder _chapter2/2.3_ , open _oper.less_ file and play with the code by adding some changes using `+` , `-`, `*` , `/` ;
  2. Start a command/terminal window at this folder, use `lessc` to compile _oper.less_ , and see how your changes affected the generated code.

## 2.4 Nested Rules

Suppose we have a `<div>` with the `.article` class. In this `<div>` we want to display the content of an article, including its title (we may use the `<h3>` element), and several paragraphs (we use the `<p>` element). Commonly we write the CSS like this:

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

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

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

After complication:

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

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_ :

    .lead {
        font-size: 16px;
        @media (min-width: 768px) {
            font-size: 20px;
        }
    }

After compilation:

    .lead {
        font-size: 16px;
    }
    @media (min-width: 768px) {
        .lead {
            font-size: 20px;
        }
    }

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 `.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:

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

Compiled to:

    .bordered {
        border: 1px dotted black;
    }
    .panel {
        background: #e1e1e1;
        border: 1px dotted black;
    }

In the `.panel` class, we "invoke" the `.bordered` function, it will include all the code inside `.bordered`.

### Mixins with parameters

Mixins can also have parameters:

    .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);
    }

Compiled to:

    .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;
    }

It can also have multiple parameters:

    .box(@margin, @padding) {
        margin: @margin;
        padding: @padding;
    }

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

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

Compiled to:

    .panel {
        margin: 3px;
        padding: 5px;
    }
    .quote {
        margin: 5px;
        padding: 10px;
    }

### 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:

    #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);
    }

Compiled to:

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

We put a mixin named `.box` inside `#mbt-lib`. Other developers can use this mixin with `#mbt-lib > .box`, while they can still define their own `.box` mixin, and since our version `.box` is under the namespace `#mbt-lib`, those two `.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 `#gradient` group.

    #gradient {
        .horizontal(@start-color, @end-color, @start-percent, @end-percent) {
            ...
        }
        .vertical(@start-color, @end-color, @start-percent, @end-percent) {
            ...
        }
        ...
    }

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

    .panel {
        ...
        #gradient > .horizontal(#555, #333, 0%, 100%);
    }

#### Practice

  1. Go to code repository folder _chapter2/2.5_ , and open a command/terminal window at this folder;
  2. Use `lessc` to compile the _mixins.less_ file: `$ lessc mixins.less`, and see the generated code;
  3. 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 `lessc` to re-compile it to see the changes.

## 2.6 Parent Selector

The `&` operator will refer to its parent selector, for example:

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

Compiled to:

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

The first `&` is replaced by its parent selector's name `.navbar`. The second `&` is replaced by `.navbar-default `.

Another example:

    .input-sm {
        height: 30px;
        select& {
          line-height: 1.4em;
        }
    }

Compiled to :

    .input-sm {
        height: 30px;
    }
    select.input-sm {
        line-height: 1.4em;
    }

Also notice that when we use this `&` operator along with mixins, the code inside the mixin will first be included, and then do the `&` replacement. For example:

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

    .well {
        .bg-warning();
    }

Compiled to:

    .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;
    }

We have the `&` operator in `.bg-warning`, so `a.bg-warning:hover` and `a.bg-warning:focus` are generated. In the `.well` class, we included this `.bg-warning` mixin, so the `.well` code will first become:

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

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

#### Practice

Suppose we have the following code:

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

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

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_.
  2. Start a command/terminal window there, use `lessc` to compile it: `$lessc test.less`.
  3. 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 `h1` tag we use the font size as 2.2 times bigger; for the `h2` we use 1.4 times bigger, etc. In this `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 `floor` and `ceil` functions can help us do the trick.

#### floor

The `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 `Math.floor` in Javascript.

Example:

    small {
        font-size: floor(14px * 0.8);
    }
    h5 {
        font-size: floor(14px * 0.7);
    }
    h6 {
        font-size: floor(8.0px);
    }

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:

    small {
        font-size: 11px;
    }
    h5 {
        font-size: 9px;
    }
    h6 {
        font-size: 8px;
    }

#### 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 `Math.ceil` in Javascript.

Example:

    big {
        font-size: ceil(14px * 1.2);
    }
    h4 {
        font-size: ceil(14px * 1.3);
    }
    h5 {
        font-size: ceil(12.0px);
    }

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:

    big {
        font-size: 17px;
    }
    h4 {
        font-size: 19px;
    }
    h5 {
        font-size: 12px;
    }

### 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:

    @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%);
    }

After compilation:

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

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

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

The `lighten` function works like a charm, but you may wonder how it magically knows that changing our RGB color `#be4c0f` to `#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:

    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

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

    @mygreen: #80e619;

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

After compilation:

    .color1 {
        color: #c7f49a;
    }
    .color2 {
        color: #c7f49a;
    }

Notice that in the `.color2` class, we utilized other color functions in _Less_ :

  * `hue` : Get the hue channel of a color object in the HSL color space.
  * `saturation` : Get the saturation channel of a color object in the HSL color space.
  * `lightness` : Get the lightness channel of a color object in the HSL color space.
  * `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 `darken` function does the reverse as `lighten`, it will decrease the lightness of a color. In the above example, after increasing the lightness of the color `#80e619` by 28%, we get `#c7f49a`. If we decrease the lightness of this color `#c7f49a` by 28%, we can get the original color back:

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

After compilation:

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

#### red, green, blue

These 3 functions will correspondingly extract the `red` , `green`, `blue` channel of a color, below is a common use case: we generate a half-transparent color of an existing color:

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

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

Compiled to:

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

#### fadein

The `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 `@inner-color` with 0.2 alpha transparency, then defines another color `@outer-color` based on the first color with an increasing 60% opacity to make it more opaque. The third color `@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 `fadein` function will not have an effect on it even we write the code as increasing its opacity by 50%.

    @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%);
    }

After compilation:

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

#### fadeout

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

    @font-color: #ff6600;

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

After compilation:

    .popover {
        color: rgba(255, 102, 0, 0.5);
    }

#### spin

The `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 `alert` or `alert-warning` classes in Bootstrap before, your code looks like this:

    <div class="alert alert-warning">
        <h4>Warning!</h4>
        <p>Warning message.</p>
    </div>

Under the default theme, this `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 `spin` function along with the `darken` function, the code is defined like below:

    @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
    }

After complication:

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

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 `#fcf8e3` towards the red zone by 10 degrees), then darkens this color by 5%. With these 2 steps we get a new color `#faebcc`. Bootstrap uses this trick for other alert states and panel states too, like `.alert-success`, `.panel-warning`, `.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 `floor`, `lighten`, `darken` and `fadein` functions to some value, then use `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:

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

Outputs after compilation:

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

See now the `.btn-large` class also has the CSS rule set as the `.btn` class.

If we have nested selectors, by default the `&:extend` directive won't extend them. Example:

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

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

After compilation:

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

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

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

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

Compiled to:

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

Now we have both of the `.nav-top` and `.nav-top h3` selectors.

### Extend VS Mixins

In our first `.btn` and `.btn-large` example, you may have noticed that we can achieve the same result by using mixins:

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

Notice that we use `.btn()` to replace `&:extend(.btn)`, and after compilation it becomes this:

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

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

Well, if we check the generated code in plain CSS, we can see by using `&: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 `&:extend` combines the selectors instead of doing code replication. So yes, using `&:extend` will help us remove unnecessary duplication and reduce the final CSS size, but does that mean we should always choose `&:extend` over mixins?

Let's see another example:

    .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;
    }

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

After compilation:

    .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;
    }

It clearly generates less code than using mixins like `.base-font()`, however, in the first part of the compiled CSS, while we let `.base-font`, `h1`, `.panel-warning` and `.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 `.btn` and `.btn-large` example is a great case to use `&:extend`, since `.btn-large` is a button (just a larger version), it has a relationship with `.btn`.

So when do we use `&:extend` and when do we use mixins? Personally I prefer to use `&:extend` when there is an `is-a` relationship between selectors, while I use mixins when there is a `has-a` relationship. For example, `.btn-large` "is-a" `.btn`, so we use `&:extend`; `.panel-warning` is not a `.base-font`, but "has-a" `.base-font`, so we should use `.base-font()`. In conclusion, though `&: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 `@import` directive to import style rules from other style sheets like:

    @import url("fineprint.css");
    @import "custom.css";

This `@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.

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

We can also omit the _.less_ suffix:

    @import "my-mixins.less";
    // next line does the same thing 
    @import "my-mixins"

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

_color.less_ :

    .text-warning {
        color: #ff6600;
    }

In next _box.less_ file, we import this _color.less_ :

    @import "color";
    .box-warning {
        .text-warning;
    }

We also include _color.less_ in another file _container.less_ :

    @import "color";
    @import "box";
    .panel-warning {
        .text-warning;
    }

As shown below, _color.less_ is included twice (directly and indirectly) in _container.less_ :

Now if we compile _container.less_ , we will have:

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

We can see that although _color.less_ is included twice, the final generated CSS code only contains the `.text-warning ` class once.

This is also the default behavior of the `@import` directive but we can change it. If we want to include the same file multiple time, in _container.less_ we can use:

    @import (multiple) "color";
    @import (multiple) "box";

After compilation, `.text-warning` will be included twice:

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

_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 `@import` code in _container.less_ , we either use the _multiple_ keyword for both lines:

    @import (multiple) "color";
    @import (multiple) "box";

Or both without it:

    @import "color";
    @import "box";

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

    @import "color";
    @import (multiple) "box";

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
  2. Use `lessc` to compile _container.less_ : `$ lessc container.less`

In the generated code, how many times the `.text-warning` class appears?

Further more, what happens if we change `multiple` to `reference ` ?

    @import (reference) "color";
    @import (reference) "box";

# 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 `.btn-warning` class on a button:

    <button class="btn btn-warning">Warning</button>

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:

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

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 `.less` files by using the `@import` directive.
  * The `mixins` folder: this folder has 30 `.less` files which contain all mixins. For example, `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 :

    $ lessc bootstrap.less bootstrap.css

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:

    <link rel="stylesheet" href="/bootstrap-3.3.7/dist/css/bootstrap.css"/>

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 `/bootstrap-3.3.7/dist/css/bootstrap.css` to `/bootstrap-3.3.7/less/bootstrap.css `:

    <link rel="stylesheet" href="/bootstrap-3.3.7/less/bootstrap.css"/>

Start a command/terminal window at the repository root folder _make-bootstrap-themes_ , then type `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:

    $ lessc theme.less theme.css

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

    <link rel="stylesheet" href="/bootstrap-3.3.7/less/bootstrap.css"/>
    <link rel="stylesheet" href="/bootstrap-3.3.7/less/theme.css"/>
    ...

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 `@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 `@import`, like: `@import "mixins/background-variant.less";`, `@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 `normalize.less` ends with the `.less` prefix, inside it there is just plain CSS code.
  * _print.less_ : Defines CSS for printing.
  * _glyphicons.less_ : Defines CSS for all glyphicons, like `.glyphicon-plus`, `.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 `html`, `body`, `a`, `img`, `hr`, etc. It also defines `img-responsive`, `img-rounded`, `img-thumbnail`, `img-circle`
  * _type.less_ : Defines CSS related to typography. For example, `h1` ~ `h6`, `p`, `.text-left`, `text-primary`, `bg-warning`, `ul`, `ol`, `small`, `big`, `blockquote`, etc.
  * _code.less_ : Defines CSS for `code`, `kbd`, `pre`.
  * _grid.less_ : Defines the grid system, including the `.container` class, `.row`, `.col-sm-*`, etc. It calls the `.make-grid`, `.make-grid-columns` function defined in _mixins/grid-framework.less_ , and calls `.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 `.table-bordered`, `.table-striped`, etc.
  * _forms.less_ : CSS for forms, for example, `form-control`, `form-group` classes are defined here.
  * _buttons.less_ : CSS for buttons, `.btn`, `.btn-primary`, `.btn-danger`, `btn-block`, `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 `.fade`, `.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 `.nav-tabs`, `.nav-pills`, `.nav-stacked`, etc.
  * _navbar.less_ : CSS for navigation bars, including `.navbar-default`, `.navbar-inverse` and classes for its inner elements, like `.navbar-brand`, `.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 `.badge` class, `.btn .badge` class (an element with `.badge` class inside another element with `.btn` class), `.list-group-item > .badge` class, etc.
  * _jumbotron.less_ : CSS for jumbotron.
  * _thumbnails.less_ : CSS for thumbnails, this `.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 `.img-thumbnail` class, which is used for images.
  * _alerts.less_ : CSS for alerts, `.alert`, `.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, `.panel`, `.panel-heading`, `.panel-body`, `.panel-warning` are defined here.
  * _responsive-embed.less_ : CSS for keeping ratio of embedded objects, it defines classes like `.embed-responsive`, `.embed-responsive-4by3 ` and `.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 `.alert` or `.modal` class before, you may have used this `.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 `.clearfix`, `.hide`, `.show`, `.text-hide`, `.center-block`, `.pull-right`, `.pull-left` classes.
  * _responsive-utilities.less_ : Defines utility classes for showing and hiding content by device via media query, including `.visible-xs`, `.visible-sm`, `visible-sm-block`, `.hidden-xs`, `.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?
  2. Does it use the _nested rules_ feature we learned in chapter 2.4?
  3. Does it use some mixins? Where are those mixins originally defined? For example, _alerts.less_ uses a mixin called `.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 `.navbar`, `.navbar-default`, and the `.navbar-inverse` parts.

Let's create a _my-navbar.less_ file. For the first 2 changes listed above, we want to override the `.navbar` class, so let's put the following content in our _my-navbar.less_ file:

    .navbar {
        border-radius: 0;
        border: none;
    }

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 `.navbar-default` and `.navbar-inverse`, since they are using different colors. Let's define colors first:

    @navbar-default-border-color: #70A1D7;
    @navbar-inverse-border-color: #F35B25;

Then we define the bottom border for both `.navbar-default` and `.navbar-inverse`

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

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:

    .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;
            }
        }
    }

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 `> .active > a` part. Let's add this to our `.navbar-default` and `.navbar-inverse`:

    .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;
                }   
            }   
        }   
    }

Notice we nest `.navbar-nav` in the `.navbar-default` and the `.navbar-inverse` classes, and inside this `.navbar-nav` class, we nest `> .active > a`. Inside this `a`, we again nest the `&, &: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: `@navbar-default-border-color` and `@navbar-inverse-border-color`
  * `.navbar` class
  * `.navbar-default` class
  * `.navbar-inverse` class

Let's compile the _Less_ code to plain CSS:

    $ lessc my-navbar.less my-navbar.css

After compilation:

    .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;
    }

Add this compiled `my-navbar.css` to the _theme-styles.html_ :

    <link rel="stylesheet" href="path/to/my-navbar.css"/>

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 `http-server` command to start a web server;
  2. In your browser, visit <http://127.0.0.1:8080/chapter3/3.2/navbar.html>
  3. 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 `lessc` to recompile it, then refresh the _navbar.html_ page.

**Hint** : You can add a `.badge` class inside both the `.navbar-default` and the `.navbar-inverse` classes.

## 3.3 Utilizing Variables

Recall in the last section we saw Bootstrap's `.navbar-nav` source code like this:

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

You may have noticed that under the `.navbar-nav` selector, Bootstrap is using two variables `@navbar-default-link-active-color` and `@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 `#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 `lessc` command to compile `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.
  2. 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.
  3. Compile this _my-theme.less_ to generate the CSS file, _my-theme.css_.
  4. 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 `.navbar-default` and `.navbar-inverse`. In Bootstrap's source code file _navbar.less_ , under the `.navbar` selector:

    .navbar {
        ...
        @media (min-width: @grid-float-breakpoint) {
            border-radius: @navbar-border-radius;
        }
    }

It is using the `@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 `.navbar-default .navbar-nav` selector 2 variables are being used: `@navbar-default-link-active-color` and `@navbar-default-link-active-bg`, and for the `.navbar-inverse .navbar-nav` selector, there are another 2 variables: `@navbar-inverse-link-active-color` and `@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:

    @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;

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 `.navbar` to add a 2px border at bottom, and use different border colors for `.navbar-default` and `.navbar-inverse`:

    @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;
        }   
    }

3) Compile _my-theme.less_ to generate the CSS file _my-theme.css_ :

    $ lessc my-theme.less my-theme.css

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 `href` attribute) :

    <link rel="stylesheet" href="path/to/bootstrap-3.3.7/dist/css/bootstrap.css"/>

Replaced by:

    <link rel="stylesheet" href="path/to/my-theme.css"/>

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 `http-server` to start a web server.
  2. Visit <http://127.0.0.1:8080/chapter3/3.3/navbar.html>, you will see the default navigation bar:

  3. 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 `lessc` to compile _my-theme.less_ code: `$ lessc my-theme.less my-theme.css`. This will generate our theme file with plain CSS code.
  4. Also in this folder, change the _navbar.html_ file content to use our own theme file: at line 5, replace the line `<link rel="stylesheet" href="/bootstrap-3.3.7/dist/css/bootstrap.css"/>` with `<link rel="stylesheet" href="my-theme.css"/>`.

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 `.navbar-default` and `.navbar-inverse`?

**Hint** : you can add `.badge` class in both `&-default` and `&-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 `navbar` section:

    ...
    @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;
    ...

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 `@gray-base` color:

    @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

Among those 6 variables, `@gray-darker` is not being used in any of Bootstrap's _.less_ files; the `@gray-dark` and the `@gray` colors are generally used for common text color; `@gray-light` and `@gray-lighter` are widely used for background color and the mouse hover color.

#### 2) Brand contextual colors section

This section defines 5 contextual colors:

    @brand-primary: darken(#428bca, 6.5%); // #337ab7
    @brand-success: #5cb85c;
    @brand-info: #5bc0de;
    @brand-warning: #f0ad4e;
    @brand-danger: #d9534f;

Lots of components use those for their own contextual colors. For example, the button's class `.btn-primary` uses `@brand-primary` as background color, `.btn-success` uses `@brand-success` as background color; `.label-warning` uses `@brand-warning` as background color; `.progress-bar-danger` uses `@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.

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

#### 4) Basic font style section

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

    @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;
    ...

#### 5) Components' common style section

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

    @padding-base-vertical: 6px;
    @padding-base-horizontal: 12px;
    @border-radius-base: 4px;                                                                                           
    @border-radius-large: 6px;
    @component-active-bg: @brand-primary; 
    ...

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.

    @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%);

Bootstrap's _alert_ and _panel_ components use those variables. For example, `.alert-warning` uses `@state-warning-text` as text color, `@state-warning-bg` as background color, and `@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?
  2. Font styles: which font typeface do we use? How big for the base font size? how about the common text color?
  3. 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?
  4. 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?
  5. 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 `@body-bg` variable.
  2. 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.
  3. 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.

  4. For components, I'll slightly change the padding value and set the border radius to zero, so no components will have rounded corners.
  5. 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:

    @font-family-sans-serif: Nunito, Helvetica, Arial, sans-serif;
    @headings-font-weight: 700;

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:

    // 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;

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 `lighten` function to make a slight change based on the contextual text colors.

Next, override the paddings value and border radius values 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;

Last, override some variables for navigation bar:

    @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;

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:

    @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";

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.

    .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;
            }   
        }   
    }

Notice here we utilized a mixin named `.box-shadow`, this mixin is defined in Bootstrap's _vendor-prefixes.less_ file at _less/mixins_ folder. The line `@import "path/to/bootstrap-3.3.7/less/bootstrap.less"; ` imports all of those mixins, so we can directly use `.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:

    $ lessc my-theme.less my-theme.css

Then link it in our _theme-styles.html_ :

    <link rel="stylesheet" href="my-theme.css"/>

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 `http-server` to start a web server.
  2. Go to folder _chapter3/3.4_ , at this folder start another command/terminal window, then use `lessc` command to compile our theme's _Less_ file: `$ lessc my-theme.less my-theme.css`.
  3. Visit web page at: <http://127.0.0.1:8080/chapter3/3.4/theme-styles.html>.
  4. 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:

    @brand-primary: #3B4A6B;
    @brand-success: #52D681;
    @brand-info: #22B2DA;
    @brand-warning: #FFC24A;
    @brand-danger: #F23557;

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 `lessc` to recompile _my-theme.less_ : `$ 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 `#233142` for background color and `#e3e3e3` for the general text color.
  2. Font styles: I'll use the "Roboto Condensed" font from Google fonts as the default font-family.
  3. Contextual colors: I'll use `#ee6363` for `@brand-primary`, `#62c462` for `@brand-success`, `#5bc0de` for `@brand-info`, `#f0ad4e` for `@brand-warning`, `#C31207` for `@brand-danger`. Additionally I'll define a new variable named `@brand-secondary`, assign its color to `#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:

  4. 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_ :

    // 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;

And in _my-theme.less_ we have:

    // 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";

Let's compile it:

    $ lessc my-theme.less my-theme.css

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 `.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:

  * `<code>` and `<pre>` tag background color
  * border color of `<blockquote>`
  * text color of text contextual color class like `.text-success`, `.text-info`
  * text color of background contextual color class like `.bg-success`, `.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 `<code>`, `<pre>` and `<blockquote>` tags, so let's override those variables in our _my-variables.less_ file:

    @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%);

For contextual text colors, you may notice we only defined the `@text-muted` variable, but where are other ones like `@text-success`, `@text-warning` ? If we check Bootstrap's _type.less_ file we can see those classes are originally defined as:

    .text-success {
        .text-emphasis-variant(@state-success-text);
    }
    .text-info {
        .text-emphasis-variant(@state-info-text);
    }

It uses a mixin called `.text-emphasis-variant` and pass the color as parameter to define the text color. In the _my-variables.less_ global settings section, we defined `@state-success-text`, `@state-info-text` as a white color `#fff`, so that's why our text with `.text-success`, `.text-info` classes display as a white color. Since those `@state-success-text`, `@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_ :

    // 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);
    }

Notice that we passed the `@brand-success`, `@brand-info` variables as the text color, and we also added a text shadow for our `<h1>` to `<h6>` heading tags to make those look prettier. We also want to override the text color of background contextual color classes, e.g. `.bg-success`, `.bg-info`, etc, currently they are using the default `@text-color`, which is a gray color `#E5E5E5`, as the text color. They don't match well with our `.bg-warning`, `.bg-success` background color, so again in _my-theme.less_ , let's change the text color to white - `#fff`. This will make them stand out.

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

OK, for this typography part, we made changes in both _my-variables.less_ and _my-theme.less_ , let's recompile our theme:

    $ lessc my-theme.less my-theme.css

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 `.navbar-default` class match the dark background color, so let's change the background color of `.navbar-default` to our `@brand-secondary`, and change the background color of `.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_ :

    // 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;

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:

    // 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;
                }
            }
        }
    }

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_ :

    // Buttons
    // ------------------------------
    @btn-default-color:             #fff;
    @btn-default-bg:                @brand-secondary;
    @btn-default-border:            darken(@btn-default-bg, 5%);

And in _my-theme.less_ :

    // 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;
        }
    }

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 `.has-warning`, `.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_ :

    // 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;

And in _my-theme.less_ :

    // 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;
    }

In the above code, for the `.has-warning`, `.has-error` and `.has-success` classes, we use Bootstrap's mixin called `.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_ ):

    // 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%);

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_ :

    // 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;

In _my-theme.less_ :

    // 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;
            }
        }
    }

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_ ):

    // Breadcrumb
    // ------------------------------
    @breadcrumb-bg:                 @brand-secondary;
    @breadcrumb-color:              @text-color;
    @breadcrumb-active-color:       @text-color;

Previous appearance:

Now:

#### Pagination

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

    // 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;

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_ :

    // 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;

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_ :

    // 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;

And code added in _my-theme.less_ :

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

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_ :

    // Wells
    // ------------------------------
    @well-bg:       @brand-secondary;
    @well-border:   lighten(@brand-secondary, 5%);

Now it becomes:

#### Modals

Current appearance:

I added some variables in _my-variables.less_ :

    // 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;

And classes in _my-theme.less_ :

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

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;
  2. 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 _< component>.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_ ;
  3. 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 `http-server` to start a web server.
  2. 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.
  3. 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.
  2. 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 `#333333`.
  3. Contextual colors: I'll use the color `#ed745e` for the primary color, `#2eb872` for the success color, `#497cb1` for the info color, `#f89b20` for the warning color, and `#e03e36` for the danger color.

  4. 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.
  5. 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_ :

    // 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;

Then in _my-theme.less_ we have:

    @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";

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. `.text-primary`, `.text-success` are all white. We need to fix that, so we add following code to the _my-theme.less_ file:

    // 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);
    }

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 `http-server` to start web server.
  2. 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.
  3. 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:

    @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";

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:

    <nav class="navbar navbar-default navbar-fixed-top">
    ...
    </nav>

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 `.navbar-menu-top`.
  2. As the user scrolls down the page a little, we remove the `.navbar-menu-top` class of the navbar so it will use the style defined in the class `.navbar-default`; if the user scrolls up back to the top, we add the `.navbar-menu-top` class back to the navbar. To detect the "scroll down/up" page event, we need some Javascript.
  3. In the second step, when we remove or add the `.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 `.navbar-menu-top` class:

    .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;
                }
            }
        }
    }

We add the `.navbar-menu-top` class, and also changed the `.navbar-brand` and `.navbar-nav > li` styles under it. After compiling this _Less_ code to plain CSS, we apply it to our navbar:

    <nav class="navbar navbar-default navbar-fixed-top navbar-menu-top" id="navbar-top">
    ...
    </nav>

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 `.navbar-menu-top` class when the user scrolls up and down the page:

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

What this script does is, if the user scrolls the page down more than 80 pixels, we remove the navbar's `.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 `.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:

    .transition-eio {
        .transition(all 0.3s ease-in-out);
    }

Here we used a mixin `.transition` which is imported from Bootstrap's _mixins.less_ , after compiled the above code, it becomes:

    .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;
    }

Then we can just add this class to our navbar:

    <nav class="navbar navbar-default navbar-fixed-top navbar-menu-top transition-eio" id="navbar-top">
    ...
    </nav>

Now when the navbar uses or drops the `.navbar-menu-top` class, the browser will do a smooth transition for us. This `.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_ :

    .navbar {
        a {
            .transition-eio; // use it as a mixin
        }
       ...
    }

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 `.navbar-menu-top` class and apply it to navbar.
  2. Write Javascript to detect the "scroll down/up" event to remove/add `.navbar-menu-top` class.
  3. Define a `.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 `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 `margin-right` for example, we will add 5 classes for it: `.mr-zero`, `.mr-xs`, `.mr-sm`, `.mr-md` and `.mr-lg`. Specifically, they should be something like this:

    .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}

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:

    <i class="fa fa-bell mr-xs"></i> <span>Some Text Here</span>

These are 5 classes for `margin-right`, and we will define similar classes for `margin-left`, `margin-top`, `margin-right`, also for `padding-top`, `padding-bottom`, `padding-left` and `padding-right`. Since each one has 5 classes and they are using the same pixels for `*-xs`, `*-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 `createSpacing` in the _my-mixins.less_ file:

    @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}-@{name} {
            @{property}: @value;
        }
        .createSpacing(@prefix, @property, (@iterator + 1));
    }

We use an iterator to loop through `@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_ :

    .createSpacing(mt, margin-top);

It is compiled to:

    .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}

We can do the same thing for other margins and paddings. Let's add them in _my-extra-styles.less_ :

    // 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);

After compilation, there will be 40 classes generated for spacing, like `.mt-xs`, `.mr-sm`, `.pt-md`, `.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 `.btn-default-outline`, `.btn-primary-outline`, `.btn-success-outline`, `.btn-info-outline`, `.btn-warning-outline` and `.btn-danger-outline` classes.

    .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);
        }
    }

Here we use a mixin `.button-outline` which is defined in _my-mixins.less_ , we also use `.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 `.breadcrumb-primary`, `.breadcrumb-success`, `.breadcrumb-info`, `.breadcrumb-warning` and `.breadcrumb-danger`.

    .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);
    }

Each calls a mixin `.breadcrumb-contexual` which is defined in the _my-mixins.less_ file. To use those classes, for example, `.breadcrumb-primary`, we can write code like below:

    <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>

Our contextual breadcrumbs' appearance:

### 4.2.5 Contextual Pagination

Similar to breadcrumbs, let's add contextual paginations:

    .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);
    }

The `.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 `.pagination` class like below:

    <ul class="pagination pagination-primary">
    ...
    </ul>

Here are our contextual paginations appearance:

### 4.2.6 Contextual Panel Topping

Under the current theme we can use contextual panel classes like `.panel-primary`, `.panel-success`, `.panel-warning`, etc. along with the `.panel` class:

    <div class="panel panel-primary">
        <div class="panel-heading">
            ...
        </div>
        <div class="panel-body">
            ...
        </div>
    </div>

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

    <div class="panel panel-primary-top">
    ...
    </div>

Their appearance:

The code is also simple:

    // 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);
    }

You may notice that here we are using a mixin named `.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:

    .panel-danger-bottom {
        .panel-contextual-pos(@brand-danger, bottom);
    }

Similarly, we can define the `.panel-default-bottom`, `.panel-primary-bottom`, `.panel-success-bottom`, `.panel-info-bottom` and `.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:

    // 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%));
    }

The `.alert-variant` mixin above is imported from Bootstrap's `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 `.alert` and `.alert-warning`, `.alert-success`, `.alert-danger`, `.alert-info` classes:

Divs with the `.alert` and `.alert-warning-outline`, `.alert-success-outline`, `.alert-danger-outline` and `.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 `.list-group-item-success`, `.list-group-item-info`, `.list-group-item-warning` and `.list-group-item-danger`.

    .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);
    }

The mixin `.list-group-item-contextual` is defined in _my-mixins.less_ :

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

Then we can use it in HTML like this:

    <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>

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:

  1. `.ribbon-container`: we will apply it to the card-like container, the key CSS property in this class is `position:relative`.
  2. `.ribbon`: a div which holds the actual ribbon, the key CSS properties in it are `position:absolute; right:-1px; top:-1px; overflow:hidden`. This div helps to locate the actual ribbon.
  3. `.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 `transform: rotate(45deg)`, or we can just call the `.rotate(45deg)` mixin which is imported from Bootstrap's _mixins.less_.

    .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;
        }
    }

Once these classes are defined, for contextual ribbons we only need to set the background color for the `.text` class, for example:

    .ribbon-primary {
        .text {
            background: @brand-primary;
        }
    }
    .ribbon-success {
        .text {
            background: @brand-success;
        }
    }

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

    <div class="ribbon-container">
        <h3>Some Title</h3>
        <p>Some Description</p>
        <div class="ribbon ribbon-primary">
            <span class="text">HOT!</span>
        </div>
    </div>

### 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:

  1. `.bookmark-container`: Like the `.ribbon-container` class, we will apply this to the outer container, the key CSS property for it is `position: relative`.
  2. `.bookmark`: the actual bookmark. Here we will use a rectangle (e.g. a `<div>` tag) as the bookmark.
  3. `.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.

    .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;
        }   
    }

Then for the contextual bookmarks we only need to set the background color, for example, for the `.bookmark-primary` and `.bookmark-success` classes we have:

    .bookmark-primary {
        background-color: @brand-primary;
    }
    .bookmark-success {
        background-color: @brand-success;
    }

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

    <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>

### 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:

    .img-hover-fadeout:hover {
        .opacity(0.8);
    }

Here we use the `.opacity` mixin which is also imported from Bootstrap's _mixins.less_ file, then we can apply this class to an image like this:

    <img src="img-source-url" class="img img-responsive img-hover-fadeout transition-eio" />

Notice we applied both the `.img-hover-fadeout` and `.transition-eio` classes to the image, the `.img-hover-fadeout` will change the image's opacity, and the `.transition-eio` class will make the change more smooth with an animation.

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

    .img-hover-scale:hover {
        .scale(1.2);
    }

The `.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:

    .img-hover-container {
        overflow:hidden;
    }

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

    <div class="img-hover-container">
        <img src="url" class="img img-responsive img-hover-scale transition-eio" />
    </div>

The third one, scale and rotate:

    .img-hover-scale-rotate:hover {
        .transform(scale(1.2) rotate(8deg));
    }

We set both the scale and rotate to the `.transform` mixin, this `.transform` mixin is defined in our own _my-mixins.less_ file:

    .transform(@string){
        -webkit-transform: @string;
        -moz-transform: @string;
        -ms-transform: @string;
        -o-transform: @string; 
        transform: @string;
    }

Apply it to an image element:

    <div class="img-hover-container">
        <img src="url" class="img img-responsive img-hover-scale-rotate transition-eio" />
    </div>

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 `@keyframes` named "swing":

    @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);
        }
    }

The `.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 `.translate` mixin is defined as below:

    .translate(@x; @y) {
        -webkit-transform: translate(@x, @y);
        -ms-transform: translate(@x, @y);
        -o-transform: translate(@x, @y);
        transform: translate(@x, @y);
    }

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

    .img-hover-swing:hover {
        .animation(swing 1s ease-in-out);
    }

The `.animation` mixin is also imported from Bootstrap's _mixins.less_ file:

    .animation(@animation) {
        -webkit-animation: @animation;
        -o-animation: @animation;
        animation: @animation;
    }

Finally to use this `.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:

    <div class="img-hover-container">
        <img src="url" class="img img-responsive img-hover-swing" />
    </div>

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 `.btn-social` class which contains the common CSS properties for all of those sign-in buttons:

    .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;
        }
    }

We defined its width, text color and the icon styles (here we are using font-awesome icons, so the `.fa` indicates the icon's class), then we can just define the background color for different social media.

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

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

We can use them in HTML like below:

    <button class="btn btn-social btn-twitter">
        <i class="fa fa-twitter"></i>
        Sign in with Twitter
    </button>

    <button class="btn btn-social btn-facebook">
        <i class="fa fa-facebook"></i>
        Sign in with Facebook
    </button>

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 `http-server` to start web server.
  2. 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.
  3. 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 `div`:

    <div class="section">
        <h4>Some Title</h4>
    </div>

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

    <div class="section fadeIn">
    ...
    </div>

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:

    <style>
        .slide-item {visibility: hidden}
    </style>
    ...
    <div class="section slide-item">
    ...
    </div>

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:

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

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:

    <input type="checkbox" name="bs-switch" checked />

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

    <link rel="stylesheet" href="switch/css/bootstrap-switch.min.css"/>
    ...
    <script src="switch/js/bootstrap-switch.min.js"></script>

Then write Javascript that simply calls the `.bootstrapSwitch` function:

    $("[name='bs-switch']").bootstrapSwitch();

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

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

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:

    <link rel="stylesheet" href="colorpicker/css/bootstrap-colorpicker.min.css"/>
    ...
    <script src="colorpicker/js/bootstrap-colorpicker.min.js"></script>

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

    <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>

The `.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:

    <link rel="stylesheet" href="datepicker/css/bootstrap-datepicker3.min.css"/>
    ...
    <script src="datepicker/js/bootstrap-datepicker.min.js"></script>
    ...

Then call the `.datapicker` function on an element:

    <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>

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:

    <link rel="stylesheet" href="lightbox/css/ekko-lightbox.min.css"/>
    ...
    <script src="lightbox/js/ekko-lightbox.min.js"></script>
    ...

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 `data-gallery` attribute:

    <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>

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

    $("[data-toggle='lightbox']").click(function (evt) {
        evt.preventDefault();
        $(this).ekkoLightbox();
    });

Here are screenshots of a working example. We have 4 images with the same value of `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 `http-server` to start web server.
  2. Visit the web page at: <http://127.0.0.1:8080/chapter4/4.3/plugins.html> to view the plugins we used.
  3. 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/>
  2. 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 `.panel` class is dropped, we can now use the new class named `.card` to implement the same look like `.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, `h1` to `h6`. Bootstrap 4 removed their `margin-top` value and add `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 `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 `margin-top`, it provides 6 classes: `.mt-0`, `.mt-1`, `.mt-2`, `.mt-3`, `.mt-4` and `.mt-5`. `.mt-0` will set `margin-top` value to be 0, `.mt-5` will set it to `3rem`.

For example, we could add the `.mt-4` class to `h1`, `h2` and `h3`, `.mt-2` to `h4`, `h5` and `h6` :

    <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>

The second part includes the `<p>`, `<em>`, `<small>`, `<big>`, and `<code>` tags. They are basically the same as Bootstrap 3. The only change is the `<pre>` tag, which doesn't have a border or background color anymore.

The third part is the `blockquote` tag. We need to explicitly add the `.blockquote` class to it. Also, for footnotes, we need to add a `.blockquote-footer` class. Recall in Bootstrap 3 we have:

    <blockquote>
        <p> 
            Blockquote: quoted text here
        </p>
        <small>some celebrity</small>
    </blockquote>

Now we need to change it to:

    <blockquote class="blockquote"> 
        <p>
            Blockquote: quoted text here
        </p>
        <footer class="blockquote-footer">some celebrity</footer>
    </blockquote>

The last part is contextual text including the `.text-muted`, `.text-primary`, `.text-danger`, etc. We don't need to change them, but contextual background (like `.bg-primary`, `.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 `.text-white` class to change the text color to white.

    <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>
    ...

### Navigation bar

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

    <nav class="navbar navbar-toggleable-md navbar-light bg-faded">
    ...
    </nav>

For the link items in navigation bar, we need to add `.nav-item` to `<li>` tags and add `.nav-link` to the `<a>` tag which is inside `<li>`.

    <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>

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

    <li class="nav-item">
        <a href="#" class="nav-link">Alerts 
            <span class="badge badge-default badge-pill">3</span>
        </a>
    </li>

The great part is now we can combine those `.bg-*`, `.navbar-light/inverse`, and `.badge-*` classes to generate several different navigation bars, for example:

The first one we use `.navbar-light` and `.bg-faded` for `<nav>`; `.btn-secondary` (see more on the next "Buttons" section) for the submit button; and `.badge-default` for the alert badge.

The second one we use `.navbar-inverse` and `.bg-inverse` for `<nav>`; `.btn-outline-success` for the submit button; and `.badge-danger` for the alert badge.

The third one we use `.navbar-danger` and `.bg-inverse` for `<nav>`; `.btn-outline-secondary` for the submit button; and `.badge-warning` and `.badge-pill` for the alert badge.

### Buttons

There are several changes for buttons:

  1. `.btn-default` is renamed to `.btn-secondary`.
  2. `.btn-xs` is removed.
  3. 6 new classes `.btn-outline-secondary`, `.btn-outline-primary`, `.btn-outline-success`, `.btn-outline-info`, `.btn-outline-warning` and `.btn-outline-danger` are added.
  4. For buttons with dropdowns, in the dropdown menu for each link `<a>` we need to add a `.dropdown-item` class to it. We also need to change the divider's class to `.dropdown-divider`.

    <p>  
        <h3>Outline buttons</h3>
            <a href="#" class="btn btn-outline-secondary">Secondary</a>
            <a href="#" class="btn btn-outline-primary">Primary</a>
            <a href="#" class="btn btn-outline-success">Success</a>
            <a href="#" class="btn btn-outline-info">Info</a>
            <a href="#" class="btn btn-outline-warning">Warning</a>
            <a href="#" class="btn btn-outline-danger">Danger</a>
    </p>

    <h3>With dropdown</h3>
    <div class="btn-group">
        <a href="#" class="btn btn-secondary">Secondary</a>
        <a href="#" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></a>
        <ul class="dropdown-menu">
            <li><a class="dropdown-item" href="#">Action</a></li>
            <li><a class="dropdown-item" href="#">Another action</a></li>
            <li class="dropdown-divider"></li>
            <li><a class="dropdown-item" href="#">Separated link</a></li>  
        </ul>
    </div>

### Forms

Changes for forms:

  * Change the label's `.control-label` class to `.form-control-label`
  * Wrap the `checkbox` and `radio` type inputs inside a `div` with the class `.form-check` instead of `.form-group`. Give the `<label>` tag inside it a class `.form-check-label`, and the `<input/>` control a class `.form-check-input`
  * In our "horizontal form", give the label inside the `.form-group` container a class called `.col-form-label`
  * Change `.col-lg-offset-2` to `.offset-lg-2`
  * In contextual input, change `.has-error` to `.has-danger`
  * For the large input, change the class `.input-lg` to `.form-control-lg`, and `.input-sm` to `.form-control-sm`

Bootstrap 4 also added a set of classes to show customized form controls. Using those classes can keep your form control, e.g. select, checkbox, radio, consistent across different browsers. Those custom classes include `.custom-control`, `.custom-checkbox`, `.custom-radio`, `.custom-select`, `.custom-control-input`, `.custom-control-indicator`, etc.

For example, to show a checkbox with `.custom-*` classes, we can do:

    <label class="custom-control custom-checkbox">
        <input type="checkbox" class="custom-control-input">
        <span class="custom-control-indicator"></span>
        <span class="custom-control-description">Custom checkbox 1</span>
    </label>

We can compare the differences between the native style and customized style of those form controls.

Open with Google Chrome in macOS:

Open with Firefox in macOS:

We can see that with different browsers, the native style of checkbox looks different (in Google Chrome, it is slightly bigger), while the customized style stays consistent.

### Tables

There are only 2 changes we need to notice:

  * Class `.table-condensed` is renamed to `.table-sm` ;
  * In contextual tables, the class of `<tr>` like `.success`, `.warning`, etc. now should have `table-` prefix, e.g. `.table-success`, `.table-warning`, etc.

### Images

Changes for images:

  * `.img-responsive` is renamed to `.img-fluid`.
  * There is no `.img-rounded` class anymore. Now we can use the `.rounded` class to add a rounded border for an image. Same for the `.img-circle` class, now we use `.rounded-circle` instead.
  * There are several new utility classes we can use for images to round the corner: `.rounded-top`, `.rounded-right`, `.rounded-bottom`, `.rounded-left`. For example, `.rounded-top` will round the top 2 corners, `.rounded-right` will round the right 2 corners, etc.

### Tabs and Pills

For tabs and pills, we need to add `.nav-item` to each `<li>` element, and add `.nav-link` to the `<a>` inside `<li>`:

    <ul class="nav nav-tabs">
        <li class="nav-item">
            <a class="nav-link" href="#">Home</a>
        </li>
    </ul>
    <ul class="nav nav-pills">
        <li class="nav-item"><a class="nav-link active" href="#">Home</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Page1</a></li>
    </ul>

### Breadcrumbs

The only change is we need to add a `.breadcrumb-item` class to each list item like this:

    <ul class="breadcrumb">
        <li class="breadcrumb-item"><a href="#">Home</a></li>
        <li class="breadcrumb-item active">Library</li>
    </ul>

### Paginations

We need to add `.page-item` to each `<li>` element and `.page-link` to `<a>`:

    <ul class="pagination"> 
        <li class="page-item active"><a class="page-link" href="#">1</a></li>
        <li class="page-item"><a class="page-link" href="#">2</a></li>
    </ul>

### Pagers

The pager component is dropped, since it can be easily made by using outline buttons, so here we will simply remove this "pagers" section.

### Alerts

There are no changes for the "Alerts" component.

### Labels and Badges

The `.label`, `.label-success`, `.label-warning`, etc. classes are dropped, now we can use `.badge-*` classes, for example, `.badge`, `.badge-success`.

For badges, we need to use an extra `.badge-pill` class to make badges have a more rounded border. We can use it along with the `.badge` class to simulate the same look in Bootstrap 3.

    <span class="badge badge-default">label default</span>
    <span class="badge badge-success">label success</span>
    <span>Alerts <span class="badge badge-pill badge-default">4</span></span>

### List groups

To show badges on the right of list group item, we need to add the `.justify-content-between` class:

    <li class="list-group-item justify-content-between">
        List group item 1 <span class="badge badge-pill badge-default">1</span>
    </li>

Use the `.list-group-item-action` with `.list-group-item` to make an item actionable with hover and active states.

    <div class="list-group">
        <a href="#" class="list-group-item list-group-item-action">Link item 3</a>
        <a href="#" class="list-group-item list-group-item-action">Link item 4</a>
    </div>

### Media object

The new code template for a media object is:

    <div class="media">
        <a href="#">
            <img class="d-flex mr-3" src="http://lorempixel.com/50/50/animals/"/>
        </a>
        <div class="media-body">
            <h5>Media Heading</h5>
            Media content
         </div>
    </div>

### Progress bars

4 progress bar classes are dropped, including `.progress-bar-success`, `.progress-bar-info`, `.progress-bar-warning` and `.progress-bar-danger`, since we can use `.bg-success`, `.bg-info`, etc. to implement it. For example:

    <div class="progress">
        <div class="progress-bar bg-success" style="width: 40%"></div>
    </div>

The `.progress-striped` is also dropped. Now we use the `.progress-bar-striped ` and the `.progress-bar` classes to implement striped progress bars:

    <div class="progress">
        <div class="progress-bar progress-bar-striped bg-info" style="width: 20%"></div>
    </div>

### Panels

Panels are dropped in Bootstrap 4, but we can easily make it by using a newly introduced `.card` class.

For basic panels:

    <div class="card">
        <div class="card-header">
            Panel heading
        </div>
        <div class="card-block">
            Panel content
        </div>
        <div class="card-footer">
            Panel footer
        </div>
    </div>

For contextual panels, we can use the `.card-outline-*` class to change the border color, use `.bg-*` to fill the card header and use the `.text-white` to change header's text color to white. For example:

    <div class="card card-outline-success">
        <div class="card-header bg-success text-white">
            Panel success
        </div>
        <div class="card-block">
            Panel content
        </div>
    </div>

We use the `.card-outline-success` and `.bg-success` in the above example, you can change it to other contextual colors like `.card-outline-danger` and `.bg-danger`.

For panels with list groups, we need to add a class named `.list-group-flush` to the `<ul>` element, for example:

    <div class="card">
        <div class="card-header">Panel heading</div>
        <div class="card-block">Panel content </div>
        <ul class="list-group list-group-flush">
            <li class="list-group-item">item 1</li>
        </ul>
    </div>

### Wells

The wells component is also dropped, again we can use the `.card` class and padding utility classes `.p-0` to `.p-5` to implement it. In the example below we used `.bg-faded` to fill a gray background color for the well, but you can use other background colors like `.bg-success`, `.bg-info`, etc. to show a different color.

    <div class="col-xs-12 col-sm-4">
        <div class="card p-3 bg-faded">
            Text in a default well.
        </div>
    </div>
    <div class="col-xs-12 col-sm-4">
        <div class="card p-2 bg-faded">
            Text in a small well.
        </div>
    </div>
    <div class="col-xs-12 col-sm-4">
        <div class="card p-4 bg-faded">
            Text in a large well.
        </div>
    </div>

### Modals

For modals, to let the close button display on the top-right corner, we need to put it after the `.modal-title` element (in Bootstrap 3 we can put it before `.modal-title`, it will still show on the top-right corner). For example:

    <div class="modal-header">
        <h4 class="modal-title">Modal title</h4>
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">
            &times;
        </button>
    </div>

### Popovers

There are no changes for this part.

### Tooltips

Tooltips now rely on a third party library called _Tether_ (website: <http://tether.io/>, github: <https://github.com/HubSpot/tether>). To make the tooltips component work, we must include its Javascript file before _bootstrap.js_.

    ...
    <script
        src="https://rawgit.com/HubSpot/tether/master/dist/js/tether.min.js">
    </script>
    <script
        src="/path/to/bootstrap-4.0.0-alpha.6/dist/js/bootstrap.min.js">
    </script>
    ...

### Jumbotron

No changes for jumbotron, but to control the font size for the headline in jumbotron, like `<h1>`, we can use the `.display-1`, `.display-2`, `.display-3` and `.display-4` classes, among which the `.display-1` class has the biggest font size and `.display-4` has the smallest.

    <div class="jumbotron">
        <h1 class="display-3" id="jumboheader">Hello, world!</h1>
        <p class="lead">This is a simple hero unit, a simple jumbotron-style component.</p>
        <p class="lead"><a class="btn btn-primary btn-lg" href="#">Learn more</a></p>
    </div>

### Carousel

There are 2 changes for the carousel component:

  * Each slide item's class `.item` is named to `.carousel-item`.
  * The class of the left arrow control is changed to `carousel-control-prev`, and the icon's class is changed to `.carousel-control-prev-icon` because all of the glyphicons are dropped in Bootstrap 4; the class of the right arrow control is now `carousel-control-next` and the icon's class is `.carousel-control-next-icon`.

#### Practice

The above changes are all we need to make for the _theme-styles.html_ page, now it is time for you to view all of them:

  1. At this book's repository folder _make-bootstrap-themes_ , open a command/terminal window, then use `http-server` to start a web server.
  2. Visit it in your browser at: <http://127.0.0.1:8080/chapter5/5.1/theme-styles.html>

## 5.2 Sass

Like _Less_ we introduced in Chapter 2, _Sass_ is also a superset of CSS and it has very similar syntax like _Less_. Since now you should be familiar with _Less_ , here we will do a quick overview.

### Installation

In order to use _Sass_ , we need to install the `sass` command (like the `lessc` command we used before), check the installation instructions at: <http://sass-lang.com/install>.

Once it is installed, we can use it in our command/terminal window:

    $ sass test.scss test.css

It basically used the same way as we used _Less_ before: `$ lessc test.less test.css`. Notice in the above line, though the compiling command is `sass`, the file is named with a suffix _.scss_ , not _.sass_.

### Variables

_Less_ uses the `@` symbol to define a variable, _Sass_ uses the `$` symbol, for example:

    $color-warning: #ff6600;
    .panel-warning {
        color: $color-warning;
    }

is compiled to:

    .panel-warning {
      color: #ff6600;
    }

Another difference is, _Less_ uses `@{variable-name}` for string interpolation , while _Sass_ uses `#{$variable-name}`:

    $alertname: alert;
    .#{$alertname}-info {
        background-color: #339900;
    }

is compiled to:

    .alert-info {
        background-color: #339900;
    }

In addition, _Sass_ provides a `!default` keyword that we can assign to variables if they haven't been assigned yet. For example:

    $color: #ff6600;
    $color: #339900 !default;
    $font-base-size: 14px !default;

    p {
        color: $color;
        font-size: $font-base-size;
    }

We can interpret the `!default` keyword to "if this variable doesn't have a value yet, use this one; otherwise, ignore this one". In the above example, we use `!default` in the second line for the variable `$color`, but `$color` has been defined in the first line, so the second value `#339900` will be ignored. For the third line, the `$font-base-size` case, since this variable hasn't been defined before, `14px` will be used. Thus, the above code will be compiled to this:

    p {
        color: #ff6600;
        font-size: 14px;
    }

About variables, there is another major difference between _Less_ and _Sass_ , we will cover it in section 5.4 when we try overriding variables to customize a theme.

### Comment

Like _Less_ , _Sass_ also support 2 ways of commenting: `//` and `/* ... */`

### Arithmetical Opertors

_Sass_ also support `+`, `-`, `*`, `/`, for example:

    $size: 14px;
    $width: 60%;
    $color: #ff6600;

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

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

is compiled to:

    .text-lg {
        font-size: 28px;
        color: #803300;
    }

    .panel-lg {
        width: 80%;
        color: #ee4400;
    }

### Nested Rules

Same as _Less_ , the following example is from chapter 2.4 we wrote in _Less_ :

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

We can just use `sass` to compile it without any changes, then we can get this:

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

The generated CSS code is also the same as using the `lessc` command.

### Mixins

In _Sass_ , we use the `@mixin` directive to define a mixin, `@include` directive to include its code.

Recall in _Less_ we have:

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

Now in _Sass_ :

    @mixin bordered() {
        border: 1px dotted black;
    }
    .panel {
        background: #e1e1e1;
        @include bordered();
     }

### Parent Selector

_Sass_ uses the `&` symbol to refer parent selector, the same as _Less_. For example:

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

is compiled to:

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

### Builtin Functions

_Sass_ provides a list of builtin functions. In chapter 2.7 we introduced some commonly used functions in _Less_ , compare to those, below are functions defined in _Sass_ , which are basically the same in _Less_ :

  * _Less_ : floor, ceil = _Sass_ : floor, ceil
  * _Less_ : lighten, darken = _Sass_ : lighten, darken
  * _Less_ : rgb, red, green, blue = _Sass_ : rgb, red, green, blue
  * _Less_ : hsl, hue, saturation, lightness = _Sass_ : hsl, hue, saturation, lightness
  * _Less_ : fadein, fadeout = _Sass_ : fade-in, fade-out
  * _Less_ : spin = _Sass_ : adjust-hue

A quick example:

    $alert-warning-bg: #fcf8e3;
    $alert-warning-border: darken(adjust-hue($alert-warning-bg, -10), 5%);
    .alert-warning {
        background-color: $alert-warning-bg;
        border: 1px solid $alert-warning-border;
    }

After compilation:

    .alert-warning {
        background-color: #fcf8e3;
        border: 1px solid #faebcc;
    }

### Extend

In _Less_ we use `&:extend` to share CSS properties with other selectors, in _Sass_ we use the `@extend` directive instead.

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

After compilation:

    .btn, .btn-large {
        background-color: #ff6600;
        color: #ffffff;
    }

    .btn-large {
        padding: 5px 10px;
        font-size: 18px;
    }

### Import Files

Use the `@import` directive to import code from other `.scss` file, the filename suffix can be ignored. For example, if we have a _variables.scss_ , and _navbar.scss_ , in _navbar.css_ we can use `@import "variables";` to import code defined in _variables.scss_.

It also works if we rename the file name _variables.scss_ to __variables.scss_ which has a leading underscore, we don't need to change the `@import "variables";` statement. The _Sass_ compiler is smart enough to find the file named __variables.scss_ , however, if we have both the _variables.scss_ and __variables.scss_ file, for this `@import "variables";` statement, _Sass_ will throw an error:

    Error: It's not clear which file to import for '@import "variables"'.
        Candidates:
            _variables.scss
            variables.scss

The file with a leading underscore at its name is called partial _Sass_ file, the underscore lets _Sass_ know that this file should not be compiled and generated to a plain CSS file. So if we just want to import a _Sass_ file, we could add this leading underscore to its name.

### Additional Features

#### `@if` directive

The `@if` directive will evaluate an expression and use styles under the expression if it is true. For example:

    $enable-rounded: true;
    @mixin border-radius($radius) {
      @if $enable-rounded {
        border-radius: $radius;
      }
    }

    .panel {
      @include border-radius(5px);
    }

is compiled to:

    .panel {
      border-radius: 5px;
    }

You can use `@if` along with `@else`, like:

    @if expressionA {
        ...
    } @else {
        ...
    }

and with `@else if`:

    @if expressionA {
        ...
    } @else if expressionB {
        ...
    } @ else {
        ...
    }

#### Passing content blocks to a Mixin

If a mixin contains a `@content` block, we can override it when we include the mixin. For example:

    @mixin aa {
      .navbar {
        @content;
      }
    }
    @include aa {
      .logo {
        background-image: url(/logo.gif);
      }
    }

`@content` will be replaced by code:

    .logo {
        background-image: url(/logo.gif);
    }

So the above code becomes:

    .navbar {
      .logo {
         background-image: url(/logo.gif);
      }
    }

After compilation:

    .navbar .logo {
      background-image: url(/logo.gif);
    }

#### `@each` directive

The `@each` directive can loop through all items in a list. For example:

    @each $icon in (user, badge, trophy) {
      .icon-#{$icon} {
        background:url('../images/#{$icon}.png');
      }
    }

is compiled to:

    .icon-user {
      background: url("../images/user.png");
    }
    .icon-badge {
      background: url("../images/badge.png");
    }
    .icon-trophy {
      background: url("../images/trophy.png");
    }

It can also loop through a map (key-value pair structure) with `map-keys` and `map-get` function:

    $size-value: (
      xs: 5px,
      sm: 10px,
      md: 15px
    );
    @each $size in map-keys($size-value) {
      .padding-#{$size} {
        padding: map-get($size-value, $size);
      }
    }

The `map-keys` return a list of the map's keys, `map-get` can get a key's value from a map, so the above code is compiled to:

    .padding-xs {
      padding: 5px;
    }
    .padding-sm {
      padding: 10px;
    }
    .padding-md {
      padding: 15px;
    }

#### `@for` directive

The `@for` directive can help repeatedly generate a set of styles with a counter variable, for example:

    @for $i from 1 through 3 {
      .padding-#{$i} {
        padding: 5px * $i;
      }
    }

Here the `$i` is our counter variable, its initial value is 1, then 2 and 3. So after compilation:

    .padding-1 {
      padding: 5px;
    }
    .padding-2 {
      padding: 10px;
    }
    .padding-3 {
      padding: 15px;
    }

#### Practice

  1. Follow the instructions at the beginning of this section to install `sass` to your computer.
  2. In this book's repo, go to folder _chapter5/5.2_.
  3. Open a command/terminal window in this folder, then use `sass` to compile the following files: _variables.scss_ , _mixins.scss_ and _extend.scss_ under the folder, for example:

        $ sass variables.scss variables.css

  4. View the content of the compiled css files: _variables.css_ , _mixins.css_ and _extend.css_.

## 5.3 Bootstrap 4 code structure

Bootstrap 4 has similar structure as Bootstrap 3, it contains the following folders:

  * _dist_ : contains final compiled CSS and JS code
  * _docs_ : contains documentations
  * _grunt_ : files used for _grunt_
  * _js_ : contains raw Javascript files
  * _nuget_ : files used for _nuget_ package manager
  * _scss_ : contains _.scss_ files, which will finally be compiled to plain CSS

Compared to Bootstrap 3, you may notice that the _fonts_ folder is gone, since Bootstrap 4 doesn't use the Glyphicons font anymore, and suggests us to use them from other sources like FontAwesome (<http://fontawesome.io/>). Among the above folders, we will focus on the _scss_ since our customization work will mainly rely on the CSS part, other folder or files like _Gruntfile.js_ , _bower.json_ , etc., are related to building or shipping this package, so we can ignore them for now.

Under the _scss_ folder, there are 39 _.scss_ files and 2 folders:

  * 36 _.scss_ files with a leading underscore in their name, like __alert.scss_ , __badge.scss_ , etc. As we mentioned in the previous section, those files are called "partial files" and will be imported by other files.
  * 3 _.scss_ files: _bootstrap.scss_ , _bootstrap-grid.scss_ and _bootstrap-reboot.scss_. _bootstrap.scss_ is the one we use to generate the final Bootstrap plain CSS file _bootstrap.css_. The latter 2 files are for Bootstrap's grid system and CSS reset, Bootstrap provides those 2 files so we can generate 2 plain CSS files like _grid.css_ and _reboot.css_ then use them separately without including all of the CSS code in _bootstrap.css_.
  * 2 folders: _mixins_ and _utilities_. The _mixins_ folder contains 30 files for defining mixins, for example, `@mixin border-radius` is defined in __border-radius.scss_. The _utilities_ folder contains 13 files which define some utility CSS classes, for example, the `.border-0 { border: 0 !important; }` class is defined in file __borders.scss_.

The first 36 _.scss_ files with leading underscore in their filenames can be divided into 6 groups:

#### 1) Global variables and mixins:

  * __variables.scss_ : Defines global variables for colors, spaces, etc.
  * __mixins.scss_ : Defines mixins, this file also imported 30 mixins files under the _mixins_ folder.
  * __custom.scss_ : This is an empty file, Bootstrap provides this as a "hook" file so we can override some variables in this file when we do the customizations. We will visit it again in section 5.4.

#### 2) Reset:

  * __normalize.scss_ : Normalizes styles of HTML elements and attributes for all major browsers.
  * __print_ : Defines CSS for printing.

#### 3) Core CSS:

  * __reboot.scss_ : Resets styles for common HTML elements.
  * __type.scss_ : Defines styles for typography, for example, `h1` to `h6`, `hr`, `small`, `mark`, `blockquote` tags' styles are defined here.
  * __images.scss_ : Defines styles for images, including `.img-fluid`, `.img-thumbnail`, etc.
  * __code.scss_ : Defines styles related to code, for example, CSS for `pre`, `code`, `kbd` tags are defined here.
  * __grid.scss_ : Defines the grid system, `.container`, `.row`, `.col-lg-*`, `.col-md-*`, etc. are defined here.
  * __tables.scss_ : CSS related to tables, for example, `.table`, `.table-bordered`, `.table-striped`, etc.
  * __forms.scss_ : CSS for forms, including `.form-control`, `.form-group`, `.col-form-label` classes, etc.
  * __buttons.scss_ : CSS for buttons: `.btn`, `.btn-primary`, `.btn-danger`, `.btn-outline-info`, `.btn-outline-warning`, etc.

#### 4) Components

  * __transitions.scss_ : Defines CSS for transition animation, like `.fade`, `.collapsing`, etc.
  * __dropdown.scss_ : CSS for dropdowns, `.dropdown`, `.dropup`, `.dropdown-menu`, `.dropdown-item` are defined here.
  * __button-group.scss_ : CSS for button groups, including `.btn-group`, `.btn-toolbar`, `.btn-group-vertical` classes, are defined here.
  * __input-group.scss_ : CSS for input groups, including `.input-group`, `.input-group-addon`, `.input-group-btn` classes, are defined here.
  * __custom-forms.scss_ : In the form part of section 5.1, we mentioned that Bootstrap 4 added a new set of classes for showing form controls to keep them looking consistent across browsers. Classes like `.custom-control`, `.custom-checkbox`, `.custom-radio`, `.custom-select`, `.custom-control-input`, `.custom-control-indicator` are defined here.
  * __nav.scss_ : CSS for nav components, `.nav`, `.nav-link`, `.nav-tabs`, `.nav-pills`, `.nav-justified` are defined here.
  * __navbar.scss_ : CSS for navbar components, `.navbar`, `.navbar-brand`, `.navbar-text`, `.navbar-toggler`, `.navbar-light`, `.navbar-inverse`, etc. are defined here.
  * __card.scss_ : CSS for cards, including `.card`, `.card-block`, `.card-header`, `.card-footer` are defined here.
  * __breadcrumb.scss_ : CSS for breadcrumb.
  * __pagination.scss_ : Defines CSS for pagination, including `.pagination`, `.page-item`, `.pagination-lg`, `.pagination-sm`, etc.
  * __badge.scss_ : CSS for badges.
  * __jumbotron.scss_ : CSS for jumbotron.
  * __alert.scss_ : CSS for alert, `.alert`, `.alert-heading`, `.alert-success`, `.alert-warning`, etc. are defined here.
  * __progress.scss_ : CSS for progress bar.
  * __media.scss_ : Defines CSS for media components. Although the media components we made in section 5.1 looks complicated, most of the classes we used for it, including `.mt-3`, `.mr-3`, `.d-flex` are defined in __utilities.scss_. This __media.scss_ only defines 2 classes `.media` and `.media-body`.
  * __list-group.scss_ : Defines classes like `.list-group``, `.list-group-item`, etc.
  * __responsive-embed.scss_ : Defines classes like `.embed-responsive`, `.embed-responsive-21by9`, `.embed-responsive-16by9`, etc.
  * __close.scss_ : Defines `.close` and `button.close` classes.

#### 5) Components with Javascript

Below 4 files define components that work with Javascript:

  * __modal.scss_ : CSS for modals.
  * __tooltip.scss_ : CSS for tooltips.
  * __popover.scss_ : CSS for popovers.
  * __carousel.scss_ : CSS for carousels.

#### 6) Utility classes

File __utilities.scss_ imports all 13 _scss_ files under the _utilities_ folder, those 13 files define all of the util classes:

  * __align.scss_ : Defines `.align-top`, `.align-middle`, `.align-bottom`, etc.
  * __background.scss_ : Defines `.bg-faded`, `.bg-primary`, `.bg-success`, etc.
  * __borders.scss_ : Defines CSS for borders, like `.border-0`, `.rounded`, `.rounded-top`, `.rounded-circle`, `.rounded-0`.
  * __clearfix.scss_ : Defines `.clearfix` class.
  * __display.scss_ : Defines classes for display style, for example, `.d-inline` is set as `display: inline !important`, `.d-flex` is set as `display: flex !important`.
  * __flex.scss_ : Defines classes for flex layout, for example, `.flex-row`, `.flex-column`, `.justify-content-start`, `.align-items-start` classes are defined here.
  * __float.scss_ : CSS for float, `.float-left`, `.float-right` and `.float-none` are defined here.
  * __position.scss_ : CSS for positioning, `.fixed-top`, `.fixed-bottom` and `.sticky-top` are defined here.
  * __screenreaders.scss_ : Defines 2 classes `.sr-only` and `.sr-only-focusable` for screenreader. 
  * __sizing.scss_ : Defines classes for width and height, for example, `.w-25` is defined as `width: 25% !important;`, `.h-50` is `height: 50% !important`, `.mw-100` is `max-width: 100% !important`.
  * __spacing.scss_ : Defines util classes for margin and padding, for example, `.mt-0` is `margin-top: 0 !important`, `.pb-1` is `padding-bottom: 0.25rem !important`, `.pr-2` is `padding-right: 0.5rem !important`.
  * __text.scss_ : Defines util classes for text, including `.text-justify`, `.text-nowrap`, `.text-left`, `.text-right`, `.text-white`, `.text-muted`, `.text-danger`, `.text-hide`, etc.
  * __visibility.scss_ : Defines classes for visibility, for example, `.invisible`, `..hidden-xs-up`, `.hidden-md-down`, `.visible-print-block`, etc. are defined here.

#### Practice

We mentioned that the _bootstrap.scss_ file is the one used to generate compiled CSS file, so let's try compiling it:

  1. In this book's repository folder, go to _bootstrap-4.0.0-alpha.6/scss_
  2. Open a command/terminal window at this folder, then use `sass` to compile the _bootstrap.scss_ to _bootstrap.css_ :

        $ sass bootstrap.scss bootstrap.css

  3. Go to folder _chapter5/5.3/_ , in the _theme-styles.html_ , at line #6 change the code:

        <link rel="stylesheet" href="/bootstrap-4.0.0-alpha.6/dist/css/bootstrap.css"/>

to:

        <link rel="stylesheet" href="/bootstrap-4.0.0-alpha.6/scss/bootstrap.css"/>

Notice that now we are using our own compiled bootstrap 4 CSS file.

  4. At this book's repository folder _make-bootstrap-themes_ , open a command/terminal window, then use `http-server` to start a web server.
  5. Visit the URL in your browser: <http://127.0.0.1:8080/chapter5/5.3/theme-styles.html>. It should look the same as the one in section 5.1: <http://127.0.0.1:8080/chapter5/5.1/theme-styles.html>

## 5.4 Customization

In this section we are going to make a simple theme for Bootstrap 4. Remember no matter which version it is, the method for building a theme is essentially the same: override those default CSS rules. This also means the methods in previous chapters we learned to make themes for Bootstrap 3 could also be applied for Bootstrap 4.

In the last section we mentioned that in Bootstrap 4's source code, there is an empty file named __custom.scss_ , Bootstrap 4 provides this file as a "hook" so we can override some variables in this file when we do the customization. So let's try to redefine some variables in this file.

### $enable-* variables

Which variable should we choose to override? The easiest way would be, override the `$enable-*` variables, by that I mean, if we check the __variables.scss_ file, there are 7 `$enable-*` variables, listed below:

    $enable-rounded:            true !default;
    $enable-shadows:            false !default;
    $enable-gradients:          false !default;
    $enable-transitions:        true !default;
    $enable-hover-media-query:  false !default;
    $enable-grid-classes:       true !default;
    $enable-print-styles:       true !default;

These variables are like switches, for example, by default we can see a lot of components in Bootstrap 4 have rounded corners, those rounded corner are actually controlled by the `$enable-rounded` variable, or we call it "switch". From the above 7 variables we can see the default theme basically enabled rounded corners, disabled gradient effects, disabled shadow effects, enabled transition animations, etc.

You must have guessed that we could just redefine those "switch" variables' values to easily generate a theme, so let's try it.

In this book's repo, go to folder _bootstrap-4.0.0-alpha.6/scss_ , open __custom.scss_ file with your favorite editor, this file doesn't have any content except some comments for now, let's redefine 2 variables:

    $enable-rounded:          false;

You can see here we are trying to disable the rounded corners, let's compile it, in this _scss_ folder, start a command/terminal window, then run the command:

    $ sass bootstrap.scss bootstrap.css

I already put a _theme-styles.html_ file in folder _chapter5/5.4_ and added a CSS link to this `bootstrap.css` file, so after you used the above command to generate the `bootstrap.css` file, simply go to this book's repository folder _make-bootstrap-themes_ , open a command/terminal window, use `http-server` command to start a web server, then open the url <http://127.0.0.1:8080/chapter5/5.4/theme-styles.html> in your browser.

If you compare this page with <http://127.0.0.1:8080/chapter5/5.1/theme-styles.html>, you can see now all of rounded corners are gone!

Buttons:

Alerts:

Panels/Cards:

Given we only added one line of code to change only one variable, this looks great, we now have the first customized theme of Bootstrap 4!

Please also notice, if you are trying to change the "gradient" variable to enable gradient effects like this:

    $enable-gradients: true;

After recompilation and generating the bootstrap CSS file, if you refresh the _theme-styles.html_ page, there isn't any change, components like buttons still don't have a gradient background color. A reasonable guess is, this version _bootstrap-4.0.0-alpha.6_ doesn't support all of those switch variables yet, so this might work when bootstrap 4 is officially released.

### Color variables

In this part we are going to override more variables like we did in chapter 3.4, but before we do it, we need to learn a major difference between _Sass_ and _Less_ , which will help us to do the overriding.

Let's check the following _Less_ code for example:

    @color: #ff6600;
    @brand-primary: @color;

    p {
        color: @brand-primary;
    }

    @color: #339900;

We first define the `@color` variable, and let the `@brand-primary` refer the value of `@color`, then in the CSS of the `p` tag, we set its color to be `@brand-primary`. In the last line we redefine the value of `@color` to be `#339900`. After compilation with `lessc`, we have the following code:

    p {
        color: #339900;
    }

Notice that the color of `p` is `#339900`.

Now let's write the same code with _Sass_ syntax:

    $color: #ff6600;
    $brand-primary: $color;

    p {
        color: $brand-primary;
    }

    $color: #339900;

This time after compilation with _Sass_ , we have:

    p {
        color: #ff6600;
    }

Now the color of `p` is `#ff6600`, we are trying to override `$color`'s value in the last line and `$brand-primary` refers to this `$color`, but apparently `p` is still using the previous color `#ff6600`, not the new one `#339900`, this is different with code generated by _Less_.

It turns out _Less_ and _Sass_ are using different ways to generate variables' values. In _Less_ , it first collects all variables' values, then generates the final value for each variable, if there are multiple definitions for the same variable, the last one wins. In the above example, once _Less_ collects all variables, `@color` is set to be `#339900`, then the `@brand-primary` will also set to be `#339900`, thus, the color of the `p` tag is set to `#339900`. While _Sass_ uses a different methodology, it won't first collect all variables to decide their final values, instead, it uses "first come, first serve" method: when it scans to `$brand-primary`, its value is already defined as the first `$color`'s value `#ff6600`, later we redefine `$color` to be `#339900`, but it will not change the `$brand-primary`'s value, so the color of the `p` tag is still `#ff6600`.

Let's see another example, suppose we have the following code in _Less_ :

    @color: #ff6600;
    p {
      color: @color;
    }

    @color: #339900;
    h1 {
      color: @color;
    }

Compiled to:

    p {
      color: #339900;
    }
    h1 {
      color: #339900;
    }

Notice both `p` and `h1` use the color `#339900`, which means _Less_ first collects all variables and finds that the final value of `@color` is `#339900`, so it uses this value in every place where `@color` appears.

Now let's try the same code in _Sass_ :

    $color: #ff6600;
    p {
      color: $color;
    }

    $color: #339900;
    h1 {
      color: $color;
    }

Compiled to:

    p {
      color: #ff6600;
    }
    h1 {
      color: #339900;
    }

Notice now the `p` tag is using color `#ff6600`, while the `h1` tag is using `#339900`, which means _Sass_ uses the former definition when it generates code for `p`. This is because it doesn't first scan all the variables, it doesn't know we will redefine `$color` later, when it generates code for the `p` tag, at that time `#ff6600` is `$color`'s value. Then on the next line we override `$color` to be `#339900`, which means that now `$color`'s value is `#339900`, so the next `h1` tag uses this value.

How would this affect our overriding for Bootstrap 4? Well, in last section we mentioned in this version _v4.0.0-alpha.6_ , Bootstrap 4 imports first 3 files in this order:

    @import "variables";
    @import "mixins";
    @import "custom";

The __custom.scss_ file is the one Bootstrap wants us to use to override some variables, but it comes after `@import "variables"`. In the __variables.scss_ file we have code like this:

    $brand-primary:     #0275d8 !defafult;
    $btn-primary-bg:    $brand-primary !default;

Notice this `$btn-primary-bg` is the background color for `.btn-primary` class, and if we want to change `$brand-primary`'s color value, we may add the following code to __custom.scss_ file to override its color:

    $brand-primary: #3B4A6B;

Apparently when we override this value, we want to change all of the places referring this `$brand-primary` color, like the background color of `.btn-primary` class. However, since in this _v4.0.0-alpha.6_ version, Bootstrap imports __variables.scss_ first then imports the __custom.scss_ , those above variables' order will be like this:

    $brand-primary:     #0275d8 !defafult;
    $btn-primary-bg:    $brand-primary !default;
    // use $brand-primary here, its value is #0275d8
    ...
    $brand-primary: #3B4A6B;
    // use $brand-primary here, now it is #3B4A6B
    // use $btn-primary-bg here, now it is still #0275d8

If we use `sass` to compile the code, we can see the value of `$btn-primary-bg` is still `#0275d8`, not `#3B4A6B`. We want to change all places where use this `$brand-primary` variable, and places where refer to it, like `$brand-primary-bg`, but clearly _Sass_ won't do it in this way.

There are several ways to solve this problem, the first one is, when we override the `$brand-primary`'s value, also override all variables referring it, in the above example, after we define `$brand-primary`, we need to also explicitly redefine the `$btn-primary-bg`, so in our __custom.scss_ we have:

    $brand-primary: #3B4A6B;
    $btn-primary-bg: $brand-primary;

This will override `$btn-primary-bg`'s value, so the background color of `.btn-primary` class will now change to `#3B4A6B`, but this way is cumbersome and infeasible: we need to override all variables referring to it, like `$link-color`, `$pagination-active-bg`, etc.

The second way is, we can change the importing order in _Bootstrap.scss_ file: first import the __custom.scss_ file, then the __variables.scss_ :

    @import "custom";
    @import "variables";
    @import "mixins";
    ...

In this case, if we define `$brand-primary: #3B4A6B` in __custom.scss_ , the later code `$brand-primary: #0275d8 !defafult` in __variables.scss_ won't override it, because there is a `!default` keyword (if you forgot what it is, check the _variables_ section in chapter 5.2), then the later code `$btn-primary-bg: $brand-primary; ` will set `$btn-primary-bg`'s value to be `#3B4A6B `, so `.btn-primary` class will use our custom color as its background color.

By just switching the importing order in _Bootstrap.scss_ , we can solve the problem, but I am trying to avoid modifying its source code to do the customization. After all, this problem should be fixed by Bootstrap. (Update: at the time of writing this book, Bootstrap 4's current _v4-dev_ branch already fixed it, we can expect in its future release _v4.0.0-alpha.7_ or _v4-beta_ , this importing order will be changed.)

If we don't change the importing order, the third way is, let's forget this __custom.scss_ hook file, we will just leave it empty, but we will create a new file _my-theme.scss_ , in this file we first redefine variables, then import _bootstrap.scss_ :

    $brand-primary: #3B4A6B;
    @import "bootstrap";

Like the second way, we make sure our custom values show first, then Bootstrap's default value in __variables.scss_ will not override it since it uses the `!default` keyword.

I'll use the last method to do our customization: go to code repo's folder _chapter5/5.4_ , open the file _my-theme.scss_ , you will see something like this:

    @import url('https://fonts.googleapis.com/css?family=Roboto+Slab');
    $font-family-serif: 'Roboto Slab', Georgia, "Times New Roman", serif;
    $font-family-base: $font-family-serif;

    $enable-rounded: false;

    // brand contextual colors
    $brand-primary: #3B4A6B;
    $brand-success: #52D681;
    $brand-info: #22B2DA;
    $brand-warning: #FFC24A;
    $brand-danger: #F23557;
    ...
    @import "../../bootstrap-4.0.0-alpha.6/scss/bootstrap";

I imported a new font named `Roboto Slab` from Google font as my theme's default font, disabled rounded corners and refined some brand contextual colors, in last line I imported bootstrap's scss source file.

What does this theme look like? Practice time!

#### Practice

  1. Go to folder _chapter5/5.4_ , open _my-theme.scss_ file and learn its content.
  2. In this folder, open a command/terminal window, then use _sass_ command to compile _my-theme.scss_ :

        $ sass my-theme.scss my-theme.css

This will generate _my-theme.css_ file.

  3. In the same folder, open the _theme-styles.html_ , at line #5, change the CSS file url to _my-theme.css_ :

        <link rel="stylesheet" href="my-theme.css"/>

  4. At this book's repository folder _make-bootstrap-themes_ , open a command/terminal window, then use `http-server` command to start a web server.
  5. Visit <http://127.0.0.1:8080/chapter5/5.4/theme-styles.html> in your browser.

Here are some screenshots for this theme:

Buttons:

Alerts:

Panels/Cards:

In this section we covered the way to override variables for Bootstrap 4, we will end here and won't go further since Bootstrap 4 is still under active development, the method we introduced here might have changed when Bootstrap 4 is officially released. But to do customization, the key idea is the same: we need to find a way to override its default styles. Thus, the method we learned in chapters 3 and 4 can also be applied here for Bootstrap 4. Now it is your practice time to create your own themes.

# Appendix A - RGB and HSL color space conversions

In chapter 2 we introduced the `lightness`, `darken`, `hsl` functions in _Less_ , to recap, when we pass a RGB color to the `lightness` function, it first converts this RGB color to the HSL color space, then changes the lightness channel's value, and finally changes it back to RGB color, so in this process the conversion happens between the RGB and HSL color spaces.

The conversion requires some calculations, for the algorithm details, I included `rgb2hsl` and `hsl2rgb` functions in this book's example code (written in Javascript), you can check them at code repository file _appendix/color_conversion.js_.

Moreover, in chapter 2 we used an example: _Less_ increases the lightness of the color `#be4c0f ` by 15% to color `#ee6f2b `, let's reproduce it with our own `rgb2hsl` and `hsl2rgb` functions:

    let color = '#be4c0f';
    let rgb = hex2rgb(color);
    let hsl = rgb2hsl(rgb.r, rgb.g, rgb.b);
    console.log('To HSL color space: ', hsl);

    // increase lightness by 15%
    hsl.l += 0.15;
    console.log('Add 15% lightness: ', hsl);

    // convert HSL back to RGB
    rgb = hsl2rgb(hsl.h, hsl.s, hsl.l);
    console.log('To RGB color space: ', rgb);
    console.log('Color hex code is: ', rgb2hex(rgb.r, rgb.g, rgb.b));

Output:

    To HSL color space:  { h: 20.91, s: 0.85, l: 0.4 }
    Add 15% lightness:  { h: 20.91, s: 0.85, l: 0.55 }
    To RGB color space:  { r: 238, g: 111, b: 43 }
    Color hex code is:  #ee6f2b

We can see by using the functions defined in the above file, we successfully changed color `#be4c0f ` to `#ee6f2b` by increasing its lightness by 15%, which is exactly the same as we did in chapter 2 with _Less_ 's `lightness` function. 

# Appendix B - Resources

## Bootstrap

Website: http://getbootstrap.com

If you are looking for documentations on some old versions of Bootstrap, this website can help:  http://bootstrapdocs.com/

Bootstrap's source code:  https://github.com/twbs/bootstrap

Version 3.3.7:  https://github.com/twbs/bootstrap/tree/v3.3.7

Version 4.0.0-alpha.6: <https://github.com/twbs/bootstrap/tree/v4.0.0-alpha.6>

Bootstrap 4 code migration guideline:

<https://v4-alpha.getbootstrap.com/migration/>

Additional showcases and add-ons: <https://expo.getbootstrap.com/resources/>

## Less

Website:  http://lesscss.org/

Source code:  https://github.com/less/less.js

Online converter:  http://less2css.org/

## Sass

Website: <http://sass-lang.com/>

Source code: <https://github.com/sass/sass>

Online converter: <https://www.sassmeister.com/>

## Glyphicons

Bootstrap's Glyphicons contains a limited icon set. Sometimes we may use glyphicons from other websites like:

  * Font Awesome: <http://fontawesome.io/>
  * Ion Icons: <http://ionicons.com/>

The above 2 websites contains hundreds of icons, they can meet our needs in most cases. You can also try the GlyphSearch website: <http://glyphsearch.com/>, which helps search icons from a bunch of resources, including font-awesome, ion-icons, foundation-icons, etc.

## Free Bootstrap themes:

Bootswatch (<http://bootswatch.com/>) provides several themes for free:

You can download its source code at  https://github.com/thomaspark/bootswatch , check the source code to learn how those themes are made.

You can also download some free themes at StartBootstrap <https://startbootstrap.com/>

## Image placeholder website

In our themes often we need some images as placeholders, e.g. user's avatar picture in media component, pictures used as banner image, pictures in the carousel component, etc. Here are some websites you can use:

  * <https://unsplash.it/>
  * <http://lorempixel.com/>
  * <https://placeimg.com/>
  * <https://www.pexels.com/>
  * <https://pixabay.com>

## Theme colors

When you design a new theme, usually you need to first pick some colors for it, you may already have your own palette if you are an experienced designer, but if you don't have any, the websites below may give you some inspiration:

  * <http://colorhunt.co/>
  * <https://coolors.co>

## Plugins

In chapter 4.3 we introduced some plugins for Bootstrap, here are some more:

  * Bootstrap select: <https://github.com/silviomoreto/bootstrap-select>
  * Bootstrap star rating: <http://plugins.krajee.com/star-rating-demo-basic-usage>
  * Bootstrap Dialog: <https://nakupanda.github.io/bootstrap3-dialog/>

If you are creating a theme or template for an admin page, you may need Javascript to create charts in some "dashboard" page, here are some Javascript libraries you can use to do it:

  * Morris.js: <http://morrisjs.github.io/morris.js/>
  * ChartJS: http://www.chartjs.org
  * Google Charts: <https://developers.google.com/chart/>

If you want to explore more, people keep submitting new resources in the Bootstrap-expo page: <https://github.com/twbs/bootstrap-expo/issues>

## Marketplaces

If you want to sell your themes to marketplaces, here are some popular ones:

  * <https://themeforest.net>
  * <https://wrapbootstrap.com/>
  * <https://creativemarket.com/themes/bootstrap>
  * <http://bootstrapbay.com/>
  * <https://gridgum.com/>
  * <https://bootstrapmade.com/>

  1. Preface
    1. Prerequisites
    2. Code examples
    3. Feedback
    4. Acknowledgments
  2. Chapter 1 - Setup Workbench
    1. 1.1 Install Node.js & npm
    2. 1.2 Install http-server and Less
    3. 1.3 Get Bootstrap Source Code
    4. 1.4 theme-styles.html
  3. Chapter 2 - Introduction to Less
    1. 2.1 Variable
    2. 2.2 Comment
    3. 2.3 Arithmetical Operators
    4. 2.4 Nested Rules
    5. 2.5 Mixins
    6. 2.6 Parent Selector
    7. 2.7 Builtin Functions
    8. 2.8 Extend
    9. 2.9 Import Files
  4. Chapter 3 - Customization
    1. 3.1 Inside Bootstrap
    2. 3.2 A small customization
    3. 3.3 Utilizing Variables
    4. 3.4 A light color theme
    5. 3.5 A dark color theme
  5. Chapter 4 - More Customizations
    1. 4.1 Starter Theme
    2. 4.2 Additional Classes
    3. 4.3 Plugins
    4. 4.4 Pack up theme files
  6. Chapter 5 - A glance at Bootstrap 4
    1. 5.1 Use Bootstrap 4 theme
    2. 5.2 Sass
    3. 5.3 Bootstrap 4 code structure
    4. 5.4 Customization
  7. Appendix A - RGB and HSL color space conversions
  8. Appendix B - Resources
    1. Bootstrap
    2. Less
    3. Sass
    4. Glyphicons
    5. Free Bootstrap themes:
    6. Image placeholder website
    7. Theme colors
    8. Plugins
    9. Marketplaces

