Lesson 27 - Bootstrap - Bootstrap's grid system
In the previous lesson, Bootstrap - Introduction to the grid systems, we introduced grid systems. Today is the last tutorial of the Bootstrap CSS framework course, we're getting to the Bootstrap grids. As always, we're going to have a look at what we can do with them using practical examples.
Responsive classes
The great thing about grid is not only that it wraps when it won't fit the
page, but we can also set when it will wrap. Except for the classes named as
col-{number}
, we can also assign responsive classes such as
.col-sm-3
which specifically means that the column will take 3/12
of the grid on small devices and larger.
Let's use these breakpoint-specific classes in the example from the end of the previous lesson. We'll define columns only on medium sized viewports and larger. There will be only a single column on smaller devices occupying the width of 12 columns (tho whole width) which is the default width. The items will be wrapped under each other.
<div class="container-fluid bg-light"> <div class="row"> <div class="col-sm-3 border bg-success text-white"> One fourth </div> <div class="col-sm-3 border bg-success text-white"> One fourth </div> <div class="col-sm-6 border bg-warning"> One half </div> </div> </div>
The result:
You can try to reduce the size of your browser window and look at the example above. The elements will wrap and stack one under another. The contents of our page are now divided into a "table" which is responsive at the same time!
We can assign multiple classes to a single column and "program" how wide it should be on different devices. You can assign any responsive class to any column. We've already defined how wide different devices are and what breakpoint abbreviations do they have in the Bootstrap - Typography lesson. To be complete let's also mention that breakpoints go as follows:
sm
md
lg
xl
Let's have a look at one more example showing a combination of multiple classes on individual columns so that they'd behave differently on different devices. We can check the behavior by reducing the size of the browser's window.
<div class="row"> <div class="col-4 col-md-6 border bg-success text-white">Column 1</div> <div class="col-8 col-md-6 border bg-success text-white">Column 2</div> </div>
The result:
On medium sized devices or larger both columns occupy a half of the
container. On smaller devices, the first <div>
takes 1/3 and
the second one 2/3 of the container.
What we should know
The column elements have the padding around them, it's called
gutter in the context of the Bootstrap grid system. We can
eventually remove it by assigning the .no-gutters
class to the
element with the .row
class. We can't add margin to the grid
columns since the total width of the elements would exceed the width of the
container and they would wrap. However, nothing keeps us from adding a another
element in the column and set the margin to this element. In order to make the
grid system work, all direct child elements of the rows have to be columns.
Columns can contain rows again, meaning we can nest grids into one another. Some
HTML elements can't be used as flex containers, for example
<button>
or <fieldset>
. There are several
bugs reported, mainly for outdated Internet Explorer, as you probably guessed.
However, some are related to modern browsers as well. You can find a list of the
reported errors here.
Gutters are implemented by applying padding
on both
sides of every column and negative margin
on the container. Because
of that, the columns have gaps between themselves but the first and the last
columns don't have a gap between themselves and the outer content of the
container.
Automatic width
If we set the width of some element using a class named as
.col-{breakpoint}-auto
, its width will be set in a way that its
content will fit inside and the rest of the width will be distributed between
the rest of the columns according to the rules defined in the grid. How the rest
of the container will be used is related to the automatic width as well. If
there are columns with a specified width in the grid and also columns with just
the .col
class assigned, the .col
columns will fill
the remaining space.
Let's try it both:
<div class="container-fluid"> <div class="row"> <div class="col border bg-success text-white"> Column 1 </div> <div class="col-sm-auto border bg-warning"> Column 2 </div> <div class="col col-sm-4 border bg-success text-white"> Column 3 </div> </div> </div>
The live demo:
The code above renders a container with three columns. The first one always takes the remaining space, as much as possible. The second one takes as little space as possible, just to make its contents fit in. The third one takes 4/12 of the width of the container. When the size of the viewport is reduced to a small device size or smaller, all columns stack one under another.
The automatic column width is rather a cool technological feature than a style you'd use very often. What makes grids so useful is specifying column widths by a particular number of grid columns, not making it based on the element contents.
Forcing the row to wrap
If we ever needed to wrap a row before it's really necessary for some reason,
we can do so by adding a column with the .w-100
class into the
grid:
<div class="container-fluid"> <div class="row"> <div class="col-sm border bg-success text-white"> Column 1 </div> <div class="col-sm border bg-success text-white"> Column 2 </div> <div class="w-100"></div> <div class="col-sm border bg-success text-white"> Column 3 </div> </div> </div>
The result:
Notice that we can use the .col-sm
class as well which adds a
responsive breakpoint without specifying how many columns of the grid should the
column take. Also, if the sum of the widths of the columns in a row exceeds 12
columns (e.g. .col-4
and .col-9
), the row will wrap as
well.
Alignment and change of order
It theoretically shouldn't happen much but sometimes we may need to align the
grid columns somehow. What we talked about in the detailed lessons about Flex
utilities works for the columns of a container as well. We assign classes
such as .align-items-center
, .justify-content-center
,
or .align-self-end
to the elements with the .row
class. We can also change the actual order of the columns in a row regardless of
its order in the code. All we need to do is to assign them one of the classes
starting with .order-{number}
, where the value of the number is
1
- 12
. We should know all of this from the flex
utilities already. To make these materials complete, let's show one example for
all:
<div class="container-fluid"> <div class="row justify-content-center bg-light" style="height: 150px;"> <div class="col-auto border bg-success text-white order-2 align-self-start"> Second </div> <div class="col-auto border bg-success text-white order-1 align-self-center"> First </div> <div class="col-auto border bg-success text-white align-self-end order-3"> Third </div> </div> </div>
And the live demo:
Offsets
We sometimes may not use some column and leave free space there instead. To
avoid declaring such a column unnecessarily in the code, we don't have to add
the empty column at all and just move the next column a bit. We are provided
with the classes named as .offset-{number}
for this purpose,
eventually .offset-{breakpoint}-number
. The number specifies how
many columns (of 12) the given column should move to the right.
<div class="container-fluid"> <div class="row"> <div class="col-md-3 bg-success text-white"> Column 1 </div> <div class="col-md-4 offset-md-4 bg-success text-white"> Column 2 </div> </div> </div>
The demo:
If we wanted to set the offset to be applied from a certain
breakpoint and to not from another, we'd disable it for the second dimension
using the .offset-{breakpoint}-0
class.
Automatic margins
From flex utilities, we should know the hack with auto margins as well. If we
set the .ml-auto
or .mr-auto
class to some column, the
rest of the columns moves to the left, resp. to the right.
<div class="container-fluid"> <div class="row"> <div class="col-md-4 border bg-success text-white"> Column 1 </div> <div class="col-md-2 border bg-success text-white"> Column 2 </div> <div class="col-md-2 border bg-success text-white ml-auto"> Column 3 </div> </div> </div>
The demo:
Congratulations! Now you master a powerful tool which allows you to create templates much faster than others who don't know it. And this is going to be very useful for you! Developing software takes lots of time, if you can save some somewhere, you'll become more successful