Less: Beyond Basics with the Bootstrap Mixins Library
Last updated
Was this helpful?
Last updated
Was this helpful?
By Maria Antonietta Perna
Preprocessors like Less, Sass, Stylus, etc., extend the capabilities of CSS by including such programming language features as variables, functions, mathematical operations, etc. Appropriate use of this technology aims to ensure maintainable stylesheet documents and an improved workflow.
Here's what the project's directory structure looks like.
All the Bootstrap files go into the bootstrap folder. This also includes a mixins folder where we place the Bootstrap mixins.
The index.html file goes straight inside the bs-mixins-demo folder.
The demo.css file will be added to the css folder, once the Less files are compiled.
The project's Less file, demo.less, is placed inside the less folder. All the Less code I write for this demo goes here.
In a real world project, I'd break its contents into separate .less files. However, given the reduced size of this demo, we can get away with just one file.
The demo page consists of a simple two-column layout with header and footer. Bootstrap components and JavaScript plugins are not used. But don't be fooled - there's enough in there to show the Bootstrap's mixins goodness in action:
adaptive layout
nested columns
columns offset
different column display order on desktop and mobile view
Bootstrap buttons
CSS3 gradients
CSS3 card-flipping effect on hover
Below is what the outline of index.html looks like.
Here's an added bonus of using the Less source code: a clean HTML document without any typical Bootstrap grid classes.
The files listed below need to be copied over from the Less folder of the downloaded source code into the demo's bootstrap folder:
mixins.less
normalize.less
scaffolding.less
variables.less
Also, the entire content of the mixins directory of the Bootstrap source code needs to be copied over into the demo's mixins folder.
To make the Bootstrap .less files available to our demo, Less offers the @import
directive. In this demo, we import our copy of the Bootstrap files into the demo.less file like so:
The reference keyword is a great feature: now we have everything contained in bootstrap/variables.less and bootstrap/mixins.less at our fingertips. However, only what we actually use for our project will be compiled into the resulting CSS document.
You can compile Less code both server side and client side.
Client side compiling is great to get started with Less and experimenting with it. However, for a production site, the best option is server side precompiling with node.js or a third party tool.
Mixins are a way of including ("mixing in") a bunch of properties from one rule-set into another rule-set.
Here's an example.
If we choose to build a web layout using floats, we will need a technique to clear those floats.
The advantage of having it packaged into a mixin is that we can now add it wherever we need to clear floats with just one line of code. For example, here's how to add it to a container element that encompasses a number of floated elements:
When compiled into CSS, this code outputs the following:
The level of complexity of a mixin varies in relation to what you intend to achieve with it. It's time to see what it's possible to achieve using the Bootstrap mixins as a library for our project.
If you're ready to move from the basics and embark on your journey to mixins ninjahood, using an excellent mixins library not only helps you write awesome CSS code, but is also a great way to learn from the best. Let's open the mixins folder and explore the way Bootstrap builds its Less code.
The mixins that I personally find most useful are those that help me build the page layout. You can find these in grid.less.
The .container-fixed() Mixin
This mixin is designed to generate the CSS for centering the content of a web page. Here it is:
Let's take a closer look into the .container-fixed()
mixin.
This particular Bootstrap mixin uses arguments with default values. The argument @gutter
has a default value of @grid-gutter-width
, that you can find in the variables.less
file. This means that, if no value for this argument is passed when using the mixin, the code will fall back on the default value.
One more interesting bit to notice about the .container-fixed()
mixin is its use of &:extend(.clearfix all).
This piece of code does the following:
it includes a .clearfix
class built with the .clearfix()
mixin. This class has the functionality of clearing floated child elements;
it extends that functionality to the elements and classes styled using the .container-fixed()
mixin. It does this with the Less :extend()
pseudo-class;
Applying the .clearfix()
mixin to any element or class that contains floated children ends up repeating the same clearfix hack over and over in the CSS document.
However, using the Less :extend()
pseudo-class instead, as Bootstrap now does, will output this CSS code:
To use the Bootstrap .container-fixed()
mixin in your code, add .container-fixed()
to a class or a HTML element. In this article's demo, I use it for the .container
class, just like Bootstrap does:
Here's what the CSS output of the .container
class looks like:
The .make-row() Mixin
In the Bootstrap grid system, columns live inside a wrapper element. The .make-row()
mixin generates the styles for this element. Here's what it looks like:
This mixin calculates a left and right margin for the row. Also, since the .make-row()
mixin is designed to style wrappers for floated columns, it's extended with the .clearfix
class for floats clearing.
In this article's demo, I use it on the .page-content
class, like this:
The CSS output is:
The Columns Mixins
The Bootstrap grid system uses four column sizes for responsive layouts: the extra-small, the small, the medium, and the large size.
Each column size is generated by a corresponding mixin. Because these mixins have a similar pattern, let's just examine the mixin for the medium column.
This is another parametric mixin. The @gutter
argument has a default value, but the value for the @columns
argument will have to be provided when using the mixin. If you don't assign a value to the @columns
argument, Less will throw an error.
A great feature Less offers is nesting. You can nest selectors in a way that reflects the parent-children relationship in your HTML document, without having to write the parent's selector every time you reference a child element's selector.
For instance, what in regular CSS looks like this:
... using Less nesting, looks like this:
Directives such as
media
orkeyframe
can be nested in the same way as selectors. Directive is placed on top and relative order against other elements inside the same ruleset remains unchanged. This is called bubbling.
The media query inside the .make-md-column()
mixin dictates the column's behavior when the screen's width corresponds to the value of the @screen-md-min
variable (Bootstrap gives a default value of 992px to this variable. You can find this out in variables.less
). When the screen's width hits the assigned value, the column's width will be equal to the percentage value of your design's number of columns divided by the total number of columns (Bootstrap's default value for the total number of columns is twelve).
The demo uses the .make-md-column()
mixin for the sidebar, the main content column, and the six nested columns inside the main content.
The CSS output for the .sidebar is:
The mixin Bootstrap uses to build the styles for the button element is a great example of how convenient it is to use Less for CSS development.
The .button-variant()
mixin is located in the buttons.less
file inside the mixins folder. It outputs default button styles, as well as styles for common button states. This means that you add this mixin to a button element's selector and never worry about writing other rules for all those button states. What a time saver!
Here's the mixin's code:
This parametric mixin needs three values from you and spits out a major chunk of CSS code that covers all buttons' states.
There are some selectors that are part of the Bootstrap framework in there, like .badge
or .dropdown-toggle
. But nothing prevents you from copying over this mixin into demo.less (or into your project's specific mixins library folder) and customizing it to fit your own needs. If you didn't want any extraneous Bootstrap selectors, you could rewrite the .button-variant()
mixin like so:
This is how I use the .demo-button-variant()
mixin in the demo page:
The CSS output is:
What about all those ampersand symbols (&)? The ampersand selector refers to the parent selector inside a nested selector. The most common use is with pseudo-classes, like in the example below. Instead of repeating .action-btn
like in vanilla CSS, slamming an ampersand does the job and saves precious time.
This compiles into the following CSS:
You can also use the ampersand selector inside mixins, like in the Bootstrap .button-variant()
mixin. When the ampersand is placed at the end of the selector list, it allows you to reverse the order of nesting. To use a small chunk of the .button-variant()
mixin as example:
When the mixin above is used on the .action-btn
selector, it outputs the following CSS
In gradients.less inside the mixins folder, you'll find a bunch of mixins encapsulated within a namespace. This is a great technique for grouping mixins for organizational purposes and making your code more portable.
Here's the general structure of the Bootstrap gradient mixin to illustrate this point (the complete source code is available with the demo's files).
As you can see, namespaces are defined in the same way as CSS ID selectors.
In the example above, the code that goes inside each grouping is not different from what you would write in your CSS code for a gradient, only using the mixin's arguments instead of fixed values.
In the demo for this article, I use the vertical gradient mixin to style the background of the entire web page:
Less has a great variety of color functions. The ones used above are designed to produce a lighter or darker variant of the input color. Really handy when you need a quick way of generating a palette of different shades of the same basic color value.
In this article I've highlighted some features of the Less preprocessor language by getting close and personal with the Bootstrap mixins and using a good number of them in a small project.
Exploring and using Bootstrap as a rich mixins library means translating all the theory on the Less preprocessor language we gain from books, courses, and tutorials, into a real-world context. It's a great way of making the transition from handling the basics of Less to becoming a pro.
This article takes a step beyond the basics of the preprocessor language by using some of the Less code as both a learning and development tool.
If you're just starting out, enjoy , a clear and concise video introduction by Sandy Ludosky.
The Less features discussed here are all implemented in and as this so that you can freely see how the page looks, check the code details for yourself and experiment with it.
The Bootstrap files we need for this demo are available on the . Make sure, you grab the Less source files.
Less has that can be used with the @import
directive: reference, inline, less, css, once, and multiple.
Client side compilation is as quick as adding demo.less and less.js (downloadable from the website) in the head
section of your HTML document.
This demo uses , a precompiler for Windows, Mac, and Linux available both as a free and a paid download. You're free to use your favorite tool, it won't affect the end result.
For an in-depth guide on how to use Prepros to precompile your Less code, by Ivaylo Gerchev will tell you all you need to know.
in Less offer a way to package all the properties of a class so that we can reuse them as a property inside another class.
From the website:
Below is the by Nicolas Gallagher, also used by the Bootstrap framework, turned into a Less mixin.
This is a , that is, a mixin that takes one or more arguments. Writing mixins like this gives us quite a bit of flexibility. We can use the same ruleset but customize it differently by changing the value we assign to the arguments.
by adding the at the end, it ensures that the compiler extends the clearfix functionality to all selectors nested inside the extended class.
Since the release of of the Bootstrap framework, &:extend(.clearfix all)
has replaced the use of the .clearfix()
mixin inside the .container-fixed()
mixin (you can define a mixin inside another mixin). Let's examine why we can consider this move as an improvement in the quality of the Bootstrap CSS code.
What the Less does is to produce a CSS declaration that groups together all the elements and classes that share the same CSS rules. For instance, if you were to apply the .clearfix()
mixin to .container
, .row
, and .footer
, your compiled CSS would repeat the same clearfix hack for each of the three classes.
The gain of using the :extend()
pseudo-class is a compliance with the . In particular, it avoids repeating the same CSS code by merging together elements and class selectors that share the same bunch of properties.
The Bootstrap .make-md-column()
mixin shows us how to take advantage of this nifty Less feature inside a mixin. The says:
The Bootstrap gradient mixin has default values as arguments, therefore you can just use empty brackets and it works. Here, I change the start and end color of the gradient using the Less pre-built and color functions.