Chapter 6. Polishing the Responsive Portfolio Website with LESS
In the preceding chapter, we constructed the portfolio website structure with HTML5 and a couple of Bootstrap drop-in classes. The website as you might have seen isn't yet decorated. We haven't yet composed our very own styles or linked the style sheet to the page. So, this chapter's focus will be on website decoration.
Bootstrap primarily uses LESS to generate the styles of its components. Following suit, we will also use LESS to style the portfolio website. LESS brings a number of features, such as variables and mixins, that would allow us to write leaner and more efficient style rules. At the end of the day, you will also find customizing and maintaining website styles with LESS is easier than with plain CSS.
Furthermore, we've also used a Bootstrap extension called Jasny Bootstrap to include off-canvas navigation into the portfolio website. At this stage, nothing will happen to the off-canvas navigation; we only set out the HTML structure. So, in this chapter, apart from compiling the website styles, we will also compile the JavaScript library of both Bootstrap and Jasny Bootstrap to make the off-canvas navigation function.
In this chapter, we will discuss many things, including the following topics:
- Learn the basic LESS syntax, such as variables and mixins
- Organize the style sheet references with LESS
@import
directive - Configure Koala to compile LESS into regular CSS
- Look into the source map to debug LESS
- Compose the website custom styles with LESS
- Compile JavaScript to activate off-canvas navigation
Basic LESS syntax
LESS (http://lesscss.org/) is a JavaScript-based CSS preprocessor developed by Alexis Sellier (http://cloudhead.io/), also known as CloudHead. As mentioned, Bootstrap uses LESS to compose its component styles—though it only recently released the Sass version officially. As mentioned, we will follow Bootstrap to use LESS to compose our own style rules and manage style sheets.
In a nutshell, LESS extends CSS by bringing some programming features, such as variable, function, and operation. CSS is a straightforward language and fundamentally very easy to learn. However, maintaining static CSS is practically exhaustive, particularly when we have to deal with a thousand lines of style rules and multiple style sheets. The capabilities that LESS offers, such as variable, mixins, function, and operation (which we are going to take a look at shortly) will allow us to develop style rules that will be easier to maintain and organize.
Variables
A variable is the most fundamental feature in LESS. A variable in LESS, as in other programming languages, is used to store a constant or a value that can be reused later limitlessly within the entire style sheet. In LESS, a variable is declared with an @
sign and is followed by the variable name. The variable name can be a combination of numbers and letters. In the following example, we will create a couple of LESS variables to store some colors in the HEX format and assign them in the succeeding style rules to pass the colors, as shown in the following code:
@primaryColor: #234fb4;
@secondaryColor: #ffb400;
a {
color: @primaryColor;
}
button {
background-color: @secondaryColor;
}
Using a LESS compiler, such as Koala, the preceding codes will be compiled into static CSS, as follows:
a {
color: #234fb4;
}
button {
background-color: #ffb400;
}
Using variables is not only limited to storing colors as we just demonstrated. We can use variables for any type of values, for example:
@smallRadius: 3px;
One of the advantages of using a variable is that, if we have to make a change, we will only need to change the value within the variable. The change we make will take place in every occurrence of that variable in the style sheet. This is certainly a time saver. Scanning through the style sheet and making the change singly or perhaps with the search and replace feature of the code editor might cause unintended changes if not done carefully.
Note
You will find the term compile and compiler often. The word compile herein means that we convert the LESS into standard CSS format that can be rendered in the browser. Compiler is the tool used to do so. In this case, the tool we are using is Koala.
Nesting style rules
LESS lets us nest style rules into one another. Traditionally with plain CSS, when we want to apply style rules to elements, say, under a <nav>
element, we can compose the style rules in the following way:
nav {
background-color: #000;
width: 100%;
}
nav ul {
padding: 0;
margin: 0;
}
nav li {
display: inline;
}
As we can see from the preceding example, we repeat the nav
selector each time we apply styles to a particular element nested under the <nav>
element. By using LESS, we are able to eliminate this repetition and simplify it by nesting the style rules, as follows:
nav {
background-color: #000;
width: 100%;
ul {
padding: 0;
margin: 0;
}
li {
display: inline;
}
}
Eventually, the preceding style rules will return the same result—only we write the style rules more efficiently this time.
Mixins
Mixins are one of the most powerful features in LESS. Mixins simplify style rules declaration by allowing us to create a group of CSS properties that can be included in other style rules in the style sheets. Let's take a look at the following code snippet:
.links {
-webkit-border-radius: 3px;
-mox-border-radius: 3px;
border-radius: 3px;
text-decoration: none;
font-weight: bold;
}
.box {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
position: absolute;
top: 0;
left: 0;
}
.button {
-webkit-border-radius: 3px;
-mox-border-radius: 3px;
border-radius: 3px;
}
In the preceding example, we declared border-radius
in three different style rules along with the vendor prefix to cover earlier versions of Firefox- and Webkit-based browsers. In LESS, we are able to simplify border-radius
declaration by creating a mixin. A mixin in LESS is simply specified with a class selector. Given the preceding example, let's create a mixin named .border-radius
to contain the border-radius
properties, as follows:
.border-radius {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
Afterwards, we include .border-radius
into the succeeding style rules to pass the containing properties into them, as follows:
.links {
.border-radius;
text-decoration: none;
font-weight: bold;
}
.box {
.border-radius;
position: absolute;
top: 0;
left: 0;
}
.button {
.border-radius;
}
This code will produce exactly the same output as in the first code snippet of this section when compiled into static CSS.
Parametric mixins
Furthermore, we can also extend the mixins into so-called parametric mixins. This feature allows us to add arguments or variables and turn the mixins to be configurable. Let's take the same example as in the preceding section. But, this time, we will not assign a fixed value; instead, we replace it with a variable, as follows:
.border-radius(@radius) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
Now, we can insert this mixin into other style rules and assign a different value to each:
a {
.border-radius(3px);
text-decoration: none;
font-weight: bold;
}
div {
.border-radius(10px);
position: absolute;
top: 0;
left: 0;
}
button {
.border-radius(12px);
}
When we compile it into regular CSS, each style rule is applied with a different border-radius
value, as follows:
a {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
text-decoration: none;
font-weight: bold;
}
div {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
position: absolute;
top: 0;
left: 0;
}
button {
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
}
Specify a default value in a parametric mixin
Furthermore, we can specify a default value in a parametric mixin, which will be useful in case a parameter is not passed. When we set a parameter in a mixin, as we did in the preceding example, LESS will take the parameter as a requirement. If we do not pass a parameter in it, LESS will return an error. So, let's take the preceding example and extend it with a default value, say, 5px
, as follows:
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
The preceding parametric mixin will return the border radius of 5px
by default. The default value will be overwritten if we pass a custom value within brackets.
Merging mixins with extend syntax
Extend syntax is the long-awaited feature to come into LESS. One main issue with LESS mixins is that it simply copies the containing CSS properties of a mixin, thus producing duplicate code. Again, if we are dealing with a large-scale website with a thousand lines of codes, the amount of duplicated code would make the style sheet size unnecessarily large.
In Version 1.4, LESS introduced extend syntax. The extend syntax comes in a form that is similar to a CSS pseudo-class, :extend
. The extend syntax will group CSS selectors that inherit the properties set containing the mixin. Compare the following two examples.
To begin with, we include a mixin without the :extend
syntax:
.border-radius {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.box {
.border-radius;
position: absolute;
top: 0;
left: 0;
}
.button {
.border-radius;
}
The preceding LESS code is short, but when it is compiled into CSS, the code extends to around 17 lines, as the border-radius
properties are repeated or simply copied in every style rule, as follows:
.border-radius {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.box {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
position: absolute;
top: 0;
left: 0;
}
.button {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
In this second example, we will put the :extend
syntax into practice into the same mixin:
.border-radius {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.box {
&:extend(.border-radius);
position: absolute;
top: 0;
left: 0;
}
.button {
&:extend(.border-radius);
}
The following is how the code turns into plain CSS; it becomes even shorter than the initial uncompiled LESS codes.
.border-radius,
.box
.button {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.box {
position: absolute;
top: 0;
left: 0;
}
Generating value with mathematical operations
We can also perform math operations with LESS-like addition, subtraction, division, and multiplication. Operations could be pretty useful to determine a length, such as the element's width and height. In the following example, we will calculate the proper box width by subtracting it with the padding so that it can be fit into the parent container.
First, we will define the variable for the padding with the @padding
variable:
@padding: 10px;
Then, we specify the box width and subtract it with the @padding
variable:
.box {
padding: @padding;
width: 500px – (@padding * 2);
}
Remember that the padding takes two sides of the box, whether it is right and left or top and bottom, so that is why we multiply @padding
in the width property by two. Finally when we compile this LESS operation into the regular CSS, this code will look as follows:
.box {
padding: 10px;
width: 480px;
}
In other cases, we can do the same to the height property, as follows:
.box {
padding: @padding;
width: 500px – (@padding * 2);
height: 500px – (@padding * 2);
}
Generating color with mathematical operations and LESS functions
Believe it or not, in LESS, we can alter colors with math operations. It's like mixing paint colors, except we do it by addition, subtraction, division, and multiplication. For instance:
.selector {
color: #aaa + 2;
}
When compiled, the color turns into the following:
.selector {
color: #acacac;
}
Furthermore, LESS also provides a handful of functions that allow us to turn colors darker or lighter to a certain extent. The following example will lighten the color in the @color
variable by 50%
.
@color: #FF0000;
.selector {
color: lighten(@color, 50%);
}
Alternatively, to darken the color, use the darken()
function, as follows:
@color: #FF0000;
.selector {
color: darken(@color, 50%);
}
Note
A complete list of the LESS color function can be found in the following page of LESS's official website (http://lesscss.org/functions/#color-operations).
Referential import
This is one of my favorite features in LESS. The referential import, as the name implies, allows us to import an external style sheet merely as reference. Prior to the emerging of this feature, all style rules in the style sheet imported with the @import
directive will be appended, which is more often than not unnecessary.
Since Version 1.5, LESS introduced the (reference)
option that marks @import
as reference, thus preventing the external style rules from being appended. Add the (reference)
mark after @import
, as follows:
@import (reference) 'partial.less';
Using a variable in an import statement
One of the constraints that LESS used to encounter was when using a variable within the @import
directive (https://github.com/less/less.js/issues/410). It is one of the most requested features to present in LESS and finally has been resolved since LESS 1.4. We are now able to declare a variable in an @import
statement by naming the variable within curly braces, for example, @{variable-name}
.
The use of a variable along with @import
will allow us to define the style sheet path once, through a variable. Then, call the path using the variable, as follows:
@path: 'path/folder/less/';
@import '@{path}mixins.less';
@import '@{path}normalize.less';
@import '@{path}print.less';
This approach is visibly neater and more efficient than having to add the full path every time we import a new style sheet, as follows:
@import 'path/folder/less/mixins.less';
@import 'path/folder/less/normalize.less';
@import 'path/folder/less/print.less';
Note
Refer to the Import Directive section of the LESS official website (http://lesscss.org/features/#import-directives-feature) for further assistance on importing an external style sheet with LESS.
Using source map for easier style debugging
While CSS preprocessors like LESS allows us to write style rules more efficiently, the browsers are still only able to read plain CSS, which will cause a new problem particularly when debugging issues in the style sheet.
Since the browser is referring to the generated CSS instead of the source file (LESS), we will likely be clueless of the exact lines where the style rules are actually declared in a source file. A source map addresses this issue by mapping the generated CSS back to the source files. In a browser that supports source map, you will find the browser refers directly to the source file. In the case of LESS, the browser will refer to the .less
style sheet as shown in the following screenshot:
In this project, we will generate a source map of the generated CSS. So, if we encounter bugs, it is a lot easier to address it. We can immediately figure out exactly where the style rules reside.
Note
Head over to the following references for further information about the source map:
- Working with CSS preprocessors by Google (https://developer.chrome.com/devtools/docs/css-preprocessors)
- An Introduction to Source Map (http://blog.teamtreehouse.com/introduction-source-maps)
- Using LESS Source Maps (http://roots.io/using-less-source-maps/)
More on LESS
LESS has plenty of features and will only grow with more additions in the years to come. It's impractical to include and discuss them all at once In this module. So, the following are a few references to dig in deeper:
- LESS's official website (http://lesscss.org/); the best source to be up-to-date with LESS
- LESS Web Development Essentials, Bass Jobsen, Packt Publishing (https://www.packtpub.com/web-development/less-web-development-essentials)
- Instant LESS CSS preprocessor (https://www.packtpub.com/web-development/instant-less-css-preprocessor-how-instant)
External style sheet references
We walked through a big amount of basic syntax in LESS in the preceding section. Now, we will start to actually work with LESS, speaking of which, before we are able to write our own style rules as well as reuse variables, mixins, and functions that are shipped in Bootstrap and the Jasny Bootstrap package, we will have to import them into our own style sheet with the LESS @import
directive.
Time for action – creating style sheets and organizing external style sheet references
Perform the following steps to manage the style sheet references:
- Go to the project directory and create a new style sheet named
var-bootstrap.less
inassets/less
directory. This style sheet contains the copy of Bootstrap's predefined variables. This copy will allow us to customize the variables without affecting the initial specifications. - Hence, copy the Bootstrap variables in the
variables.less
style sheet of the/bootstrap/less
directory. Paste the complete variables intovar-bootstrap.less
that we only created in step 1.Tip
For your convenience, you may also copy Bootstrap variables directly from the Github repository (http://git.io/7LmzGA).
- Create a new style sheet named
var-jasny.less
. Similar tovar-bootstrap.less
, this style sheet will contain the copy of the Jasny Bootstrap variables. - Obtain the Jasny Bootstrap variables in
variables.less
of thejasny-bootstrap/less
directory. Paste all the variables in thevar-jasny.less
style sheet we just created in step 3.Tip
Alternatively, copy the variables directly from the Jasny Bootstrap repository (http://git.io/SK1ccg).
- Create a new style sheet named
frameworks.less
. - We are going to use this style sheet to import the Bootstrap and Jasny Bootstrap style sheets residing in the
bower_component
folder. - In
frameworks.less
, create a variable named@path-bootstrap
to define the path, pointing to the folder namedless
, where all the LESS style sheets of Bootstrap reside:@path-bootstrap: '../../bower_components/bootstrap/less/';
- Similarly, create a variable that defines the path, pointing to the Jasny Bootstrap
less
folder, as follows:@path-jasny: '../../bower_components/jasny-bootstrap/less/';
- Also create one to define the Ionicons path:
@path-ionicons: '../../bower_components/ionicons-less/less/';
- Import the style sheets that contain variables using the following code:
@import 'var-bootstrap.less'; @import 'var-jasny.less';
- Import the Bootstrap and Jasny Bootstrap style sheets, which are only required to build the portfolio website. Specify the paths using the variables we created in steps 6 to 8, as follows:
// Mixins @import '@{path-bootstrap}mixins.less'; // Reset @import '@{path-bootstrap}normalize.less'; @import '@{path-bootstrap}print.less'; // Core CSS @import '@{path-bootstrap}scaffolding.less'; @import '@{path-bootstrap}type.less'; @import '@{path-bootstrap}grid.less'; @import '@{path-bootstrap}forms.less'; @import '@{path-bootstrap}buttons.less'; // Icons @import '@{path-ionicons}ionicons.less'; // Components @import '@{path-bootstrap}navs.less'; @import '@{path-bootstrap}navbar.less'; @import '@{path-bootstrap}jumbotron.less'; // Offcanvas @import "@{path-jasny}navmenu.less"; @import "@{path-jasny}offcanvas.less"; // Utility classes @import '@{path-bootstrap}utilities.less'; @import '@{path-bootstrap}responsive-utilities.less';
Tip
You can also copy the preceding code from Gist (http://git.io/WpBVAA).
Note
To minimize extraneous style rules, which really are not needed for the website, we excluded a number of Bootstrap and Jasny Bootstrap style sheets from
frameworks.less
as you can see previously. - Create a new style sheet named
style.less
. This is the style sheet where we are going to compose our very own style rules. - Import the Bootstrap variables and the mixins within
style.less
:@path-bootstrap: '../../bower_components/bootstrap/less/'; @import 'var-bootstrap.less'; @import 'var-jasny.less'; @import (reference) '@{path-bootstrap}mixins.less';
What just happened?
To sum up, we just created style sheets and put them in order. At first, we created two style sheets named var-bootstrap.less
and var-jasny.less
to store the Bootstrap and Jasny Bootstrap variables. As mentioned, we made these copies to avoid directly altering the originals. We have also created a style sheet named frameworks.less
, containing references to the Bootstrap and Jasny Bootstrap style sheets.
Finally, we created the website primary style sheet named style.less
and imported the variables and mixins so that they are reusable inside the style.less
.
Have a go hero – name and organize the style sheets
In the preceding steps, we organized and named the folders as well as the files to my personal preferences. Even so, you don't have to follow the naming conventions absolutely. Do organize and name them in your own way.
Note
The most important thing to note is that the @import
statement refers to the correct file name.
The following are a few ideas:
- Rename
var-bootstrap.less
to simplyvars.less
. - Alternatively, create a new folder name
vars
orconfigs
to put thevar-bootstrap.less
andvar-jasny.less
style sheet in it. - Did you know that you can also import the LESS style sheet without declaring the
.less
extension. For the sake of simplicity, you can omit the extensions, for example:@import (reference) '@{path-bootstrap}mixins.less';
Pop quiz – which of the following option is not LESS Import option?
Q1. In one of the section of this chapter, we discussed (reference)
, which imports yet treats external LESS style sheets only as a reference. In addition to (reference)
, LESS also provides more options to import a style sheet. So, which of the following is not the LESS import option?
(less)
(css)
(multiple)
(once)
(default)
Q2. How do you use variable within an @import
statement?
@import '@{variable}style.less';
@import '@[variable]style.less';
@import '@(variable)style.less';
var-bootstrap.less
and var-jasny.less
to store the Bootstrap and Jasny Bootstrap variables. As mentioned, we made these copies to avoid directly altering the originals. We have also created a style sheet named frameworks.less
, containing references to the Bootstrap and Jasny Bootstrap style sheets.
style.less
and imported the variables and mixins so that they are reusable inside the style.less
.
Have a go hero – name and organize the style sheets
In the preceding steps, we organized and named the folders as well as the files to my personal preferences. Even so, you don't have to follow the naming conventions absolutely. Do organize and name them in your own way.
Note
The most important thing to note is that the @import
statement refers to the correct file name.
The following are a few ideas:
- Rename
var-bootstrap.less
to simplyvars.less
. - Alternatively, create a new folder name
vars
orconfigs
to put thevar-bootstrap.less
andvar-jasny.less
style sheet in it. - Did you know that you can also import the LESS style sheet without declaring the
.less
extension. For the sake of simplicity, you can omit the extensions, for example:@import (reference) '@{path-bootstrap}mixins.less';
Pop quiz – which of the following option is not LESS Import option?
Q1. In one of the section of this chapter, we discussed (reference)
, which imports yet treats external LESS style sheets only as a reference. In addition to (reference)
, LESS also provides more options to import a style sheet. So, which of the following is not the LESS import option?
(less)
(css)
(multiple)
(once)
(default)
Q2. How do you use variable within an @import
statement?
@import '@{variable}style.less';
@import '@[variable]style.less';
@import '@(variable)style.less';
preceding steps, we organized and named the folders as well as the files to my personal preferences. Even so, you don't have to follow the naming conventions absolutely. Do organize and name them in your own way.
Note
The most important thing to note is that the @import
statement refers to the correct file name.
The following are a few ideas:
- Rename
var-bootstrap.less
to simplyvars.less
. - Alternatively, create a new folder name
vars
orconfigs
to put thevar-bootstrap.less
andvar-jasny.less
style sheet in it. - Did you know that you can also import the LESS style sheet without declaring the
.less
extension. For the sake of simplicity, you can omit the extensions, for example:@import (reference) '@{path-bootstrap}mixins.less';
Pop quiz – which of the following option is not LESS Import option?
Q1. In one of the section of this chapter, we discussed (reference)
, which imports yet treats external LESS style sheets only as a reference. In addition to (reference)
, LESS also provides more options to import a style sheet. So, which of the following is not the LESS import option?
(less)
(css)
(multiple)
(once)
(default)
Q2. How do you use variable within an @import
statement?
@import '@{variable}style.less';
@import '@[variable]style.less';
@import '@(variable)style.less';
(reference)
, which imports yet treats external LESS style sheets only as a reference. In addition to (reference)
, LESS also provides more options to import a style sheet. So, which of the following is not the LESS import option?
(less)
(css)
(multiple)
(once)
(default)
@import
statement?
@import '@{variable}style.less';
@import '@[variable]style.less';
@import '@(variable)style.less';
Working with Koala
The HTML and the style sheets have been prepared. It's now time to put them together to shape a solid portfolio website. We will compose the website styles using LESS syntax. Herein, we will also use Koala as in the first project. This time, we will compile LESS into plain CSS.
Time for action – compiling LESS into CSS using Koala
Perform the following steps to compile LESS into CSS using Koala:
- Add the project directory in the Koala sidebar, as follows:
- Select all the style sheets except
frameworks.less
andstyle.less
. Right-click and select Toggle Auto Compile. Have a look at the following screenshot:This will turn off the Auto Compile option on the selected style sheets and prevent Koala from compiling these style sheet unintentionally.
- On the other hand, ensure that Auto Compile is checked for the two remaining style sheets,
frameworks.less
andstyle.less
: - Make sure that the
frameworks.less
andstyle.less
output is set to/assets/css
directory, as shown in the following screenshot: - Check the Source Map option for both style sheets to generate the source map files, which will help us when debugging:
- Select the output styles for the two style sheets,
frameworks.less
andstyle.less
, to compress:This option will generate a small-sized CSS style sheet, as the codes within the style sheet will be compressed into a single line. Hence, the style sheet will load faster in the browser and also save bandwidth consumption on the user's side.
- Select
frameworks.less
and click on the Compile button to compile it into CSS: - Do the same for
style.less
. Select it and click on the Compile button to compile it into CSS. Openindex.html
in the code editor, and link both of the style sheets inside<head>
, as follows:<link href="assets/css/frameworks.css" rel="stylesheet"> <link href="assets/css/style.css" rel="stylesheet">
What just happened?
In the preceding steps, we compiled the website primary style sheets, frameworks.less
and style.less
, from LESS to CSS. You should now have them along with the source maps in the assets/css/
directory. The code is compressed, thus resulting in a relatively small file size, as shown in the following screenshot:
Additionally, we also linked these CSS style sheets in index.html
. However, since we have not yet written our own styles, the websites are decorated with the default Bootstrap styles, as shown in the following screenshot:
frameworks.less
and style.less
, from LESS to CSS. You should now have them along with the source maps in the assets/css/
directory. The code is compressed, thus resulting in a relatively small file size, as shown in the following screenshot:
also linked these CSS style sheets in index.html
. However, since we have not yet written our own styles, the websites are decorated with the default Bootstrap styles, as shown in the following screenshot:
Polishing the portfolio website with LESS
This is the section you might be waiting for, to style the portfolio website. It is apparently a pleasing experience to see the website start to have shapes, colors, and look. In this section, we will customize the default styles and compose our style rules using the LESS syntax that we have covered earlier in this chapter.
Time for action – composing the website styles with LESS syntax
Perform the following steps to style the website:
- Add a new font family from Google Font. Herein, I opted for Varela Round (http://www.google.com/fonts/specimen/Varela+Round). Place the following Google Font link before any other style sheets:
<link href='http://fonts.googleapis.com/css?family=Varela+Round' rel='stylesheet' type='text/css'>
- We will customize the default styles by changing some variables. Open
var-bootstrap.less
in Sublime Text. First, we change the@brand-primary
variable that defines the Bootstrap primary color; change it from#428bca
to#46acb8
: - Also, change the color in the
@brand-success
variable from#5cb85c
to#7ba47c
: - Change the
@headings-font-family
variable, which defines the font family used in the headings, frominherit
to"Varela Round"
, as follows:@headings-font-family: "Varela Round", @font-family-sans-serif;
- The Bootstrap default style shows a glowing effect when the user focusses on a form field. The color of this effect is specified in
@input-border-focus
. Change the color from#66afe9
to#89c6cb
: - In the top section of the website, you can see that the navbar still has the Bootstrap default style with the gray background and border color, as shown in the following screenshot:
- These two colors are specified in
@navbar-default-bg
and@navbar-default-border
, respectively. Change both of these variable values to transparent, as follows:@navbar-default-bg: transparent; @navbar-default-border: transparent;
- Similarly, the default style of the Jumbotron section is set with a gray background color. To remove this color, set the
@jumbotron-bg
variable totransparent
, as follows:@jumbotron-bg: transparent;
- We will be back editing a few more Bootstrap variables later on. For the meantime, let's write our own style rules. To begin with, we will show the navbar toggle button, which is hidden by the Bootstrap default styles. In our case, this button will be used to slide the off-canvas navigation on and off. Let's force this button to be visible with the following style rules:
.portfolio-topbar { .navbar-toggle { display: block; } }
- As you can see from the following screenshot, the toggle button with the so-called hamburger icon (http://gizmodo.com/who-designed-the-iconic-hamburger-icon-1555438787) is now visible:
- Currently, this button is positioned on the right-hand side. Referring to the website blueprint, it should be on the left. Add
float:left
to put it on the left-hand side andmargin-left:15px
to add a little whitespace to the button's left, as follows:.portfolio-topbar { .navbar-toggle { display: block; float: left; margin-left: 15px; } }
- Herein, I want to customize the toggle button's default styles, which are also specified through a couple of variables in
var-bootstrap.less
. Hence, openvar-bootstrap.less
in Sublime Text. - First of all, we will remove the button borders by changing the value of the
@navbar-default-toggle-border-color
variable from#ddd
totransparent
, as follows:@navbar-default-toggle-border-color: transparent;
- We will also remove the gray background color that appears when we hover over the button. Remove the gray background color out of it by changing the
@navbar-default-toggle-hover-bg
variable from#ddd
totransparent
, as follows:@navbar-default-toggle-hover-bg: transparent;
- I want the hamburger icon to look bolder and strong. So, herein, we want to change the colors to black. Change the value of
@navbar-default-toggle-icon-bar-bg
from#888
to#000
:@navbar-default-toggle-icon-bar-bg: #000;
- At this stage, the website content is aligned to the left-hand side, which is the default browser alignment for any content. Following the website blueprint, the website content should be centered. Use
text-align: center
, as follows, to align the content to the center:.portfolio-about, .portfolio-display, .portfolio-contact, .portfolio-footer { text-align: center; }
- Add the following to turn the website name to all-caps (all capital letters), making it bigger and bolder:
.portfolio-about { .portfolio-name { text-transform: uppercase; } }
- On the other hand, make the catchphrase line subtler by specifying the text color to gray light. Herein, we can simply use Bootstrap's predefined variable named
@gray-light
to apply the gray color, as follows:.portfolio-about { .portfolio-name { text-transform: uppercase; } .lead { color: @gray-light; } }
- In the portfolio section, specify the background color with gray light, which is lighter than the color in
@gray-lighter
variable. The addition of the background color aims to lay a bit of emphasis on the portfolio section. - In this project, we opt to use the LESS
darken()
function to slightly darken the white color, as follows:.portfolio-display { background-color: darken(#fff, 1%); }
Note
The background color may alternatively be achieved by lightening the black color by 99 percent using the LESS
lighten()
function asbackground-color: lighten(#000, 99%);
. - At this stage, if we take a look at the portfolio section, it seems there are merely little spaces at the top and the bottom, as pointed out in the following screenshot:
- Give the portfolio section more space to breathe at the top and bottom by adding
padding-top
andpadding-bottom
, as follows:.portfolio-display { background-color: darken(#fff, 1%); padding-top: 60px; padding-bottom: 60px; }
- To sum up, we added two headings in the website, including one in the portfolio section, to explicitly display the section name. These headings will share the same style rules. So, in that case, we better create a mixin that specifically defines the heading styles.
- Define the mixin as well as the CSS properties to apply the heading styles, as follows:
.heading { color: lighten(#000, 70%); text-transform: uppercase; font-size: 21px; margin-bottom: 60px; }
- Add the following style rules for the section heading, which will make it look subtler and in tune with the background color of the portfolio section:
.portfolio-display { ... h2 { &:extend(.heading); } }
- As shown in the following screenshot, there is only very little space in between each row; the rows are too close to each other, as follows:
So, put more space by specifying
margin-bottom
for each portfolio item, as follows:.portfolio-item { margin-bottom: 30px; }
- Add styles for the portfolio image, as follows:
.portfolio-image { padding: 15px; background-color: #fff; margin-right: auto; margin-left: auto; }
- Also, add the styles for the caption, as follows:
.portfolio-caption { font-weight: 500; margin-top: 15px; color: @gray; }
- What do you think about showing a transition effect when we hover over the portfolio image? That will look nice, won't it? In this case, I would like to show a shadow surrounding the portfolio image upon hover.
- Add the effect using Bootstrap's predefined mixins,
.transition()
and.box-shadow()
, as follows:.portfolio-image { padding: 15px; background-color: #fff; margin-right: auto; margin-left: auto; .transition(box-shadow 1s); &:hover { .box-shadow(0 0 8px fade(#000, 10%)); } }
- Below the portfolio section, we have the website contact form, which has already been applied with the Bootstrap default styling. So, let's customize it with our own style rules.
- First, we will add more spaces at the top and the bottom of the contact form section with
padding
. - Add the styles for the heading with the
.heading
mixin we created in step 18:.portfolio-contact { ... h2 { &:extend(.heading); } }
- The form currently spans the container fully. So, add the following style rules to set the maximum width, yet still display the form in the middle of the container, as follows:
.portfolio-contact { ... .form { width: 100%; max-width: 600px; margin-right: auto; margin-left: auto; } }
- Add the following style rules to make the form elements—
<input>
,<textarea>
,<button>
—look flatter. These style rules remove the shadow and lower the border radius. Have a look at the following code:.portfolio-contact { ... .form { width: 100%; max-width: 600px; margin-right: auto; margin-left: auto; input, textarea, button { box-shadow: none; border-radius: @border-radius-small; } } }
- Add the following lines to style the button and make it live with a transition effect, as follows:
.portfolio-contact { ... .form { width: 100%; max-width: 600px; margin-right: auto; margin-left: auto; input, textarea, button { box-shadow: none; border-radius: @border-radius-small; } .btn { display: block; width: 100%; .transition(background-color 500ms); } } }
- Starting this step, we will add style rules for the footer, the last section of the website. The footer contains the social media links, Dribbble and Twitter, and a copyright statement at the very bottom.
- First, as in the preceding sections, we put more whitespace at the top and bottom of the section with padding:
.portfolio-footer { padding-top: 60px; padding-bottom: 60px; }
- Then, we put more spaces between the social media links and the copyright statement with
margin-bottom
:.portfolio-footer { padding-top: 60px; padding-bottom: 60px; .social { margin-bottom: 30px; } }
- Add the following lines to remove the
<ul>
elementpadding
derived from default browser styles:.portfolio-footer { ... .social { margin-bottom: 30px; ul { padding-left: 0; } } }
- Add the highlighted lines in the following code to display the social media links beside each other:
.portfolio-footer { ... .social { margin-bottom: 30px; ul { padding-left: 0; } li { list-style: none; display: inline-block; margin: 0 15px; } } }
- Give the social media links the color of their respective social media brands, as follows:
.portfolio-footer { ... .social { ... a { font-weight: 600; color: @gray; text-decoration: none; .transition(color 500ms); &:before { display: block; font-size: 32px; margin-bottom: 5px; } } .twitter a:hover { color: #55acee; } .dribbble a:hover { color: #ea4c89; } } }
Tip
Get more colors of popular websites in BrandColors (http://brandcolors.net/).
- Finally, make the copyright statement color subtler with the gray color:
.portfolio-footer { ... .copyright { color: @gray-light; } }
What just happened?
In the preceding steps, we just styled the website by customizing a number of Bootstrap variables as well as composing our own style rules. Compile style.less
to generate the CSS. Additionally, you can obtain all the style rules we applied from this Gist (http://git.io/-FWuiQ).
The website should now be presentable. The following screenshot shows how the website looks in the desktop view:
The website is also responsive; the layout will adapt to the viewport width size, as shown in the following screenshot:
Have a go hero – being more creative
Many of the style rules that we have just applied in the preceding section are merely decorative. Feel free to add more creativity and customization, as follows:
- Explore the website's new color schemes. Use handy tools, such as Kuler, (https://kuler.adobe.com/) to generate color scheme
- Apply different font families
- Present more awesome transition effects with CSS3
Pop quiz — using LESS function and extend syntax
Q1. How do you make a color lighter with LESS?
lighter(#000, 30%);
lighten(#000, 30%);
lightening(#000, 30%);
Q2. How do you make a color transparent?
fadeout(#000, 10%);
transparentize(#000, 10%);
fade-out(#000, 10%);
Q3. Which one of the following is an incorrect way to extend a mixin in LESS?
.class:extend(.another-class);
.class::extend(.another-class);
.class {
:extend(.another-class);
}
style.less
to generate the CSS. Additionally, you can obtain all the style rules we applied from this Gist (
The website should now be presentable. The following screenshot shows how the website looks in the desktop view:
The website is also responsive; the layout will adapt to the viewport width size, as shown in the following screenshot:
Have a go hero – being more creative
Many of the style rules that we have just applied in the preceding section are merely decorative. Feel free to add more creativity and customization, as follows:
- Explore the website's new color schemes. Use handy tools, such as Kuler, (https://kuler.adobe.com/) to generate color scheme
- Apply different font families
- Present more awesome transition effects with CSS3
Pop quiz — using LESS function and extend syntax
Q1. How do you make a color lighter with LESS?
lighter(#000, 30%);
lighten(#000, 30%);
lightening(#000, 30%);
Q2. How do you make a color transparent?
fadeout(#000, 10%);
transparentize(#000, 10%);
fade-out(#000, 10%);
Q3. Which one of the following is an incorrect way to extend a mixin in LESS?
.class:extend(.another-class);
.class::extend(.another-class);
.class {
:extend(.another-class);
}
- the website's new color schemes. Use handy tools, such as Kuler, (https://kuler.adobe.com/) to generate color scheme
- Apply different font families
- Present more awesome transition effects with CSS3
Pop quiz — using LESS function and extend syntax
Q1. How do you make a color lighter with LESS?
lighter(#000, 30%);
lighten(#000, 30%);
lightening(#000, 30%);
Q2. How do you make a color transparent?
fadeout(#000, 10%);
transparentize(#000, 10%);
fade-out(#000, 10%);
Q3. Which one of the following is an incorrect way to extend a mixin in LESS?
.class:extend(.another-class);
.class::extend(.another-class);
.class {
:extend(.another-class);
}
lighter(#000, 30%);
lighten(#000, 30%);
lightening(#000, 30%);
fadeout(#000, 10%);
transparentize(#000, 10%);
fade-out(#000, 10%);
.class:extend(.another-class);
.class::extend(.another-class);
.class {
:extend(.another-class);
}
Improve and make the website functioning with JavaScript
The off-canvas navigation has not yet been activated. If you click on the toggle button, the off-canvas navigation will not slide in. Furthermore, if you view the portfolio website in Internet Explorer 8, you will find that a number of style rules are not applied. This is because Internet Explorer 8 does not recognize the HTML5 elements that are used in the website. To sort these issues out, we will have to make use of some JavaScript libraries..
Time for action – compiling JavaScript with Koala
- Create a new JavaScript file named
html5shiv.js
inassets/js
directory. - Import
html5shiv.js
from the HTML5Shiv package we downloaded through Bower into this file:// @koala-prepend "../../bower_components/html5shiv/dist/html5shiv.js"
- Create a new JavaScript file named
bootstrap.js
. - In
bootstrap.js
, import the JavaScript libraries that are required to turn the off-canvas navigation functionality on, as follows:// @koala-prepend "../../bower_components/jquery/dist/jquery.js" // @koala-prepend "../../bower_components/bootstrap/js/transition.js" // @koala-prepend "../../bower_components/jasny-bootstrap/js/offcanvas.js"
- Open Koala and ensure that the Auto Compile option for
html5shiv.js
andbootstrap.js
is checked, as shown in the following screenshot: - Also, make sure that the output path of these two JavaScript files is set to the
/assets/js
directory, as shown in the following screenshot: - Compile both these JavaScript files by clicking on the Compile button in Koala, as follows:
Once these JavaScript files are compiled, you should find the minified version of these files,
html5shiv.min.js
andbootstrap.min.js
, as shown in the following screenshot: - Open
index.html
in Sublime Text, and linkhtml5shiv.js
within the<head>
section using the Internet Explorer conditional comment tag, as follows:<!--[if lt IE 9]> <script type="text/javascript" src="assets/js/html5shiv.min.js"></script> <![endif]-->
- Link
bootstrap.min.js
at the bottom ofindex.html
, as follows:<script type="text/javascript" src="assets/js/bootstrap.min.js"></script>
What just happened?
We just compiled jQuery and Bootstrap JavaScript libraries to enable the off-canvas functionality. We also enabled HTML5 elements in Internet Explorer 8 using HTML5Shiv. By now, the website is fully functional.
Tip
You can view the website through this Github page (http://tfirdaus.github.io/rwd-portfolio/).
You should be able to slide in and out the off-canvas navigation, and the styles should now be visible in Internet Explorer 8. Take a look at the following screenshot:
Tip
You can view the website through this Github page (http://tfirdaus.github.io/rwd-portfolio/).
You should be able to slide in and out the off-canvas navigation, and the styles should now be visible in Internet Explorer 8. Take a look at the following screenshot:
Summary
We just accomplished the second project of this module. In this project, we built a portfolio website using Bootstrap. Bootstrap makes it easy and quick to build a responsive website along with the website components using the drop-in classes provided.
At the top of that, we also used a Bootstrap extension called Jasny Bootstrap to include off-canvas navigation, which is one of the missing popular responsive design patterns in the original Bootstrap. When it comes styling the website, we used LESS, a CSS preprocessor that allows us to write the style rules more efficiently.
To sum up, we did many things in this project to get the website up and running. I hope you've learned many things along the way.
In the next chapter, we will start off the third project of this module using the Foundation framework. Stay tuned!