Preface
Step Four: Reponsive Layout using Bootstrap.
From template, to SASS, now we need to focus on the HTML itself, especially for bootstrap default class.
1: Overview
General Preview
This below is general preview of, what responsive page that we want to achieve. Just keep in mind that, responsive design is based on consideration. So different website might have different preview.
Source image is available in inkscape SVG format, so you can modify, and make your own preview quickly.
Bootstrap v4
The obsolete Bootstrap v4 article series is also available.
Source Code: Step-04
The source code for this chapter is, available for download at the following link:
SASS Directory Structure
For each step as the site grow, we are going to alter the SASS, one by one. After its complete we are going to have this structure.
❯ tree -C sass/css
sass/css
├── bootstrap.scss
├── bootswatch5.scss
├── main
│ ├── _decoration.scss
│ ├── _layout-content.scss
│ ├── _layout-page.scss
│ ├── _logo.scss
│ └── _sticky-footer.scss
├── main.scss
└── _variables.scss
2 directories, 9 files
Custom SASS: Main
So that the main file is going to be like this one below:
@import
"main/layout-page",
"main/layout-content",
"main/logo",
"main/decoration",
"main/sticky-footer"
;
2: Simple Responsive
Using bootstrap class.
We require real example page, as usual.
Example Layout Page
Responsive Class
We would like to apply a simple responsive design for this two elements.
<!-- responsive -->
<div class="row layout-base maxwidth">
<main class="col-sm-8 p-4 bg-warning">
Page Content
</main>
<aside class="col-sm-4 p-4 bg-info">
Side Menu
</aside>
</div>
Page Skeleton
So far we have these three elements:
-
Header part: Navigation Bar.
-
Main part: Content
-
Footer part.
The internal layout for this show case can be summarized as below:
<html>
<head>
<!--head section -->
</head>
<body>
<!-- header -->
<nav role="navigation">
...
</nav>
<!-- main: responsive layout -->
<div class="row">
<main class="col-md-8">
<!-- content -->
</main>
<aside class="col-md-4">
<!-- aside -->
</aside>
</div>
<!-- footer -->
<footer>
...
</footer>
</body>
</html>
Of course you can make your own skeleton to suit your needs.
The Columns
Now we can have this two elements inside main
parts.
-
main
element: page content or blog post content -
aside
element: side panel
What is this col-md-8
and col-md-4
class?
Bootstrap is twelve columns based layout.
This means the total column should be 12
.
For tow-third
plus one-third
layout,
you use col-md-8
and col-md-4
.
Blocks
Nunjucks Document Source
The template for this article is definitely the same as previous code, the ony differences is the content.
{% extends './layouts/base.njk' %}
{% block htmlhead %}
{% include './heads/041-meta.njk' %}
{% include './heads/041-links.njk' %}
{% endblock %}
{% block header %}
{% include './shared/041-navbar.njk' %}
{% endblock %}
{% block content %}
{% include './contents/043-main.njk' %}
{% endblock %}
{% block footer %}
{% include './shared/041-footer.njk' %}
{% endblock %}
Static Page
HTML Document Target
The generated HTML result can be found here:
Browser Preview
Screenshot
For desktop screen the result is similar to below figure:
For mobile screen the result is similar to below figure:
3: Responsive Spacing
What if I want gap between column, vertically and horizontally?
Vertical on Mobile Screen
This layout-content
just a custom class.
// responsive - mobile
.layout-base main {
margin-bottom: 20px;
}
@media only screen and (min-width: 576px) {
.layout-base main {
margin-bottom: 0px;
}
}
This will only give gaps, for mobile screen.
For real life blog I prefer to use md
vreakpoint instead of sm
.
so the media screen in my real life blog is:
@media only screen and (min-width: 768px) {
...
}
Or alternatively, use responsive mixin
provided by bootstrap.
Browser Preview
Screenshot
For mobile screen the result is similar to below figure:
Horizontal on Desktop Screen
Bootstrap 5 has grid and flex. The grid implement native css gap, so you can use freely.
Unfortunately, bootstrap flex can’t do that. We will deal with this in next chapter with wrapper class.
4: Navigation Bar
Navbar for this chapter.
The next example require a complete page, so we can examine responsive for the whole page.
For the sake of responsive example page, I decide to bring back the navbar for this chapter.
This section deal with HTML preparation. We will focus on the responsive itself in the next section.
Templates
Nunjucks
❯ tree -C views
views
├── 044-responsive-content.njk
├── contents
│ └── 044-main.njk
├── heads
│ └── 044-links.njk
├── layouts
│ └── base.njk
└── shared
├── 044-footer.njk
├── 044-navbar-collapse.njk
├── 044-navbar-dropdown.njk
├── 044-navbar.njk
└── navbar-button.njk
5 directories, 9 files
Navbar: Reusable Button
My most favorite part is this reusable chunk.
<button type="button"
class="navbar-toggler"
data-bs-toggle="collapse"
data-bs-target="#navbarCollapse"
aria-controls="navbarCollapse"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
![Bootstrap5: Nunjucks: Shared: Navbar: Button][040-s-navbar-button]
Navigation Bar
Now we can go straight with the navbar.
<!-- header -->
<nav class="navbar navbar-expand-sm navbar-dark
maxwidth fixed-top bg-dark">
<div class="container-fluid">
<a class="navbar-brand ms-4" href="#">
<img src="assets/images/logo-gear.png"
alt="Home" width="32" height="32"/>
</a>
{% include './navbar-button.njk' %}
{% include './044-navbar-collapse.njk' %}
</div>
</nav>
Navbar: Collapsible
And go deep into the collapsible detail.
<div class="collapse navbar-collapse"
id="navbarCollapse">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link active" href="#">
<span class="fa fa-home"></span>
Blog <span class="visually-hidden"
>(current)</span></a>
</li>
<li class="nav-item dropdown">
{% include './044-navbar-dropdown.njk' %}
</li>
<li class="nav-item">
<a class="nav-link active" href="#">
<span class="fas fa-child"></span>
About</a>
</li>
</ul>
<form class="d-flex form-inline mt-2 mt-md-0">
<input class="form-control mr-sm-2" type="text"
placeholder="Search"
aria-label="Search" role="search">
<button class="btn btn-outline-light my-2 my-sm-0"
type="submit">Search</button>
</form>
</div>
Navbar: Dropdown
And again go deeper into the dropdown detail in collapsible chunk.
<a href="#"
class="nav-link active dropdown-toggle"
data-bs-toggle="dropdown"
aria-expanded="false">
<span class="fa fa-link"></span>
Archives</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">
<span class="fa fa-tags"></span>
By Tags</a></li>
<li><a class="dropdown-item" href="#">
<span class="fa fa-folder"></span>
By Category</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">
<span class="fa fa-calendar"></span>
By Chronology</a></li>
</ul>
Stylesheet
The stylesheet res;onsible for logo in navigation bar can be found as below:
.navbar-brand img {
width: 32px;
height: 32px;
margin-top: -10px;
margin-bottom: -10px;
}
This will only give gaps, for mobile screen.
Now we are ready to focus on the responsive itself.
5: Responsive Maxwidth
I add a custom class named maxwidth
.
And, what is this maxwidth
class anyway ?
I have a smartphone, tablet, sometimes medium screen, and mostly I’m working with large screen. What is good for my regular screen, looks ugly in large screen. My solution is to create maxwidth, so my content would not be stretched horizontally.
Example Layout Page
Responsive Class
The responsive class for HTML document is similar as above:
<!-- responsive main -->
<div class="row layout-base maxwidth">
<main class="col-sm-8 p-4 bg-warning">
<header>
<h2>Your mission. Good Luck!</h2>
</header>
<article>
<ul class="list-group">
...
</ul>
</article>
</main>
<aside class="col-sm-4 p-4 bg-dark text-light">
Side Menu
</aside>
</div>
Container Class
Why not using Container Class?
Sometimes we can’t rely on bootstrap class.
For example container
is good for some case.
container
class has its own maximum width.
But it has margin issue with other case.
So we have to make our own maxwidth class.
Stylesheet
Add this rule below:
.maxwidth {
margin-right: 0;
margin-left: 0;
}
@media only screen and (min-width: 1200px) {
.maxwidth {
max-width: 1200px;
margin-right: auto;
margin-left: auto;
}
}
Remember that in this chapter, we haven’t access bootstrap variables yet. In the next chapter we are going to use responsive mixin.
@include media-breakpoint-up(xl) {
...
}
Blocks
Nunjucks Document Source
I need to show how this maxwidth
works with navbar and footer.
So the templates is completely different now.
{% extends './layouts/base.njk' %}
{% block htmlhead %}
{% include './heads/041-meta.njk' %}
{% include './heads/044-links.njk' %}
{% endblock %}
{% block header %}
{% include './shared/044-navbar.njk' %}
{% endblock %}
{% block content %}
{% include './contents/044-main.njk' %}
{% endblock %}
{% block footer %}
{% include './shared/044-footer.njk' %}
{% endblock %}
HTML Head
Assets: Resource Links
Since I utilize navbar, I also add icons as assets, such as FontAwesome.
<link rel="stylesheet" type="text/css"
href="assets/css/bootstrap.css">
<link rel="stylesheet" type="text/css"
href="assets/css/main.css">
<link rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.8.1/css/all.css"
integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
crossorigin="anonymous">
<script src="assets/js/popper.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
Header and Footer
The detail have already provided in previous section.
<!-- header -->
<nav class="navbar navbar-expand-sm navbar-dark
maxwidth fixed-top bg-dark">
<div class="container-fluid">
...
</div>
</nav>
<!-- footer -->
<footer class="footer">
<div class="maxwidth bg-dark text-light text-center">
© 2021.
</div>
</footer>
Static Page
HTML Document Target
The generated HTML result can be found here:
Browser Preview
Screenshot
For landscape mobile phone screen the result is similar to below figure:
For portrait mobile screen the result is similar to below figure:
Browser Preview: Maxwidth
Do not forget our focus, the maxwidth.
For large display, we limit the maximum width.
6: Default Gutter
Bootstrap has a default gutter, actually.
The issue is, you have to put the those element
inside a col class
.
Example Layout Page
Responsive Class
Here the responsive class for HTML document.
<!-- responsive main -->
<div class="row layout-base maxwidth">
<main class="col-sm-8">
<section class="p-4 bg-warning h-100">
<header>
<h2>Your mission. Good Luck!</h2>
</header>
<article>
<ul class="list-group">
...
</ul>
</article>
</section>
</main>
<aside class="col-sm-4">
<section class="p-4 bg-dark text-light h-100">
Side Menu
</section>
</aside>
</div>
Blocks
Nunjucks Document Source
{% extends './layouts/base.njk' %}
{% block htmlhead %}
{% include './heads/041-meta.njk' %}
{% include './heads/044-links.njk' %}
{% endblock %}
{% block header %}
{% include './shared/044-navbar.njk' %}
{% endblock %}
{% block content %}
{% include './contents/045-main.njk' %}
{% endblock %}
{% block footer %}
{% include './shared/044-footer.njk' %}
{% endblock %}
Static Page
HTML Document Target
The generated HTML result can be found here:
Browser Preview
Screenshot
For desktop screen the result is similar to below figure:
For mobile screen the result is similar to below figure:
We have the basic, so we can manually enhance later.
What is Next 🤔?
We are going to continue to enhance our responsive material. But before we do that, let me introduce you to some color palletes option available.
Consider continue reading [ Bootstrap - Sass - Color Pallete ].