# How to Build a Landing Page Template With Bootstrap 4

In this tutorial we’ll continue our tour of Bootstrap 4. More specifically, we’ll learn how to use it to build a responsive landing page.

## What We’ll be Working Towards

Before starting, as always, let’s take a quick look at our demo project:

Be sure to check the full screen version and resize your browser window to see how its layout changes depending on the viewport size.

Note: This tutorial assumes you have some familiarity with Bootstrap 4. For example, you should understand how its grid system and flex component work. In addition, a good understanding of its responsive breakpoints will be serve you well.

To help you get up to speed, here at Tuts+ we have a number of courses focusing on Bootstrap 4.

### The Assets

We’ll be using a few assets in this project, here’s where you’ll find them:

• For the icons used in this demo, I’ve incorporated the Font Awesome library into our pen.
• All images come from Unsplash.

## 1. Set Out the Markup

Let’s begin! We do so with typical page markup; a header, a footer, and five sections:

 1 
...
 2 
 3   4 
...
 5   6 
...
 7   8 
...
 9   10 
...
 11   12 
...
 13 
 14 
...


## 2. Define Some Basic Styles

Before having a closer look at the individual parts of our page, let’s first define some CSS styles. These are mostly reset rules along with a few helper classes which we’ll append to the target elements later on:

 1 :root {  2  --lightblue: #F6F9FC;  3  --red: #d64041;  4 }  5 6 a,  7 a:hover {  8  color: inherit;  9 }  10 11 a:hover {  12  text-decoration: none;  13 }  14 15 .bg-lightblue {  16  background: var(--lightblue);  17 }  18 19 .bg-red {  20  background: var(--red);  21 }  22 23 .text-red {  24  color: var(--red);  25 }  26 27 .container-fluid-max {  28  max-width: 1440px;  29 }  30 31 .cover {  32  background: no-repeat center/cover;  33 }  34 35 .p-15 {  36  padding: 15px;  37 } 

Note: we’ll try to keep our CSS as lightweight as possible and take advantage of Bootstrap 4’s built-in classes.

• The logo
• The contact info

Using Bootstrap’s defined breakpoints, on extra large screens it should look like this:

On large screens, like this:

On smaller screens it will have a slightly different appearance:

To build the header markup, we’ll take advantage of the navbar component that Bootstrap provides.

Here’s what that looks like:

 1  

By default, only the mobile header (off-canvas menu) will have a background color.

However, in an upcoming section, we’ll discuss how to add a background color to the desktop header whenever the page is scrolled.

 1 .scroll .page-header {  2  background: var(--red);  3 }  4 5 .page-header {  6  transition: background 0.5s ease-in-out;  7 }  8 9 .page-header .navbar {  10  padding: 1rem 0;  11 }  12 13 .page-header .navbar-toggler {  14  border-color: var(--white);  15 }  16 17 @media screen and (max-width: 991px) {  18  .page-header {  19  background: var(--red);  20  }  21 } 

## 4. Build the Hero Section

The first section of our page includes:

• A full-screen background image
• A heading and two call-to-action buttons which are vertically centered over that image.

Here’s what it looks like:

### Section #1 HTML

 1 
 2 
 3 
 4 
 5 

...

 6 
 7  ...  8  ...  9 
 10 
 11 
 12 
 13 


### Section #1 CSS

For readability reasons, we’ll create an overlay on top of the background. We’ll then ensure that the text is placed over that overlay.

Similarly to the header, later we’ll discuss how to scale this section, each time the page is scrolled.

 1 .scroll .hero {  2  transform: scale(0.98);  3 }  4 5 .hero {  6  background-attachment: fixed;  7  transition: transform 0.5s ease-in-out;  8 }  9 10 .hero::after {  11  content: '';  12  position: absolute;  13  top: 0;  14  right: 0;  15  bottom: 0;  16  left: 0;  17  background: linear-gradient(  18  rgba(0, 0, 0, 0.5) 0,  19  rgba(0, 0, 0, 0.3) 50%,  20  rgba(0, 0, 0, 0.1) 100%  21  );  22 }  23 24 .hero .container-fluid {  25  z-index: 10;  26 } 

## 5. Build the Overview Section

The second section of our page includes some details which provide a quick overview once our visitors have absorbed the hero:

• Four text blocks with their icons
• A call-to-action button

On large screens and above, it should look like this:

On small and medium screens, like this:

Finally on extra small screens, all columns are stacked:

### Section #2 HTML

 1 
 2 
 3 
 4 
 5 

...

 6 
 7 
...
 8 
...
 9 
...
 10 
...
 11 
 12  ...  13 
 14 
 15 
 16 


### Stacking Icons

To stack multiple icons in our columns, we’ll take advantage of the styles bundled with Font Awesome. This will allow us to stack a white icon on top of a colored circle icon.

For example, below you can see the markup used for the first column. The two <i> elements are inline, next to one another, but with the fa-stack classes they become stacked.

 1 
 2   3   4   5   6 

...

 7 

...

 8 


## 6. Build the Split Blocks Section

The third section of our page includes two full-screen rows. Each row is split, containing an image column and a text column. The contents inside the text columns have to be vertically centered.

On medium screens and above, the section layout will look like this:

On narrow screens, they should be as follows:

### Section #3 HTML

You’ll notice the order of the blocks above. On narrow screens the text and image blocks must alternate; image, text, image, text. This wouldn’t happen without the flexbox order- classes you’ll see used below:

 1  

## 7. Build the Image Gallery Section

The fourth section of our page includes:

• Five image columns along with their description
• A call-to-action button

On medium screens and above, it’ll look like this:

On small screens, the layout changes as follows:

On extra small screens, all image columns are stacked:

### Section #4 HTML

 1  

The markup responsible for setting the columns’ content looks like this:

### Section #4 CSS

Initially all images are blurry and grayscale. Each time we hover over an image, the image scales and its default filters are removed.

These are the styles to achieve that:

 1 .popular-destinations figure {  2  margin-bottom: 30px;  3 }  4 5 .popular-destinations figcaption {  6  top: 0;  7  right: 0;  8  bottom: 0;  9  left: 0;  10  background: rgba(0, 0, 0, 0.3);  11 }  12 13 .popular-destinations img {  14  filter: grayscale(100%) blur(3px);  15  transition: transform 0.5s, filter 0.75s;  16 }  17 18 .popular-destinations a:hover img {  19  transform: scale(1.25);  20  filter: none;  21 } 

## 8. Build the Call to Action Section

The fifth section of our page includes:

• A text block
• A call-to-action button

Calls to action are vital on landing pages as they encourage visitors to do something instead of leaving. The pointing icon we’ve used makes the CTA particularly compelling. On medium screens and above, its appearance looks as follows:

On smaller screens though, all elements are stacked:

### Section #5 HTML

 1 
 2 
 3 
 4 
 5 

...

 6 

...

 7 
 8   14 
 15 
 16 


## 9. Build the Footer

We’ve reached the end of our landing page template! The page footer includes:

• An element with copyright information
• An element with links to different pages

On medium screens and above, it should look like this:

On smaller screens, the layout changes as follows:

### Footer HTML

 1 
 2 
 3 
 4   5   12 
 13 
 14 


### Footer CSS

The alignment of the footer links will change depending on the viewport size. Here are the rules determining that behavior:

 1 .page-footer .footer-links {  2  text-align: right;  3 }  4 5 @media screen and (max-width: 767px) {  6  .page-footer .footer-child {  7  text-align: center;  8  }  9 } 

At this point, let’s have a look at our page:

## 10. Add Some JavaScript Actions

It’s time now to write some JavaScript that will enhance the experience of our page.

### On Scroll Animations

When the page is scrolled, the body element should receive the scroll class. This class will be responsible for the following things:

• Adding a background color to the header. Note that behavior should happen only on medium screens and above. Remember we’ve already set a background color for the mobile menu.
• Scaling the first section.

Let’s quickly revisit the corresponding styles:

 1 .scroll .page-header {  2  background: var(--red);  3 }  4 5 .scroll .hero {  6  transform: scale(0.98);  7 }  8 9 .page-header {  10  transition: background 0.5s ease-in-out;  11 }  12 13 .hero {  14  transition: transform 0.5s ease-in-out;  15 }  16 17 @media screen and (max-width: 991px) {  18  .page-header {  19  background: var(--red);  20  }  21 } 

And here is the required JavaScript code:

 1 const $body =$("body");  2 const $header =$(".page-header");  3 const scrollClass = "scroll";  4 5 $(window).on("scroll", () => {  6  if (this.matchMedia("(min-width: 992px)").matches) {  7  const scrollY =$(this).scrollTop();  8  scrollY > 0  9  ? $body.addClass(scrollClass)  10  :$body.removeClass(scrollClass);  11  } else {  12  $body.removeClass(scrollClass);  13  }  14 });  ### Firing Bootstrap’s Scrollspy As a next step we want to automatically update the active menu link depending on the scroll position. To do this, we’ll take advantage of Bootstrap’s Scrollspy plugin. Following the documentation, to trigger scrollspy behavior to the navigation items, we’ll have to adjust the body element. More specifically: • Give it position:relative • Add data-spy="scroll" • Add data-target="#navbar" where #navbar is the ID of our navbar element. Inside that element there are the menu links that should receive Scrollspy’s active class. • Add data-offset="72" where 72 is the height of the desktop header as well as the height of the mobile header when the menu is closed. This option determines the menu link that will become active as soon as its corresponding section is 72 pixels from the top of the viewport. Here are the required page structure changes:  1   2  ...  3   6  ...  7   One thing to note is that things becomes tricky when responsive offsets are required. That said, when the header has a different height depending on the screen (due to the font sizing). In such a case, giving a static value to the data-offset attribute won’t work and initializing the plugin through JavaScript (along with some custom code) is the only choice. Saying that, this is beyond the scope of our tutorial at this point. ### Add Smooth Scrolling to Logo & Menu Links Lastly, each time we click on the logo or a menu link, the browser should smoothly scroll to the appropriate section. Thanks to jQuery’s animate method, we’re able to easily achieve this functionality. Here’s the required JavaScript code:  1 $(".page-header .nav-link, .navbar-brand").on("click", function(e) {  2  e.preventDefault();  3  const href = $(this).attr("href");  4 $("html, body").animate({  5  scrollTop: \$(href).offset().top - 71  6  }, 600);  7 }); 

Notice the number 71 inside the code. This number is derived by subtracting 1 from 72 (remember that’s the header height).

My initial attempt was to put the number 72 inside the code above. However, I encountered a problem in a few browsers (e.g. Firefox–Chrome worked though). Specifically, each time a header menu link was clicked, that link didn’t immediately receive the expected active class (which comes from the Scrollspy component). That worked as soon as I scrolled down around one pixel. With that in mind, a simple fix was just to decrease the initial number by one.

## Conclusion

That’s all folks! This has been a long journey, but hopefully you will have found it worth the effort. I really hope this exercise gave you enough knowledge and inspiration for building awesome landing pages with Bootstrap 4. Don’t forget to check the full screen version and make sure it matches your work.

With regards to this demo, a next step might be to make it dynamic by connecting it to a server-side language. For example, it would be great to build a WordPress theme based on this layout.