In this article by Silvio Moreto Pererira, author of the book, Bootstrap By Example, we will focus on mobile design and how to change the page layout for different viewports, change the content, and more.
In this article, you will learn the following:
(For more resources related to this topic, see here.)
Maybe you have asked yourself (or even searched for) the reason of the mobile first paradigm movement. It is simple and makes complete sense to speed up your development pace.
The main argument for the mobile first paradigm is that it is easier to make it greater than to shrink it. In other words, if you first make a desktop version of the web page (known as responsive design or mobile last) and then go to adjust the website for a mobile, it has a probability of 99% of breaking the layout at some point, and you will have to fix a lot of things in both the mobile and desktop.
On the other hand, if you first create the mobile version, naturally the website will use (or show) less content than the desktop version. So, it will be easier to just add the content, place the things in the right places, and create the full responsiveness stack.
The following image tries to illustrate this concept. Going mobile last, you will get a degraded, warped, and crappy layout, and going mobile first, you will get a progressively enhanced, future-friendly awesome web page. See what happens to the poor elephant in this metaphor:
At the beginning of Bootstrap, there was no concept of mobile first, so it was made to work for designing responsive web pages. However, with the version 3 of the framework, the concept of mobile first was very solid in the community.
For doing this, the whole code of the scaffolding system was rewritten to become mobile first from the start. They decided to reformulate how to set up the grid instead of just adding mobile styles. This made a great impact on compatibility between versions older than 3, but was crucial for making the framework even more popular.
To ensure the proper rendering of the page, set the correct viewport at the <head> tag:
<meta name="viewport" content="width=device-width,
initial-scale=1">
Here, you will learn how to debug different viewports using the Google Chrome web browser. If you already know this, you can skip this section, although it might be important to refresh the steps for this.
In the Google Chrome browser, open the Developer tools option. There are many ways to open this menu:
With Developer tools, click on the mobile phone to the left of a magnifier, as showed in the following image:
It will change the display of the viewport to a certain device, and you can also set a specific network usage to limit the data bandwidth. Chrome will show a message telling you that for proper visualization, you may need to reload the page to get the correct rendering:
For the next image, we have activated the Device mode for an iPhone 5 device. When we set this viewport, the problems start to appear because we did not make the web page with the mobile first methodology.
Now that we know more about mobile first development and its important role in Bootstrap starting from version 3, we will cover Bootstrap usage for different devices and viewports.
For doing this, we must apply the column class for the specific viewport, for example, for medium displays, we use the .col-md-*class. The following table presents the different classes and resolutions that will be applied for each viewport class:
|
Extra small devices (Phones < 544 px / 34 em) |
Small devices (Tablets ≥ 544 px / 34 em and < 768 px / 48 em) |
Medium devices (Desktops ≥ 768 px /48 em < 900px / 62 em) |
Large devices (Desktops ≥ 900 px / 62 em < 1200px 75 em) |
Extra large devices (Desktops ≥ 1200 px / 75 em) |
Grid behavior |
Horizontal lines at all times |
Collapse at start and fit column grid |
|||
Container fixed width |
Auto |
544px or 34rem |
750px or 45rem |
970px or 60rem |
1170px or 72.25rem |
Class prefix |
.col-xs-* |
.col-sm-* |
.col-md-* |
.col-lg-* |
.col-xl-* |
Number of columns |
12 columns |
||||
Column fixed width |
Auto |
~ 44px or 2.75 rem |
~ 62px or 3.86 rem |
~ 81px or 5.06 rem |
~ 97px or 6.06 rem |
To exemplify the usage of Bootstrap scaffolding in mobile devices, we will have a predefined web page and want to adapt it to mobile devices. We will be using the Chrome mobile debug tool with the device, iPhone 5.
You may have noticed that for small devices, Bootstrap just stacks each column without referring for different rows. In the layout, some of the Bootstrap rows may seem fine in this visualization, although the one in the following image is a bit strange as the portion of code and image are not in the same line, as it supposed to be:
To fix this, we need to add the class column's prefix for extra small devices, which is .col-xs-*, where * is the size of the column from 1 to 12. Add the .col-xs-5 class and .col-xs-7 for the columns of this respective row. Refresh the page and you will see now how the columns are put side by side:
<div class="row">
<!-- row 3 -->
<div class="col-md-3 col-xs-5">
<pre><p>I love programming!</p>
<p>This paragraph is on my landing page</p>
<br/>
<br/>
<p>Bootstrap by example</p>
</pre>
</div>
<div class="col-md-9 col-xs-7">
<img src="imgs/center.png" class="img-responsive">
</div>
</div>
Although the image of the web browser is too small on the right, it would be better if it was a vertical stretched image, such as a mobile phone. (What a coincidence!)
To make this, we need to hide the browser image in extra small devices and display an image of the mobile phone. Add the new mobile image below the existing one as follows. You will see both images stacked up vertically in the right column:
<img src="imgs/center.png" class="img-responsive">
<img src="imgs/mobile.png" class="img-responsive">
Then, we need to use the new concept of availability classes present in Bootstrap. We need to hide the browser image and display the mobile image just for this kind of viewport, which is extra small. For this, add the .hidden-xs class to the browser image and add the .visible-xs class to the mobile image:
<div class="row">
<!-- row 3 -->
<div class="col-md-3 col-xs-5">
<pre><p>I love programming!</p>
<p>This paragraph is on my landing page</p>
<br/>
<br/>
<p>Bootstrap by example</p>
</pre>
</div>
<div class="col-md-9 col-xs-7">
<img src="imgs/center.png" class="img-responsive hidden-xs">
<img src="imgs/mobile.png" class="img-responsive visible-xs">
</div>
</div>
Now this row seems nice! With this, the browser image was hidden in extra small devices and the mobile image was shown for this viewport in question. The following image shows the final display of this row:
Moving on, the next Bootstrap .row contains a testimonial surrounded by two images. It would be nicer if the testimonial appeared first and both images were displayed after it, splitting the same row, as shown in the following image. For this, we will repeat almost the same techniques presented in the last example:
The first change is to hide the Bootstrap image using the .hidden-xs class. After this, create another image tag with the Bootstrap image in the same column of the PACKT image. The final code of the row should be as follows:
<div class="row">
<div class="col-md-3 hidden-xs">
<img src="imgs/bs.png" class="img-responsive">
</div>
<div class="col-md-6 col-xs-offset-1 col-xs-11">
<blockquote>
<p>Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Integer posuere erat a ante.</p>
<footer>Testimonial from someone at
<cite title="Source Title">Source Title</cite></footer>
</blockquote>
</div>
<div class="col-md-3 col-xs-7">
<img src="imgs/packt.png" class="img-responsive">
</div>
<div class="col-xs-5 visible-xs">
<img src="imgs/bs.png" class="img-responsive">
</div>
</div>
We did plenty of things now; all the changes are highlighted. The first is the .hidden-xs class in the first column of the Bootstrap image, which hid the column for this viewport.
Afterward, in the testimonial, we changed the grid for the mobile, adding a column offset with size 1 and making the testimonial fill the rest of the row with the .col-xs-11 class.
Lastly, like we said, we want to split both images from PACKT and Bootstrap in the same row. For this, make the first image column fill seven columns with the .col-xs-7 class.
The other image column is a little more complicated. As it is visible just for mobile devices, we add the .col-xs-5 class, which will make the element span five columns in extra small devices. Moreover, we hide the column for other viewports with the .visible-xs class.
As you can see, this row has more than 12 columns (one offset, 11 testimonials, seven PACKT images, and five Bootstrap images). This process is called column wrapping and happens when you put more than 12 columns in the same row, so the groups of extra columns will wrap to the next lines.
Availability classes
Just like .hidden-*, there are the .visible-*-*classes for each variation of the display and column from 1 to 12. There is also a way to change the display of the CSS property using the .visible-*-* class, where the last * means block, inline, or inline-block. Use this to set the proper visualization for different visualizations.
The following image shows you the final result of the changes. Note that we made the testimonial appear first, with one column of offset, and both images appear below it:
Completing the mobile visualization devices, we move on to tablets and small devices, which are devices from 544 px (34 em) to 768 px (48 em). Most of this kind of devices are tablets or old desktops monitors. To work with this example, we are using the iPad mini in the portrait position.
For this resolution, Bootstrap handles the rows just as in extra small devices by stacking up each one of the columns and making them fill the total width of the page. So, if we do not want this to happen, we have to set the column fill for each element with the .col-sm-* class manually.
If you see now how our example is presented, there are two main problems. The first one is that the heading is in separate lines, whereas they could be in the same line. For this, we just need to apply the grid classes for small devices with the .col-sm-6 class for each column, splitting them into equal sizes:
<div class="row">
<div class="col-md-offset-4 col-md-4 col-sm-6">
<h3>
Some text with <small>secondary text</small>
</h3>
</div>
<div class="col-md-4 col-sm-6">
<h3>
Add to your favorites
<small>
<kbd class="nowrap"><kbd>ctrl</kbd> + <kbd>d</kbd></kbd>
</small>
</h3>
</div>
</div>
The result should be as follows:
The second problem in this viewport is again the testimonial row! Due to the classes that we have added for the mobile viewport, the testimonial now has an offset column and different column span. We must add the classes for small devices and make this row with the Bootstrap image on the left, the testimonial in the middle, and the PACKT image on the right:
<div class="row">
<div class="col-md-3 hidden-xs col-sm-3">
<img src="imgs/bs.png" class="img-responsive">
</div>
<div class="col-md-6 col-xs-offset-1 col-xs-11
col-sm-6 col-sm-offset-0">
<blockquote>
<p>Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Integer posuere erat a ante.</p>
<footer>Testimonial from someone at
<cite title="Source Title">Source Title</cite></footer>
</blockquote>
</div>
<div class="col-md-3 col-xs-7 col-sm-3">
<img src="imgs/packt.png" class="img-responsive">
</div>
<div class="col-xs-5 hidden-sm hidden-md hidden-lg">
<img src="imgs/bs.png" class="img-responsive">
</div>
</div>
As you can see, we had to reset the column offset in the testimonial column. It happened because it kept the offset that we had added for extra small devices. Moreover, we are just ensuring that the image columns had to fill just three columns with the .col-sm-3 classes in both the images. The result of the row is as follows:
Everything else seems fine! These viewports were easier to set up. See how Bootstrap helps us a lot? Let's move on to the final viewport, which is a desktop or large devices.
Last but not least, we enter the grid layout for a desktop and large devices. We skipped medium devices because we coded first for this viewport.
Deactivate the Device mode in Chrome and put your page in a viewport with a width larger or equal to 1200 pixels.
The grid prefix that we will be using is .col-lg-*, and if you take a look at the page, you will see that everything is well placed and we don't need to make changes! (Although we would like to make some tweaks to make our layout fancier and learn some stuff about the Bootstrap grid.)
We want to talk about a thing called column ordering. It is possible to change the order of the columns in the same row by applying the.col-lg-push-* and .col-lg-pull-* classes. (Note that we are using the large devices prefix, but any other grid class prefix can be used.)
The .col-lg-push-* class means that the column will be pushed to the right by the * columns, where * is the number of columns pushed. On the other hand, .col-lg-pull-* will pull the column in the left direction by *, where * is the number of columns as well. Let's test this trick in the second row by changing the order of both the columns:
<div class="row">
<div class="col-md-offset-4 col-md-4 col-sm-6 col-lg-push-4">
<h3>
Some text with <small>secondary text</small>
</h3>
</div>
<div class="col-md-4 col-sm-6 col-lg-pull-4">
<h3>
Add to your favorites
<small>
<kbd class="nowrap"><kbd>ctrl</kbd> + <kbd>d</kbd></kbd>
</small>
</h3>
</div>
</div>
We just added the .col-lg-push-4 class to the first column and .col-lg-pull-4 to the other one to get this result. By doing this, we have changed the order of both the columns in the second row, as shown in the following image:
In this article, you learned a little about the mobile first development and how Bootstrap can help us in this task. We started from an existing Bootstrap template, which was not ready for mobile visualization, and fixed that.
While fixing, we used a lot of Bootstrap scaffolding properties and Bootstrap helpers, making it much easier to fix anything. We did all of this without a single line of CSS or JavaScript; we used only Bootstrap with its inner powers!
Further resources on this subject: