Less Web Development Essentials - Second Edition - Sample Chapter
Less Web Development Essentials - Second Edition - Sample Chapter
ee
Sa
pl
Your clients will be happy with your advanced and stable designs.
Development and maintenance time, along with expenditure, will decrease.
Also, other projects know the power of Less. Projects such as Twitter Bootstrap
and the WordPress Roots theme rely on Less. These projects build clear and
extendable frameworks with Less.
Less is open source and licensed under Apache License. The source code
of Less is maintained on GitHub. Everybody will be allowed to contribute
to it. You can use Less free of charge.
Improving Web
Development with Less
It is impossible to imagine modern web design without CSS. With CSS3, web
designers are able to rely on advanced functions such as gradients, transitions, and
animations. On the other hand, with these, the CSS code becomes more complex
and difficult to maintain. Less is a CSS preprocessor that extends CSS with modern
programming-language concepts. It enables you to use variables, functions,
operations, and nesting (rule or selector) while coding your CSS. It also helps you
write CSS with the don't repeat yourself (DRY) principle. The DRY principle
prevents you from repeating any kind of information in your code.
This chapter will cover the following topics:
Introduction to CSS3
Vendor-specific rules
[1]
Chapter 1
Such selectors add powerful functions to CSS3. Nowadays, we are able to perform
operations with CSS alone. However, in the past, we needed JavaScript or hardcoded
styles (or classes at the very least). Less helps you organize and maintain these new
selectors well and this is one of the reasons to learn it. Powerful selectors make
CSS more important, but the CSS code also becomes cumbersome and difficult to
maintain. Less will prevent this problem in CSS, even making complex code flexible
and easy to maintain.
Visit http://www.w3.org/TR/selectors/#selectors for a
complete list of the CSS selectors.
Find all the CSS declarations that apply to the element and property in
question
Note that browsers such as Firefox have options to disable pages in order to
use other alternatives to user-defined fonts. Here, the user settings overrule
CSS of the web page. This way of overruling the page settings is not part of
the CSS precedence unless they are set using !important.
If two or more rules have the same precedence and specificity, the one
declared last wins.
As a Less/CSS designer, you will be making use of the calculated CSS specificity in
most cases.
After this, the number of IDs in the selector will be the next indicator to calculate
specificity. The #footer #leftcolumn {} selector has two IDs, the #footer {}
selector has one ID, and so on.
Note that in this case, an ID is a unique selector starting with #. The
[id=] selector for the same HTML element counts as an attribute. This
means that div#unique {} has one ID and div[id="unique"] {}
has zero IDs and one attribute.
If the number of IDs for two declarations is equal, the number of classes, pseudo
classes, and attributes of the selector will be of importance. Classes start with a dot.
For example, .row is a class. Pseudo classes, such as :hover and :after, start with a
colon, and attributes, of course, are href, alt, id, and so on.
The #footer a.alert:hover {} selector scores two (one class and one pseudo
class) and the #footer div.right a.alert:hover {} selector scores three (two
classes and one pseudo class).
[4]
Chapter 1
If this value is equal for both declarations, we can start counting the elements and
pseudo elements. The pseudo elements are defined with a double colon (::) and
allow authors to refer to otherwise inaccessible information, such as ::firstletter. The following example shows you how this works.
The #footer div a{} selector scores two (two elements) and the #footer div p a
{} selector scores three (three elements).
You should now know what to do when your style isn't directly applied. In most
cases, make your selector more specific to get your style applied. For instance, if
#header p{} doesn't work, you can try adding a #header #subheader p{} ID, a
#header p.head{} class, and so on.
When the cascade and !important rules do not give a conclusive answer, specificity
calculation seems to be a difficult and time-consuming job. Although Less won't help
you here, tools such as Firebug (and other developer tools) can make the specificity
visible. An example using Firebug is shown in the following screenshot, where the
selector with the highest specificity is displayed at the top of the screen and the
overruled styles are struck out:
[5]
The preceding example uses the .flex-display (); mixin to set the vendor prefixes
for the flex value of the display property. In the Vendor-specific rules section, you
will learn more about vendor prefixes and the Less autoprefix plugin. The Less
autoprefix plugin makes it unnecessary to use vendor prefixes in your Less code.
You can find the Less autoprefix plugin at https://github.com/less/lessplugin-autoprefix. Also, the .flex-display(); mixin becomes unnecessary.
Some ancient browsers use an older syntax for the flexbox layout, autoprefixing does
not fix old syntaxes and polyfills.
The flexbox grid is a grid system based on the flex display property. This grid
system can be used with the Bootstrap grid as a fall back for older browsers. The Less
code to build the flexbox grid can be found at https://github.com/bassjobsen/
flexboxgrid and the official website of the flexbox grid is http://flexboxgrid.
com/.
[6]
Chapter 1
Flexboxes have been mentioned because they have the potential to play an important
role in the future of web design. In Chapter 5, Integrating Less in Your Own Projects,
you can read about the flexboxgrid.com and flexible.gs grid systems, which are
built with flexboxes. However, this book will mainly focus on creating responsive
and flexible layouts with Less using the CSS media queries and the float property.
Visit https://developer.mozilla.org/en-US/docs/Web/
Guide/CSS/Flexible_boxes for additional information, examples,
and browser compatibility.
Compiling Less
After delving into the theory of CSS, you can finally start using Less. As mentioned
earlier, the syntax of Less is very similar to the syntax of CSS. More precisely, Less
extends the CSS syntax. This means that any valid CSS code is, in fact, a valid Less code
too. With Less, you can produce the CSS code that can be used to style your website.
The process used to make CSS from Less is called compiling, where you can compile
the Less code via server side or client side. The examples given in this book will make
use of client-side compiling. Client side, in this context, means loading a Less file in the
browser and using JavaScript on the client machine to compile and apply the resulting
CSS. Client-side compiling is used in this book because it is the easiest way to get
started, while still being good enough for developing your Less skills.
It is important to note that the results from client-side compiling serve
only demonstration purposes. For production, and especially when
considering the performance of an application, it is recommended that
you use server-side precompiling. Less bundles a compiler based on
Node.js, and many other GUIs are available to precompile your code.
These GUIs will be discussed toward the end of this chapter.
the latest version from a content delivery network (CDN). Flexboxes have been
mentioned because they have the potential to play an important role in the future of
web design. For now, they are beyond the scope of this book. This book will focus on
creating responsive and flexible layouts with Less using CSS media queries and grids.
[7]
Replace 2.x.x in the preceding code with the latest version available.
Note that you can download the examples from the support files for this chapter in
the downloadable files for the book at www.packtpub.com.
Downloading the example code
You can download the example code files for all Packt Publishing books
you have purchased from your account at http://www.packtpub.
com/. If you purchased this book elsewhere, you can visit http://
www.packtpub.com/support/ and register to have the files e-mailed
directly to you.
To start with, have a look at this plain yet well-structured HTML5 file:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example code</title>
<meta name="description" content="Example code">
<meta name="author" content="Bass Jobsen">
<link rel="stylesheet/less" type="text/css"
href="less/styles.less" />
<script
src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.2.0/
less.min.js"></script>
</head>
<body>
<h1>Less makes me Happy!</h1>
</body>
</html>
[8]
Chapter 1
As you can see, a Less file has been added to this document by using the
following code:
<link rel="stylesheet/less" type="text/css"
href="less/styles.less" />
When rel="stylesheet/less" is used, the code will be the same as for a style
sheet. After the Less file, you can call less.js by using the following code:
<script
src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.2.0/
less.min.js"></script>
Or alternatively, load a local file with a code that looks like the following:
<script src="js/less.js" type="text/javascript"></script>
Now open http://localhost/index.html in your browser. You will see the Less
makes me happy! header text in its default font and color.
It is not necessary to have a local web server running. Navigating to
the index.html file on your hard drive with your browser should be
enough. Or double click on the index.html file to open it in your default
browser. Unfortunately, this won't work for all browsers, so use Mozilla
Firefox in order to be sure. The examples in this book use http://
localhost/map/, but this can be replaced with something similar to
file:///map/ or c:\map\, depending on your situation. Note that
you cannot run less.js from CDN when using the file:// protocol in
Google Chrome. You can not use the less.js compiler from CDN. You
should replace it with a local version.
[9]
After this, you should open less/styles.less in your favorite text editor. The
syntax of Less and CSS doesn't differ here, so you can enter the following code into
this file:
h1{color:red;}
Following this, reload your browser. You will see the header text in red.
From the preceding code, h1 is the selector that selects the HTML H1 attribute in
your HTML. The color property has been set to red between the accolades. The
properties will then be applied onto your selectors, just like CSS does.
[ 10 ]
Chapter 1
As you can see, the line with var less = { env: 'development' }; is new here.
This line contains less as a JavaScript variable used by less.js. In fact, this is a
global Less object used to parse some settings to less.js. The only setting that
will be used in this book is env: 'development'. For more settings, you can check
http://lesscss.org/#client-side-usage-browser-options.
The env: 'development' line also prevents Less from caching. Less
doesn't cache files in the browser cache. Instead, files are cached in the
browser's local storage. If env is set to production, this caching could
yield unexpected results as the changed and saved files are not compiled.
Since Version 2 of Less, options can also be specified on the script tag, as shown in
the following code:
<script src="less.js" data-env="development"></script>
Alternatively, you can use the link tag that refers to your source file, as follows:
<link data-env="development"' rel="stylesheet/less"
type="text/css" href="less/styles.less">
To try this new setting, edit less/styles.less again and remove an accolade curly
bracket to create an invalid syntax of the h1{color:red form, and then save the file.
[ 11 ]
In your browser, you will see a page like the following screenshot:
Besides syntax errors, there will also be name errors displayed. In the case of a name
error, an undeclared function or variable would have been used.
It is possible to set other settings for debugging, either in the global Less object
or by appending the setting to the URL. For example, you can specify the
dumpLineNumbers setting by adding the following lines of code to your HTML file:
<script type="text/javascript">less = { env:
'development',dumpLineNumbers: "mediaQuery"
};</script>
Alternatively, you can add !dumpLineNumbers:mediaQuery to the URL. You can, for
instance, open http://localhost/index.html#!dumpLineNumbers:mediaQuery
in your browser to enable the setting. This setting enables other tools to find the line
number of the error in the Less source file. Setting this option to mediaQuery makes
error reporting available for the Firebug or Chrome development tools.
Similarly, setting this to comments achieves the same for tools such as FireLESS.
For instance, using FireLESS allows Firebug to display the original Less filename
and the line number of CSS styles generated by Less. Older and experimental
versions of Chrome did support this mediaQuery format. Currently, most browsers
offer support for the CSS source maps, as described in the next section, in favor of
other source mapping formats. The current version of Less does not support CSS
sourcemap for in-browser usage. When developing in browser with the less.js
compiler, you can use the FireLESS add-on for Firefox.
[ 12 ]
Chapter 1
Plugins
Plugins have been used since Version 2 of Less. They can be used with both the
client-side and the server-side compiler. The current list of plugins can be found at
http://lesscss.org/usage/#plugins-list-of-less-plugins. Writing a plugin
yourself is not that difficult, but beyond the scope of this book. You can be sure that
the list of useful plugins will grow over time. Less plugins described in this book
only work in a node.js application (including Grunt and Gulp) and sometimes also
for in browser usage.
The Less plugins can be grouped into the following four or five types:
The first type, the so-called visitors, enable you to change the compile
process. The inline URLs plugin converting url() to a call to data-uri() is
an example of a visitor plugin.
[ 13 ]
The second type are file manager plugins, which help you to set the
files that should be compiled. Examples of file manager plugins are the npm
import (https://github.com/less/less-plugin-npm-import) and bower
resolve (https://github.com/Mercateo/less-plugin-bower-resolve)
plugins.
The post-process plugins form the third type. The autoprefix (https://
github.com/less/less-plugin-autoprefix) and clean-css (https://
github.com/less/less-plugin-clean-css) plugins are examples. They
are able to change and modify the already compiled CSS code.
The fourth type are the pre-process plugins. Pre-process plugins can
automatically add the Less code before your custom code. You can use this
type of plugin to load a complete library before your custom code. The
Bootstrap plugin loads Bootstrap's Less code. You can find the Bootstrap
plugin at https://github.com/bassjobsen/less-plugin-bootstrap.
Finally, plugins can also be used to extend Less with your own custom
functions. Plugins that extend Less with custom functions can be grouped
in the fifth type, although these plugins, just like the visitor plugins, change
the compile process. An example of a plugin, which extends Less with
some custom functions, can be found at https://github.com/less/lessplugin-advanced-color-functions.
To use a plugin with Less in browser, you should first include the plugin source,
and then set the plugin option of the less.js compiler. Your code will look like that
shown in the following code snippet:
<script src="plugin.js"></script>
<script>
var less = {
env: "development",
plugins: [Plugin]
};
</script>
<script
src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.2.0/
less.min.js"></script>
In this book, you will find many code examples. Unless explicitly mentioned, the
format of these examples always shows the Less code first, followed by the compiled
CSS code. For instance, you can write the following lines of code in Less:
mixin() {
color: green;
}
[ 14 ]
Chapter 1
p {
.mixin();
}
[ 15 ]
Vendor-specific rules
CSS3 introduced vendor-specific rules, which offer you the possibility of writing
some additional CSS applicable for only one browser. At first sight, this seems
the exact opposite of what you want. What you want is a set of standards and
practicalities that work the same with every browser, and a standard set of HTML
and CSS that has the same effect and interpretation for every browser. Actually,
these vendor-specific rules are intended to help us reach this utopia. Vendorspecific rules also provide us with early implementations of standard properties
and alternative syntax. Last but not least, these rules allow browsers to implement
proprietary CSS properties that would otherwise have no working standard (and
may never actually become the standard).
For these reasons, vendor-specific rules play an important role in many new features
of CSS3. For example, animation properties, border-radius, and box-shadow,
depend on vendor-specific rules. You can easily see that some properties may evolve
from vendor prefixes to standard. Currently, most browsers support the borderradius and box-shadow properties without any prefix.
Vendors use the following prefixes:
WebKit: -webkit
Firefox: -moz
Opera: -o
Autoprefixing
Vendor prefixes make writing the CSS code, and therefore the Less code, more
complex. Also, you will have to change your code when your requirements change.
In this book, you will find the code examples that use mixins for prefixing your
CSS properties. Autoprefixing your code will be a better practice in many cases
by consensus of the community. Examples of mixins used for prefixing can help
you understand why mixins are easier to maintain and how they prevent code
duplication. Even when you autoprefix your code, you will need mixins for nonstandard code.
To autoprefix your code, you can use the Less autoprefix plugins. Note that you
can read more about plugins in general in the Server-side compiling section.
[ 16 ]
Chapter 1
With the autoprefix plugin, you can compile the following Less code:
#grad {
background: linear-gradient(red, blue);
}
The preceding Less code compiles into the following CSS code:
#grad {
background: -webkit-gradient(linear, left top, left bottom,
from(red), to(blue));
background: -webkit-linear-gradient(red, blue);
background: -moz-linear-gradient(red, blue);
background: -o-linear-gradient(red, blue);
background: linear-gradient(red, blue);
}
The autoprefix plugin has got a browser's option. This option enables you
to specify your target browsers. The Less autoprefix plugin is based on the
autoprefixer plugin for PostCSS and gets its information about the browsers'
features and usage statics from the Can I use (http://caniuse.com/) database.
You can find the documentation for the Less plugin at https://github.com/less/
less-plugin-autoprefix. The documentation of the Less plugin also refers to the
PostCSS autoprefixer documentation to show you how to set your target browsers.
The PostCSS autoprefixer, including documentation, can be found at https://
github.com/postcss/autoprefixer.
Note that the autoprefixer only adds prefixes; adding polyfill or other alternative
syntaxes is beyond the scope of the autoprefixer. Later on in this chapter, we will
discuss how to create a background gradient. The background gradient code has an
alternative fallback syntax for Internet Explorer 7 and 8. The autoprefixer does not
add this alternative syntax to your CSS code.
In many situations, you can also consider a strategy of graceful degradation for older
syntaxes. Graceful degradation means that you only add more user experience for
modern browsers, without breaking the functionality of your design. One of the
advantages of a graceful degradation strategy is that you do not have to try to run
complex code on old and slow hardware, which can slow down your website. You
can read more about graceful degradation at http://www.w3.org/wiki/Graceful_
degradation_versus_progressive_enhancement.
[ 17 ]
For rounded corners with different radii, use a list with values separated by spaces:
10px 5px 20px 15px;. The radii are given in the following order: top-left, top-right,
bottom-right, and bottom-left. By keeping these rules in mind, you will see how Less
can keep your code clean.
[ 18 ]
Chapter 1
You can see that the corners have been created with a radius of 10 pixels, set by
the border-radius property, and the border itself has been set with the border
property. If you were using CSS, you would have to repeat these properties three
times for the header, footer, and body. In order to change these rules or add a
vendor, you would also have to change the same code three times. To begin with,
you might perhaps think, "Why not group the selectors?" in a fashion similar to the
following code:
#header, #content, #footer{
border-radius: 10px;
border: 5px solid darkblue;-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
The preceding code is syntactically correct in order to write the CSS or Less code.
However, as your code base grows, it won't be easy to maintain. Grouping selectors
based on properties makes no sense when reading and maintaining your code.
Moreover, such constructs will also introduce many duplicated and unstructured
usages of the same selectors.
With Less, you are able to solve these problems efficiently. By creating a so-called
mixin, you can solve the issues mentioned earlier. For the border radius, you can use
the following code:
.bordered(@radius; @border-color) {
border-radius: @radius;
border: 5px solid @border-color;
}
[ 19 ]
To use the mixin mentioned in the preceding code, you should call it as a property
for the selector, using the following code:
#header{
background-color: red;
bordered(10px, darkblue);
}
Looking at the original code in the less/bordered.less file, you can see that the
preceding code wouldn't be able to work for #content. The border radius for the
content is 20 pixels instead of 10 pixels, as used for header and footer. Again, Less
helps you solve this problem efficiently. Mixins can be called with parameters in the
same way as functions can be called in functional programming. This means that in
combination with a value and a reference for this value, mixins can be called in order
to set the properties. In the following example, this will change to the following code:
.bordered(@radius: 10px; @border-color: darkblue) {
border-radius: @radius;
border: 5px solid @border-color;
}
[ 20 ]
Chapter 1
After rewriting your Less code, reload your browser or watch it if you have applied
the #!watch trick. You will see that the output will be exactly the same. This shows
you how to get the same results with Less, using a more efficiently structured code.
[ 21 ]
The preceding code will result into an example of a simple layout with borders and
rounded corners. The final result should look like the following screenshot:
Chapter 1
To use a CSS reset, you can make use of the @import directive of Less. With @import,
you can include the other Less files in your main Less file. The syntax is @import
"{filename}";. By default, the search path for the directives starts at the directory
of the main file. Although setting alternative search paths is possible (by setting the
path's variable of your Less environment), it will not be used in this book.
The examples of Less files in this book contain @import "normalize.less";
in the first few lines of the code. Again, you should note that normalize.less
does contain the CSS code. You should pay particular attention to the profits of
this solution!
If you want to change or update the CSS reset, you will only have to replace one file.
If you have to manage or build more than one project, which most of you may be
doing, then you can simply reuse the complete reset code.
A gradient example
In the next example, you can use a linear gradient of two colors. The background
gradients use vendor-specific rules.
You can use the example code from the rounded corners example to add gradients
to it.
The first step is to copy or open less/gradient.less and add a new mixin at the
start of this file, as shown in the following code:
/* Mixin */
.gradient (@start: black, @stop: white,@origin: left) {
background-color: @start;
[ 23 ]
-webkit-linear-gradient(@origin, @start,
-moz-linear-gradient(@origin, @start, @stop);
-o-linear-gradient(@origin, @start, @stop);
-ms-linear-gradient(@origin, @start, @stop);
linear-gradient(@origin, @start, @stop);
This will create gradients going from left (@origin) to right with colors from @start
to @stop. This mixin has default values.
IE9 (and its earlier versions) do not support gradients. A fallback can be added
by adding background-color: @start;, which will create a uniform colored
background for older browsers.
After adding the mixin to your code, you can call on it for our #header, #body, and
#footer selectors, as shown in the following code:
#header{
background-color: red;
.roundedcornersmixin();
.gradient(red,lightred);
}
#content{
background-color: white;
min-height: 300px;
.roundedcornersmixin(20px);
.gradient();
}
#footer{
background-color: navy;
.roundedcornersmixin(20px);
.gradient(navy,lightblue);
}
For example, if you renamed the Less file to less/gradient.less, you would also
have had to change the reference in your HTML file to the following code:
<link rel="stylesheet/less" type="text/css"
href="less/gradient.less" />
[ 24 ]
Chapter 1
If you now load the HTML file in the browser, your results should be like the
following screenshot:
Gradients in the header, content, and footer from the example code
[ 25 ]
To make things clear, it is important to keep in mind the button that is about to
be pressed. The button will have two states: pressed and not pressed. Without
transitions and animations, we are only able to style these states. The color of the
button is white, but it becomes red when you hover the mouse over it. (In the CSS
terms, its state becomes hovered by adding the :hover pseudo class.) In this case, the
transition describes how the hovered button becomes red. For example, the change in
color from white to red in two seconds (which makes it pink halfway) shows that the
start of the color change is slow and changes faster as time passes. Using animations
here enables us to describe the state of the button for every time interval between the
start (not hovered) and end (hovered).
Transformations change the position of an element and how it looks. They do not
depend on the state of the element. Some of the possible transformations are scaling,
translating (moving), and rotating.
In practice, we use a combination of animations, transformations, and/or
transitions in most situations. Also, in these cases, vendor-specific rules will play
an important role.
Now a transformation will be added to our example.
Using the example code with rounded corners and gradients, copy the following
code to less/transition.less or open less/transition.less, and add the
following code to the beginning of the file:
/* Mixin */
.transition (@prop: all, @time: 1s, @ease: linear) {
-webkit-transition: @prop @time @ease;
-moz-transition: @prop @time @ease;
-o-transition: @prop @time @ease;
-ms-transition: @prop @time @ease;
transition: @prop @time @ease;
}
This mixin example has three variables; the first is the property (@prop), which you
will change. This can be height, background-color, visibility, and so on. The
default value all shouldn't be used in the production code as this will have a negative
effect on performance. The @time variable sets the duration in milliseconds or seconds
with ms or s respectively appended to it. The last variable, @ease, sets the transitiontiming-function property. This function describes the value of a property, given that a
certain percentage of it has been completed. The transition-timing-function property
describes the completeness of the transition as a function of time. Setting it to linear
shows the effect with the same speed from start to end, while ease starts slow and
ends slow, having a higher speed in the middle. The predefined functions are ease,
linear, ease-in, ease-out, ease-in-out, step-start, and step-end.
[ 26 ]
Chapter 1
Note that these mixins will not be needed when you compile
your code with the Less autoprefix plugin. Similarly, the
.roundedcornersmixin(); mixin will not be needed and can be
replaced with the border-radius property.
Now, you can edit less/transition.less to use this mixin. You can set the
background color of the body when you hover over it. Note that you don't need to
use the transition to change the gradient color but to rather change the backgroundcolor attribute. You are using background-color because transition-duration
doesn't have a visible effect on the gradient. The code of the background-color
transition is as follows:
#content{
background-color: white;
min-height: 300px;
.roundedcornersmixin(20px);
.transition(background-color,5s);
}
#content:hover{
background-color: red;
}
If you renamed the Less file, for example, to less/transition.less, you would
also have to change the reference in your HTML file to the following code:
<link rel="stylesheet/less" type="text/css"
href="less/transition.less" />
If you load the HTML file in the browser, you will be able to see the results there.
Move your mouse over the content and see it change from white to red in five seconds.
Finally, a second example, that rotates the header, can be added. In this example, you
will use @keyframes. Using @keyframes will be complex. So, in this case, you can
define some vendor-specific rules and add these animation properties to #header:
as follows:
@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
@-webkit-keyframes spin { 100% { -webkit-transform:
rotate(360deg); } }
@keyframes spin { 100% { -webkit-transform: rotate(360deg);
transform:rotate(360deg); } }
#header{
-webkit-animation:spin 4s linear infinite;
-moz-animation:spin 4s linear infinite;
animation:spin 4s linear infinite;
}
[ 27 ]
You can add the preceding code to our example files or open less/keyframes.less.
If you renamed the Less file, for example, to less/keyframes.less, you also have to
change the reference in your HTML file to the following code:
<link rel="stylesheet/less" type="text/css"
href="less/keyframes.less" />
Now, load the HTML file in the browser and watch your results. Amazing, isn't
it? With a little bit of creative thinking, you will see the possibilities of creating a
rotating windmill or a winking owl using only CSS3. However, the first thing that
should be done is to explain the code used here in more detail. As mentioned earlier,
there are many cases in which you would make combinations of animations and
transformations. In this example, you also get to animate a transformation effect. To
understand what is going on, we will split the code into three parts.
The first part is @keyframes, shown in the following code, which describes the value
of the CSS properties (transformation in this case) as a function of the percentage of
the animation completeness:
@keyframes spin { 100% { -webkit-transform: rotate(360deg);
transform:rotate(360deg); } }
The third part is the animation itself, described by the animation, my-spin-effect,
which is 4s, linear, and infinite. This is the shorthand notation of settings of the
sub properties of the animation property. In fact, you can write this as the following
code, without the vendor-specific rules:
animation-name: my-spin-effect;
animation-duration: 4s;
animation-timing-function:linear;
animation-iteration-count: infinite;
[ 28 ]
Chapter 1
You can use the three parts of the preceding code to build a complete animation.
After doing this, you can extend it. For example, add an extra keyframe, which
makes the time curve nonlinear, as follows:
@keyframes my-spin-effect {
50% { transform: rotate(10deg);}
100% {transform: rotate(360deg); }
}
You can add a second property using background-color. Don't forget to remove the
gradient to see its effect. This is shown in the following code:
@-moz-keyframes my-spin-effect {
50% { transform: rotate(10deg); background-color:green;}
100% { transform: rotate(360deg); }
}
//.gradient(red,yellow);
You might have noticed that the complete profit of using Less isn't realized here. You
will have to write the @keyframes definition repeatedly due to the different vendor
prefixes its variable animation name. In Chapter 4, Testing Your Code and Using
Prebuilt Mixins Libraries, a solution will be provided to you for this. Again, you can
use the Less autoprefix plugin to solve this problem.
Unfortunately, browser support for transitions, transformations, and animations
is not great and varies between browsers. Google Chrome does support CSS 3D
transforms since Version 36. Older versions of Firefox lack support for the CSS
filters, and IE9 (and earlier versions) don't support them at all. To solve this, many
developers look to jQuery to support their animations. The jQuery.animate()
function allows us to change the CSS properties of the elements using JavaScript.
You can still use Less to set the initial CSS. An alternative for this would be to use
animate.css (which you can access at https://github.com/daneden/animate.
css); this cross-browser library of the CSS animations gets converted into the Less
code with a jQuery fallback.
Box-sizing
The box-sizing property is the one that sets the CSS-box model used for calculating
the dimensions of an element. In fact, box-sizing is not new in CSS, but nonetheless,
switching your code to box-sizing: border-box will make your work a lot easier.
When using the border-box settings, calculation of the width of an element includes
border width and padding. So, changing the border of padding won't break your
layouts. You can find a copy of the code used in this section in boxsizing.html from
the download files.
[ 29 ]
Nowadays, most web designs use a grid. Grids split your design into columns
of equal size. This helps you make things clear and build responsive interfaces.
Depending on the available screen size (or width), you can show your content and
navigation with a different representation of the same columns.
To handle different screen sizes, some parts of your website will have fluid width or
height. Other elements, such as borders, gutters, and the white space, should have a
fixed width. The combination of fluid widths as a percentage of the screen width (or
viewport) with fixed widths becomes complex. This complexity will be due to the
fact that browsers use different calculations for padding and margins of elements.
In order for you to see this, look at the following example. A container of 5300 pixels
width has been created. Inside this container, you can add two rows and split the
second row into two parts of 50 percent or half of its width.
<div class="wrapper" style="width:300px;">
<div style="background-color:red;width;100%;">1</div>
<div style="backgroundcolor:green;width:50%;float:left;">2</div>
<div style="backgroundcolor:blue;width:50%;float:right;">3</div>
</div>
An HTML wrapper
The current structure doesn't show a problem until you add some padding, which
is used to construct some space or a border between the two columns in the second
row (numbers, 2 and 3, in the screenshot of the HTML wrapper). The padding and
the border will break our layout as follows:
<div class="wrapper" style="width:300px;">
<div style="background-color:red;width:100%;">1</div>
<div style="background-color:green;width:50%;float:left;
border:5px solid yellow;">2</div>
<div style="background-color:blue;width:50%;border:5px solid
yellow;float:right;">3</div>
</div>
<br>
[ 30 ]
Chapter 1
<div class="wrapper" style="width:300px;">
<div style="background-color:red;width;100%;">1</div>
<div style="background-color:green;float:left;width:50%;
padding-right:5px;">
<div style="background-color:yellow;">2</div></div>
<div style="background-color:blue;width:50%;
padding-right:5px;float:right;">3</div>
</div>
Finally, the output of this code should look like the following screenshot:
A similar action can be performed, except that the wrappers can be wrapped inside
an extra wrapper. The box-sizing: border-box; declaration can then be applied
to this. Now, the results should look like the following screenshot:
[ 31 ]
As you can see, the padding and borders are subtracted by 50 percent from the parent.
This will make the calculation a lot easier. Of course, you can do the calculating
yourself, once the parent container wrapper has a fixed width. If the parent has 300
pixels, 50 percent of this will be 150 pixels. Taking away the padding and the width
of the border will give you the fixed size of a column. This won't work when your
parent has a fluid width (the percentage of the viewport). Fluid layouts change their
width with the width of the screen. If your screen becomes smaller, all the elements
become smaller too and the percentage stays equal. You will quickly realize that doing
calculations for all the possible screen sizes to find the real size of a column that allows
all of your elements to align, is a long, challenging, and arduous process.
For these reasons, you should make use of box-sizing: border-box; for all
the examples in this book. Note that box-sizing also has to be defined by
vendor-specific rules, as follows:
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: b/'order-box;
Note that the .box-sizing mixin will become obsolete when you
compile your Less code with the Less autoprefix plugin.
[ 32 ]
Chapter 1
With autoprefixing, your Less code can be reduced to the following code:
// Reset the box-sizing
*,
*:before,
*:after {
box-sizing: border-box;
}
The preceding code has been added into a separate file called
boxsizing.less. From now on, the basics of our Less files will
contain the following code:
@import: "normalize.less";@import: "boxsizing.less"
In the next chapters, you will learn more about organizing your Less code into files.
Server-side compiling
You have already taken the first few steps toward developing Less. As explained
earlier, client-side compiling has been used. However, client-side compiling with
less.js shouldn't be used on real websites. This is because, despite making your
development easy and fast, compiling your Less files for every page request (or in
fact, initial page load per user) will actually slow down your website.
For the production environment, it is required that you compile your files and serve
the final CSS file to the browser. The term, server side, can be somewhat misleading.
Server side in this context means that a compiled CSS code is sent to the client's
browser instead of the Less code, which has to be compiled in the client's browser by
less.js before it is shown. You should precompile your Less code. By copying and
pasting the results of less.js to a file and including this as a CSS file in your HTML
files, you should get the same effect, except that your CSS is not minimized.
Less bundles a command-line compiler. Installing and using it is simple, using the
following command:
>> npm install -g less
>> lessc styles.less styles.css
[ 33 ]
Node enables you to run the JavaScripts without a browser. Node and npm run
on Windows, Mac OS X, and other Unix/*nix machines. You will find the
Node.js source code or a prebuilt installer for your platform by visiting
http://nodejs.org/download/. The package manager for the Node JavaScript
platform is npm. The npm command-line tool is bundled with Node.js, so installing
Node.js will install npm at the same time. More information about npm can also
be found at https://www.npmjs.com/package/npm.
Use the help function to get a list of options you can use with the following
command-line compiler:
>> lessc help
The links to styles.css in your HTML, after successfully compiling it, are then
shown as follows:
<link rel="stylesheet/css" type="text/css" href="styles.css">
The preceding command will generate two files: styles.css.map and styles.css.
The last line of styles.css now contains an extra line, which refers to the source
map as follows:
/*# sourceMappingURL=boostrap.css.map */
In your HTML code, you only have to include the styles.css, as shown in the
following code:
<link href="styles.css" rel="stylesheet">
[ 34 ]
Chapter 1
When using the CSS source maps, as described in the preceding code, and inspecting
your HTML code with Google Chrome Developer Tools, you will see something like
the following screenshot:
Inspect source with Google Chrome Developer Tools and source maps
As you can see, styles now have a reference to their original Less file, such as grid.
less, including line number, which helps you in debugging. The styles.css.map
file should be in the same directory as the styles.css file. You don't have to include
your Less files in this directory too.
Plugins
The Less plugins can be installed with npm too. The npm plugin is the package
manager for Node.js.
To install a Less plugin, you should run the following command on your console:
npm install less-plugin-{plugin-name}
To use an already installed plugin with the command-line compiler, you should
use plugin-name as an option for the compiler. Options for the plugin can be set by
leveraging the = sign, followed by the list of options.
[ 35 ]
After installing the plugin, you can run the compiler with the clean-css option
as follows:
lessc clean-css file.less
The preceding code will compile into the CSS code, as the following code shows:
.class1,.class2{color:red}
As you can see, clean-css also merges the selectors. For advanced optimization of
your code, which includes selector merging, you should run the clean-css plugin
with the advanced option as follows:
lessc --clean-css="advanced" file.less
[ 36 ]
Chapter 1
Also, Pleeease is a CSS post-processor, which can be used to run different postprocess once. Pleeease, among others, runs the autoprefixer plugin, provides a
fallback for the em units, and can merge media queries. A Pleeease plugin for
Less is available, too.
You can read more about Pleeease at http://pleeease.io/.
[ 37 ]
The example code for this section can be found in the /gulp/
directory of the download for this chapter.
After installing Gulp, you have to create a Gulpfile.js file in your working
directory. The Gulpfile.js file defines the task that it should perform on your files
when running the gulp command. Your first Gulp file will look like that shown in
the following code:
var gulp = require('gulp');
var less = require('gulp-less');
gulp.task('default', function () {
gulp.src('./less/project.less')
.pipe(less())
.pipe(gulp.dest('./css'));
});
Now you can run the grunt command in the console, which will compile the Less
code of the ./less/project.less into the ./css/project.css file. The basic build
system uses the gulp-less plugin to compile your Less code. You can add more
plugins such as gulp-sourcemap and gulp-autoprefixer in order to bring your
build system to the next level.
The gulp-less plugin enables you to use the Less plugin, too. Using the Less
plugins, instead of the gulp plugins, for tasks will simplify your Gulp configuration.
You can use the task configuration shown in the following code to compile your Less
code with sourcemaps, and the clean-css and autoprefixer postprocessors:
var gulp = require('gulp');
var less = require('gulp-less');
var sourcemaps = require('gulp-sourcemaps');
var LessPluginCleanCSS = require("less-plugin-clean-css"),
cleancss = new LessPluginCleanCSS({advanced: true});
var LessPluginAutoPrefix = require('less-plugin-autoprefix'),
autoprefix= new LessPluginAutoPrefix({browsers: ["last 2
versions"]});
gulp.task('default', function () {
gulp.src('./less/project.less')
.pipe(sourcemaps.init())
.pipe(less({
[ 38 ]
Chapter 1
plugins: [autoprefix, cleancss]
}))
.pipe(sourcemaps.write())
.pipe(gulp.dest('./css'));
});
Finally, you can consider extending your build system with gulp-livereload. The
gulp-livereload plugin can be used with the livereload Chrome extension. The
livereload extension enables you to see the compiled version of your code in your
browser directly after saving and opens the way to in browser development too. You
can read more about livereload at http://livereload.com/.
CodeKIT: This GUI is for Mac (OS X). It compiles many languages, including
Less. It includes optimizations and browser previews.
When choosing a GUI for Less development, always check which version of less.
js it uses. Some GUIs are built on older versions of less.js and don't support the
latest features.
Web developers using Visual Studio should check out Web Essentials. Web
Essentials extends Visual Studio with a lot of new features, including Less. Also,
other IDEs such as PHPStorm have the built-in Less compilers. There is also a Less
plugin for Eclipse.
[ 39 ]
[ 40 ]
Chapter 1
OOCSS focuses on the code structure of your code. With OOCSS, you will
code reusable objects of styles. With OOCSS you work with reusable objects and
each object contains styles rules for a HTML structure which holds a type of content.
The basic rules of OOCSS help you to separate the structure from skin and container
from content. The OOCSS media object is probably the most discussed example.
You can read more about the media object at http://www.stubbornella.org/
content/2010/06/25/the-media-object-saves-hundreds-of-lines-of-code/.
When we create an object for buttons, it will look as shown
in the following code:
.btn {}
.btn .btn-error{}
.btn .active {}
OOCSS not only tries to separate the container from the content, but also separates
the style from the structure. In the button example, the .btn selector provides the
structure while the .btn-error selector provides the styling. Also note that the .btn
.active {} selector describes a state of your button object.
Nesting of selectors can be used to organize style rules for the button object together.
The following Less code can be used for the button object:
.btn {
.btn-error{}
.active {}
}
As already mentioned, BEM is an application of OOCSS. The BEM syntax uses the
following assumptions:
The Less code for the button component using BEM will look like the following code:
.btn {
&__error {}
&--active{}
}
[ 41 ]
The preceding Less code makes use of the & parent selector and nesting, and will
compile into the CSS code as follows:
.btn {}
.btnerror {}
. btnactive {}
Summary
In this chapter, you refreshed and extended your knowledge of CSS3. You learned
how to compile your Less code on the client side. Furthermore, you wrote the code
that allows you to have rounded corners, gradients, and animations in Less. You
witnessed the profits of using Less and can now take the crucial initial steps to
organize and plan your new projects. You also witnessed why you would want
to use the CSS resets, how to compile these into the Less code, as well as how the
box-sizing:border-box can make your job easier. You also saw what a mixin is,
how to use it, and how you can import a Less file with the @import directive. You
learned what is server-side compiling, how to set up a build process, and how to use
GUIs. Last but not least, you got introduced to some methodologies that will help
you to better organize your CSS code, leveraging Less.
In the next chapter, you will learn how to use variables in Less and how to build and
use complex mixins.
[ 42 ]
www.PacktPub.com
Stay Connected: