CSS Tutorial – Build a landing page using just HTML and CSS featuring Flexbox and Grid.
Tags: css, tutorial, webdev, beginners
Published: 2021-09-02 20:28:08


In this tutorial, we are going to build a simple landing page for an online education platform called **Skilllz**.

![ezgif.com-gif-maker.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1630594529443/CAyP8xaQu.gif)

This tutorial will cover the usage and implementation of CSS Flexbox and CSS Grid alignment. Many other CSS concepts which will be covered as well.

The tutorial will be divided into three sections

- The Navigation Section
- The Showcase Section 
- and the Lower Section, 

All of which pertains to the three respective HTML sections that make up this project.

### Creating HTML boilerplate
If you have emmet installed inside of your IDE, you can generate a a HTML boilerplate for your project by typing `!` and clicking the `enter` or `tab` key on your keyboard. 

If not, you can copy this boilerplate code and paste it into your HTML file

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link rel="stylesheet" href="styles.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ=="
  crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
 
</body>
</html>
```

### Using Font Awesome Icons
As seen in one of the shots, we will be using some font icons to give better swap to our service section. For this, we will be using font awesome from the CDN. If you created a HTML biolerplate by yourself, copy the following link tag and paste it into your head tag

```html 
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ=="
  crossorigin="anonymous" referrerpolicy="no-referrer" />
```

### Getting Started
Ensure that your stylesheet file (.css) is properly linked to your HTML page. 

![test.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630594929098/f1wmeHd2u.png)

### SECTION ONE: The Navigation Area
The Navigation Bar section is going to be comprised of our site's name as well as two navigation links: `Log in` and `check courses`.

Here is the markup for our navbar:

```html
<div class="navbar">
        <div class="container flex">
          <h1 class="logo">Skilllz</h1>
            <nav>
              <ul>
                <li class="nav"><a class="outline" href="">Log in</a></li>
                <li class="nav"><a href="" class="outline">Check courses</a 				</li>
              </ul>
            </nav>
        </div>
      </div>
```

On the div wrapping the elements inside this section (the navbar), we register the `container` and `flex` class.

- `.container`: we will use this utility class on every section, to make sure the inner elements do not exceed a certain width which we specify in CSS

- `.flex`: we will use this utility class to display children elements in a horizontally aligned manner (side-by-side), using CSS flexbox.

Inside the `div` we have a `h1` with class of `logo` and two navigation links `li>a`  with the `outline` classes respectively.

Our page will look all plain and bare

![navbarHTML1.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630595276773/-EEGivFRh.png)

#### Applying CSS styling
We now have to apply some CSS rules to style our nav section to the way we want. What we want to first do is set the base styling for our web page:

```css
/* Overide default style and setting padding and margin to nothing */

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0
}

/* White text throughtout */

body {
  font-family: "lato", sans-serif;
  color: white;
}

/* Make all link texts black with no text decoration */
a {
  color: black;
  text-decoration: none;
}


h1 {
  font-size: 30px;
  font-weight: 600;
  margin: 10px 0;
  line-height: 1.2;
}


h2 {
  font-size: 25px;
  font-weight: 300;
  margin: 10px 0;
  line-height: 1.2;
}

p {
  font-size: 30px;
}

/* All images must not be larger than parent container */
img {
  width: 100%;
}

/* No styling on list items */
li {
  list-style-type: none;
}



p {
  font-size: 20px;
  margin: 10px 0;
}
```

With the default styles applied, our page will now look like this


![navbarHTML2.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630595599024/Jdo2NMJoWx.png)

Next, we need to define the styling for our container class 

```css
/* Centers it, sets a maximum width and make sure elements can flow past it*/

.container {
  margin: 0 auto;
  max-width: 1200px;
  overflow: visible;
}
```
Now, our content will not exceed the maximum width specified.

![navbarHTML3.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630595814313/hJyfKLGu_.png)

After that, we will need to set the background color of our navbar section to purple

```css
/* Sets background color, height and padding*/

.navbar {
  background-color: purple;
  height: 70px;
  padding: 0 30px;
}
```

![navbarHTML4.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630595978724/i34yJ6oqx.png)

Then we target only the h1 inside the navbar and specify the following styles

```css
/* Sets font size, reduces font-weight, adds margin and line height */

.navbar h1 {
  font-size: 30px;
  font-weight: 300;
  margin: 10px 0;
  line-height: 1.2;
}
```

With that style applied, our `h1` heading will look like this 


![navbarH5.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630596077400/KaV-ihM5C.png)

Now we need to display both children elements inside the container h1 and nav side-by-side, using Flexbox. 

```css
.navbar .flex {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 100%;
}
```

First, we set the display mode to flex. This will align the elements side by side by default. We then justify the content, adding a considerable space between them using space-between value. 

We align the items to appear at the center (middle) of the container and set its height to take up the entire container.

This is what our page should now look like

![navrbarH6.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630596208046/gpHYywdQm.png)

However, we also do not want both of our navigation link stacked on top of each other. Instead, we want them to be displayed side-by-side. Guess how we do that? With FlexBox!

```css
.navbar ul {
  display: flex;
}

/* Changes the color of both links to white, add padding between them and margin as well */

.navbar a {
  color: white;
  padding: 9px;
  margin: 0 10px;
}
```

Our page will now look like this

![navbarH7.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630596287006/LfW-VLkTL.png)


If you saw the brief intro video, you will notice that whenever I hover over any of the links, the text color changes to a lighter shade of purple and a solid border appears below it. We can implement this transition using the CSS :hover pseudoelement:

```css
.navbar a:hover {
  color: #9867C5;
  border-bottom: 3px solid #9867C5;
}
```

Now watch this

![ezgif.com-gif-maker (1).gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1630594419089/Vtsysb5k4.gif)

### SECTION TWO: The Showcase Area

The showcase area is going to house the headline text, supporting text, a form for signing up new users as well as a headline image. 

This section is going to be divided into two, the left side and the right side. In other words, it will be displayed as a grid of two units.

Here is the markup for this section

```html
<section class="showcase">
        <div class="container">
            <div class="grid">
              <div class="grid-item-1">
                <div class="showcase-text">
                  <h1>Learn any digital skill of your choice today</h1>
                  <p class="supporting-text"> Over 30,000 students currently learn with us</p>
                </div>
                <div class="showcase-form">
                  <form action="">
                    <input type="email" placeholder="Enter your email address">
                    <input type="submit" class="btn" value="Start Learning">
                  </form>
                  <p class="little-info">Try out our free courses today. No risk, no credit card required</p>
                </div>
              </div>

              <div class="grid-item-2">
                <div class="image">
                  <img src="./images/transparent.png" alt="">
                </div>
              </div>
           </div>

        </div>
      </section>
```

Currently, our app is going to look a bit messy

![showcaseH1.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630596573612/rcPWsUYDw.png)

### Applying CSS styling
First, we set the height of the showcase section as well as a background color

```css
.showcase {
  height: 300px;
  background-color: purple;
}
```

Our app will now look like this

![showcaseH2.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630596666208/RdgZmOjyH.png)

Next, we apply the following styles 

```css
/* Adds margin below the text */
.showcase p {
  margin-bottom: 30px;
}

/* Adds a shadow below the image */
.showcase img {
  box-shadow: 7px 7px 7px rgba(0, 0, 0, 0.2);
}

/* Adds some padding on the form content */
.showcase-form {
  padding-left: 7px;
}
```

This brings us to the main activity. If you remember, I have said that we are going to be creating two sections (grids) inside of the showcase container. With the grid class registered on that container, we can align its content using CSS grid display

```css
.grid {
  overflow: visible;
  display: grid;
  grid-template-columns: 60% 40%;
}
```

This will create two columns inside of our showcase container. The first part will take up 60 percent of the container and the second part will take up the remaining 40 percent of the container. The overflow visible will ensure that the image (if bigger than container) will flow beyond the container.

Our app will now look like this

![showcaseH3.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630596870076/JwP8tBGbQ.png)

Next, we need to set some space between the navigation area and showcase area

```css
.grid-item-1,
.grid-item-2 {
  position: relative;
  top: 50px;
}
```

As a result, it is now spaced out a bit

![showcaseH4.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630597026683/nVD4I0v3j.png)


Now, we need to style both of our form inputs because they don't look so nice. We select the first input by it's type (email) and select the second by its class name btn

```css
.showcase input[type='email'] {
  padding: 10px 70px 10px 0;
  font-size: 14px;
  border: none;
  border-radius: 6px;
  padding-left: 6px;
}

.btn {
  border-radius: 6px;
  padding: 12px 20px;
  background: #9867C5;
  border: none;
  margin-left: 10px;
  color: white;
  font-size: 16px;
  cursor: pointer;
  box-shadow: 0 10px 10px rgba(0, 0, 0, 0.2);
}
```

This style will transform both our form inputs to this


![showcaseH5.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630597140313/NI1Elml--.png)

Also maybe change the font of the supporting text

```css
.showcase-form {
  margin: auto;
}

/* Change typeface and its size */
.little-info {
  font-size: 15px;
  font-family: "poppins", sans-serif;

}
```

This is the final look of our showcase section


![showcaseH7.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630597217333/tNwQhYU0X.png)


That's it for this section!

### SECTION THREE: The Lower Area
The lower part of the page is going to contain two sections, the stats section and the testimonials section.

The stats container which displays the services offered by Skilllz will comprise of three `div`, each of which houses a font awesome icon, a `h3` of class `title` and a paragraph `p` of class `text`.

The testimonial container will hold the testimonials of three random people you learned using Skillz. I grabbed the pictures from unsplash.

#### The stats section
First, we are going to work on the stats area. The text is just a dummy 'lorem50' text to act as filler text.

Here is the markup for it

```html
<div class="lower-container container">
      <section class="stats">
        <div class="flex">
          <div class="stat">
            <i class="fa fa-folder-open fa-2x" aria-hidden="true"></i>
            <h3 class="title">Over 300 available courses</h3>
            <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
              Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
          </div>
          <div class="stat">
            <i class="fa fa-graduation-cap fa-2x" aria-hidden="true"></i>
            <h3 class="title">Free certificate offered on all courses</h3>
            <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
              Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
          </div>
          <div class="stat">
            <i class="fa fa-credit-card-alt fa-2x" aria-hidden="true"></i>
            <h3 class="title">Book 1on1 session for as low as $5</h3>
            <p class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
              Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
          </div>
        </div>
      </section>
```

This section will be displayed as a blank page. This is because we had set the color of our text in the whole body to white. So we have to begin styling.

#### Applying CSS Styling

First we need to apply the following styles

```css
/* Centers the container, sets a maximum width
.lower-container {
  margin: 120px auto;
  padding: 0;
  max-width: 1400px;
}


/* Targets all h3 with class of title */
.title {
  color: black;
  font-size: 20px;
  text-align: left;
  padding-left: 10px;
  padding-top: 10px;
}

/* Targets the paragraphs with class name of text */
.text {
  color: black;
  font-size: 19px;
  width: 100%;
  padding: 10px;
  margin: 0, 20px;
  text-align: justify;
}
```

This will now make our texts visible


![lower1.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630597454275/uFia5K0Ic.png)

Notice that the font icons from Font Awesome are not visible. We will be working on that pretty soon.

But before then, we will need to do something important. We do intend for all of the three stat div to be aligned horizontally (side-by-side). To achieve that, we will once again be using CSS flexbox

```css
/* Display horizontally, put a little space around them */
.flex {
  display: flex;
  justify-content: space-around;
}

/* Add some padding around the container. Align text centrally */
.stats {
  padding: 45px 50px;
  text-align: center;
}

/* Set margin and width */
.stat {
  margin: 0 30px;
  text-align: center;
  width: 800px;
}
```

This is how our app will now look like

![lower2.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630597579500/73HA5dRDu.png)

Still no icons? Time to fix that!

```css
.stats .fa {
  color: purple;
}
```
and voila!

![lower4.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630597601083/rUCYU2BBs.png)

### The testimonials section

The second section inside of the lower container div of the page is the testimonial section. This section is going to comprise of three cards, each of which contains the image of the person (clipped inside a circle), his/her name and the persons  testimonial.

Here is the markup for that

```html
<section class="testimonials">
      <div class="container">
        <div class="testimonial grid-3">
          <div class="card">
            <div class="circle">
              <img src="./images/4.jpg" alt="">
            </div>
            <h3>Aston</h3>
            <p>I have learnt web development using this platfrom and I am going to say this is the best platform for learning. Absolutely
            worth the investment!</p>
          </div>
          <div class="card">
            <div class="circle">
              <img src="./images/5.jpg" alt="">
            </div>
            <h3>Beth</h3>
            <p>I have learnt copywriting using this platfrom and I am going to say this is the best platform for learning. Absolutely
            worth the investment!</p>
          </div>
          <div class="card">
            <div class="circle">
              <img src="./images/6.jpg" alt="">
            </div>
            <h3>Chris</h3>
            <p>I have learnt affilitate marketing using this platfrom and I am going to say this is the best platform for learning. Absolutely
            worth the investment!</p>
          </div>
        </div>
      </div>
    </section>
```

#### Applying Styling to it
First, we set the text color to black so we can see it

```css
.testimonial {
  color: black;
  padding: 40px;
}
```

When applied, it should make the texts visible and add some padding to the section

![testi1.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630597841996/VeSGlvYWp.png)

Next, we set the image to take up the height of parent container

```css

/* Wrap the image inside a cirle shape and set height to take up all of parent element */

.testimonial img {
    height: 100%;
    clip-path: circle();
}

/* Align text centrally */

.testimonial h3{
  text-align: center;
}
```

If you checked the final layout in the gif, you will notice that all three testimonial cards are aligned side-by-side on the same line.

Hence, we will need to create a `div` of three equal columns using the CSS grid arrangement

```css
/* Create a grid of three equal columns. Set a gap of 40 px between them */

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 40px;
}


/* Create a white card with some shadow around it */
.card {
  padding: 10px;
  background-color: white;
  border-radius: 10px;
  box-shadow: -7px -7px 20px rgba(0, 0, 0, 0.2),
               7px  7px 20px rgba(0, 0, 0, 0.2)
}
```

With all of this styles applied, the testimonials section will now look like this

![testi2.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630598189933/LF1uYN89Q.png)

Finally, we style the circle div and postion it relatively to the top border of the card using CSS

```css
.circle {
    background-color: transparent;
    border:3px solid purple;
    height:90px;
    position: relative;
    top: -30px;
    left: 120px;
    border-radius:50%;
    -moz-border-radius:50%;
    -webkit-border-radius:50%;
    width:90px;
}
```

And here is how everything will look like on our browser


![testi4.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1630598299218/2fvuO131f.png)

### Wrapping Up
The FlexBox and Grid alignment are very powerful tools for laying out a web page however you want it to look.

In this tutorial, we have managed to design a simple landing page using CSS Flexbox, Grids as well as many other CSS properties. In my next tutorial, I will be making it more responsive using media queries.

The code for this whole project can be gotten from its [GitHub](https://github.com/KingsleyUbah/Skilllz) repository.

I hope you learned something useful from this tutorial. If you have any suggestions, reach out to me on [Twitter](https://twitter.com/ubahthebuilder).

Thanks for following along and see you soon.