Where to Discuss?

Local Group

Preface

Step One: Using Bootstrap for the first time

From HTML5 without any stylesheet. We can add CSS framework. And try cool bootstrap components.


1: Chapter Overview

Consider examine the directory structure.

Source Code: Step-01

The source code for this chapter is, available for download at the following link:

Bootstrap v4

The obsolete Bootstrap v4 article series is also available.

General Preview

This below is general preview of, what page that we want to achieve.

Bootstrap5: General Preview of Simple Page Layout

Plain HTML

Compiled HTML Document

The outputs, will be generated as below:

❯ ls -1 *.html
012-head-cdn.html
013-head-local.html
015-navbar.html

Bootstrap5: Directory Structure: Compiled

We have three document to examine.

Assets

CSS and Javascript

We are going to use some assets. Official style and javascript from bootstraps. And also custom css.

❯ tree -C css js
css
├── bootstrap.css
├── main.css
└── sticky-footer.css
js
└── bootstrap.min.js

2 directories, 4 files

Bootstrap5: Directory Structure: Assets

Templates

Nunjucks

More document, means more templates. But don’t worry, I made reusable templates. So we don’t need to repeat ourselves.

❯ tree -C views
views
├── 012-head-cdn.njk
├── 013-head-local.njk
├── 015-navbar.njk
├── contents
│   ├── 011-main.njk
│   └── 015-main.njk
├── heads
│   ├── 011-meta.njk
│   ├── 012-links.njk
│   ├── 013-links.njk
│   └── 015-links.njk
├── layouts
│   ├── 011-base.njk
│   └── 015-base.njk
└── shared
    ├── 011-footer.njk
    ├── 011-header.njk
    ├── 015-footer.njk
    └── 015-header.njk

5 directories, 15 files

Bootstrap5: Directory Structure: Templates

We can now start coding the HTML documents.


2: Loading Assets

There are some alternative to load CSS.

For this tutorial. I suggest to use local CSS. Because we are going to make a custom Bootstrap CSS

Using CDN Bootstrap Assets

It is as simple as

  <link rel="stylesheet"
    href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" 
    integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" 
    crossorigin="anonymous">

And if you need the javascript, you can add:

  <script
    src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
    crossorigin="anonymous"></script>

The sample code is here:

Bootstrap5: Nunjucks: Assets: CDN

Using Local Bootstrap Assets

You need to download bootstrap.css, and also bootstrap.min.js from the official site. And put the artefact to css and js directory.

  <link rel="stylesheet"
    type="text/css" href="./css/bootstrap.css">
  <script src="./js/bootstrap.min.js"></script>

Bootstrap5: Nunjucks: Assets: Local

Some bootstrap functionality required javascript.

Adding Meta

As the official guidance said. We have to add a few meta tags on the head.

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,
    initial-scale=1, shrink-to-fit=no">
  <title>Your mission. Good Luck!</title>

Bootstrap5: Nunjucks: Heads: Meta

HTML Head

We have already shown the HTML chunks above.

  • 011-meta.njk
  • 012-links.njk
  • 013-links.njk

We are going to use these chunks in the next section.


3: CDN and Local Templates

Consider build the HTML document right away.

Templates

The specific templates that we need for bootstrap using CDN are shown below:

views
├── 012-head-cdn.njk
└── heads
    ├── 011-meta.njk
    └── 012-links.njk

The specific templates that we need for bootstrap using local assets are shown below:

views
├── 013-head-local.njk
└── heads
    ├── 011-meta.njk
    └── 013-links.njk

Since we have similar part for 012 and 013 document, all part other than assets links is considered reusable chunks. I use 011 number for reusable chunks.

views
├── contents
│   └── 011-main.njk
├── layouts
│   └── 011-base.njk
└── shared
    ├── 011-footer.njk
    └── 011-header.njk

Layout

Reusable Parent Template

This is the skeleton for of the building block. The template itself is rather a reusable template.

<!DOCTYPE html>
<html>

<head>
  {% block htmlhead %}{% endblock %}
</head>

<body>
  <div class="container">
    {% block header %}{% endblock %}
    {% block content %}{% endblock %}
    {% block footer %}{% endblock %}
  </div>
</body>

</html>

Bootstrap5: Nunjucks: Base Layout: Parent Template

Blocks: for CDN

Nunjucks Document Source

We can put different chunk for each block.

{% extends './layouts/011-base.njk' %}

{% block htmlhead %}
  {% include './heads/011-meta.njk' %}
  {% include './heads/012-links.njk' %}
{% endblock %}

{% block header %}
  {% include './shared/011-header.njk' %}
{% endblock %}

{% block content %}
  {% include './contents/011-main.njk' %}
{% endblock %}

{% block footer %}
  {% include './shared/011-footer.njk' %}
{% endblock %}

Bootstrap5: Nunjucks: Source: CDN

Blocks: for Local

Nunjucks Document Source

The only difference with the CDN document is the HTML assets.

{% extends './layouts/011-base.njk' %}

{% block htmlhead %}
  {% include './heads/011-meta.njk' %}
  {% include './heads/013-links.njk' %}
{% endblock %}

{% block header %}
  {% include './shared/011-header.njk' %}
{% endblock %}

{% block content %}
  {% include './contents/011-main.njk' %}
{% endblock %}

{% block footer %}
  {% include './shared/011-footer.njk' %}
{% endblock %}

Bootstrap5: Nunjucks: Source: Local

Of course we can optimize this repetition using nunjucks variable. But I leave this this way, I do not want to go deep into Nunjucks,' and forget the bootstrap stuff.


4: Reusable Templates

For both HTML target: CDN and Local.

Overview

Beside the layout, we have this common templates.

views
├── contents
│   └── 011-main.njk
├── heads
│   └── 011-meta.njk
└── shared
    ├── 011-footer.njk
    └── 011-header.njk

Bootstrap5: Nunjucks: Pane Summary

Consider examine one by one.

Main

Content

Now consider having fun for while. And give more example class, and see what happened.

    <!-- main -->
    <ul class="list-group">
      <li class="list-group-item">
      To have, to hold, to love,
      cherish, honor, and protect?</li>

      <li class="list-group-item">
      To shield from terrors known and unknown?
      To lie, to deceive?</li>

      <li class="list-group-item">
      To live a double life,
      to fail to prevent her abduction,
      erase her identity, 
      force her into hiding,
      take away all she has known.</li>
    </ul>

List Group

We need to see if Bootstrap class work correctly. Consider add this container and list-group class.

Bootstrap5: Nunjucks: Content: Main

Header

Just a simple header.

    <!-- header -->
    <p><i>Your mission,
        should you decide to accept it.</i></p>
    <br/>

Bootstrap5: Nunjucks: Shared: Header

Footer

And another simple footer.

    <!-- footer -->
    <br/>
    <p><i>As always, should you
        be caught or killed,
        any knowledge of your actions
        will be disavowed.</i></p>

Bootstrap5: Nunjucks: Shared: Footer

HTML Preview: CDN

HTML Document Target

Hve a look at the result by opening the file in Browser.

Bootstrap5: Qutebrowser: CDN

And also the HTML source.

Bootstrap5: Qutebrowser: CDN: Source

HTML Preview: Local

HTML Document Target

The local output in browser is exactly the same. The only different is the head part of the source.

Bootstrap5: Qutebrowser: Local

There is more fun than just this. We are going to explore later.


5: Bootstrap: Navbar Class

As the site grows…

Let’s try something else, that is not too simple.

For the rest of this show case, I’m using both navbar header and footer.

Overview

Beside the layout, we have this common templates.

views
├── contents
│   ├── 015-main.njk
│   └── 015-links.njk
├── heads
│   └── 015-meta.njk
└── shared
    ├── 015-footer.njk
    └── 015-header.njk

Bootstrap5: Nunjucks: Pane Summary

Consider examine one by one.

As Header

Navbar lies on header part.

  <!-- header -->
  <nav class="navbar navbar-expand-md
      navbar-dark bg-dark">
    <div class="navbar-collapse">
      <ul class="navbar-nav mx-2">
        <li class="nav-item">
          <a class="nav-link active"
             href="#">Home
            <span class="visually-hidden"
            >(current)</span></a>
        </li>
      </ul>
    </div>
  </nav>

Bootstrap5: Nunjucks: Shared: Header

Navbar also lies on footer part.

  <!-- footer -->
  <footer class="footer">
    <div class="bg-dark text-light text-center">
      &copy; 2021.
    </div>
  </footer>

Bootstrap5: Nunjucks: Shared: Footer

Assets

Additional CSS

We need a little tweak To have proper layout, this navbar require additional CSS.

❯ tree -C css js
css
├── main.css
└── sticky-footer.css
.layout-base {
  padding-top: 3rem;
  padding-bottom: 2rem;
}

Bootstrap5: Assets: CSS: Main

And for the sticky footer. I grab from the official site.

html {
  position: relative;
  min-height: 100%;
}
body {
  margin-bottom: 60px; /* Margin bottom by footer height */
}
.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 60px; /* Set the fixed height of the footer here */
  line-height: 60px; /* Vertically center the text there */
  background-color: #f5f5f5;
}

Bootstrap5: Assets: CSS: Sticky

HTML Head

You should define styles on <head> element. We will do it in templates.

  <link rel="stylesheet"
    type="text/css" href="./css/bootstrap.css">
  <link rel="stylesheet"
    type="text/css" href="./css/main.css">
  <link rel="stylesheet"
    type="text/css" href="./css/sticky-footer.css">

Bootstrap5: Nunjucks: Heads: Links

Templates

Nunjucks

No reusable templates here, except the HTML head meta.

views
├── 015-navbar.njk
├── contents
│   └── 015-main.njk
├── heads
│   ├── 011-meta.njk
│   └── 015-links.njk
├── layouts
│   └── 015-base.njk
└── shared
    ├── 015-footer.njk
    └── 015-header.njk

5 directories, 15 files

Layout

Consider change the layout into simpler HTML tags as below:

<!DOCTYPE html>
<html>

<head>
  {% block htmlhead %}{% endblock %}
</head>

<body>
  {% block header %}{% endblock %}
  {% block content %}{% endblock %}
  {% block footer %}{% endblock %}
</body>

</html>

Bootstrap5: Nunjucks: Layout: Base

Blocks

Nunjucks Document Source

Well… pretty similar with the tree above right?

{% extends './layouts/015-base.njk' %}

{% block htmlhead %}
  {% include './heads/011-meta.njk' %}
  {% include './heads/015-links.njk' %}
{% endblock %}

{% block header %}
  {% include './shared/015-header.njk' %}
{% endblock %}

{% block content %}
  {% include './contents/015-main.njk' %}
{% endblock %}

{% block footer %}
  {% include './shared/015-footer.njk' %}
{% endblock %}

Bootstrap5: Nunjucks: Blocks: Navbar

Main

It is almost the same with previous, except the additional custom CSS class the layout-base.

  <!-- main -->
  <div class="layout-base">
    <main role="main" class="container">
      <ul class="list-group">
        <li class="list-group-item">
        To have, to hold, to love,
        cherish, honor, and protect?</li>

        <li class="list-group-item">
        To shield from terrors known and unknown?
        To lie, to deceive?</li>

        <li class="list-group-item">
        To live a double life,
        to fail to prevent her abduction,
        erase her identity, 
        force her into hiding,
        take away all she has known.</li>
      </ul>
    </main>
  </div>

Bootstrap5: Nunjucks: Contents: Main

Browser Preview

Screenshot

And have fun with the result. Consider open the file in Browser.

Bootstrap5: Qutebrowser: Minimal Navigation Bar

Static Page

HTML Document Target

As a summary from this chapter, all the html element is as shown below.

Consider examine the HTML output, above.


What is Next 🤔?

Thank you for reading. I know it still feels like a template tutorial, than stylesheet one. That is why we have to go on. There are, some interesting topic about Navigation Bar in Bootstrap 5.

Consider continue reading [ Bootstrap5 - Navigation Bar - Class ].