How To Create A Responsive Navigation Bar With Flexbox And Media Queries
Tags: css, tutorial, beginners, todayilearned
Published: 2021-01-28 12:10:36

Hello Fellow Codenewbies 👋

We've learned about [Flexbox](https://dev.to/adiatiayu/a-dip-into-css-flexbox-22e6), [justify-content](https://dev.to/adiatiayu/css-flexbox-justify-content-2ljk), [align-items](https://dev.to/adiatiayu/css-flexbox-align-items-96k), [flex-direction](https://dev.to/adiatiayu/css-flexbox-flex-direction-415g) and [media queries](https://dev.to/adiatiayu/css-media-queries-15gg).
In this post, we will create a simple navbar with what we've learned so far.
We will work on the bigger screen and working our way down to the smaller screen sizes.


![big-screen.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611574013441/qn8ga1qeO.jpeg)
*Bigger screen (laptop, etc.)*


![smaller-screen.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611574026372/V9sHUqgfL.jpeg)
*Smaller screen (mobile, etc.)*

# The Navigation Bar (Navbar)

In our navbar, we will have a title (or a logo if you prefer) and a description.
We will also have an unordered list of the links to a few pages.

📝**Side note:**
Some developers use `<div>` as the container for the links, but it is still a common practice to use `<ul>` for semantic and accessibility purposes because links in navbar **are** an *unordered* list.

## Create The HTML

Following the semantic rule, let's create a `<header>` since our navbar is the header of the page.
Inside our `<header>`, we will have an `<h1>` (or `<img>` for a logo) and a `<p>` with a class of "subtitle" for the description of the site.
We will also want to have a `<nav>` with `<ul>` and some `<li>`s with `<a>` for the links to our pages.
As we don't need to refer the link to anywhere else, for now, we put `#` in the `href`.


```html
<header>
    <h1>Sophisticated Navbar</h1>
    <p class="subtitle">Navbar Demo With Flexbox & Media Queries</p>
    <nav>
      <ul>
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact Me</a></li>
      </ul>
    </nav>
</header>
``` 

![1.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611359401668/mKq4BXcek.jpeg)

Great!
It doesn't look good so far, but we will style it soon 😊

## Prepare The HTML For Styling

First of all, for the sake of the styling, we will wrap the `<header>` and everything inside it in a `<div>` and give class of `container` and `container-nav`.

📝 **Side note**
It is a common practice to create multiple classes to an element when we intend to reuse it for the same styling in other places.
For example, when we want to apply the more generic style that we set in `.container` to a `<header>` and a `<section>`, and/or any other elements.
But in this tutorial, we will not reuse it. I just want to give you a sense of what is the common practice in the real world.

We want to make the `<h1>` and the `<p>` be side by side with the `<nav>`.
Therefore, we want to wrap them in a `<div>` and give it class of "titles".
We are grouping them for styling purposes later on.


```html
<header>
  <div class="container container-nav">
    <div class="titles">
      <h1>Sophisticated Navbar</h1>
      <p class="subtitle">Navbar Demo With Flexbox & Media Queries</p>
    </div>
    <nav>
      <ul>
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact Me</a></li>
      </ul>
    </nav>
  </div>
</header>
``` 

## Start Styling With CSS

I'm using *Caveat* and *VT323* fonts from [Google Fonts](https://fonts.google.com/). Feel free to use any type of fonts of your choice.

## Styling The `<body>`

What we are doing here:
- Give it a background color.
- Overwrite the default margin from browsers by setting the `margin` to `0`.
- Use the same font type for `.subtitle` and `<nav>`.

    So we will declare the default font in the `<body>`. I am using the *VT323* as the default font.


```css
body {
  background-color: #719fb0;
  font-family: "VT323", monospace;
  margin: 0;
}
``` 

![body.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611577392254/3ePjMRhuJ.jpeg)


## Styling The Typography

What we are doing here:

- Set the *Caveat* font to `<h1>` to overwrite the default font. 
- Give `margin: 0;` to `<h1>` to get rid of the default margin that comes with it.
- Set `color` and `font-size` for the `<h1>`, `.subtitle` and `nav a`.
- Apply `text-transform: uppercase;` to the `.subtitle` and `nav a `.

```css
h1 {
  font-family: "Caveat", cursive;
  font-size: 2.5rem;
  color: #fd5f00;
  margin: 0;
}

.subtitle,
nav a {
  font-size: 1.5rem;
  color: #f9f8eb;
  text-transform: uppercase;
}
``` 


![typography-style.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611574239901/wnBhK_uGp.jpeg)

## Styling The Layout

### The `.container`

What we are going to do here:

- Set `width: 90%;` to give some space on the left and right sides.
- Set `max-width: 900px;`. 

    *Setting the `max-width` to an element will prevent it to get bigger than the value stated when we expand the window or view the page on a bigger screen*.
- Give `margin:  0 auto;` to center the `.container`.

```css
.container {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
}
```

![container.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611575124318/pk80HU6wz.jpeg)

📝**Author's note:**
I'm giving a border to some elements to give a clearer view of how things working and look like.

### The `.container-nav`

For bigger screen sizes, we would like to have the `.titles` be in line with the `<nav>` and we will do this with Flexbox in `.container-nav`.
This way, we can reuse the `.container` - as the more generic style - when we need it in the future.

What we are going to do here:
- Apply `display: flex;`.

    It will bring the `<nav>` to the top and in line with the `.titles`.
- Set `justify-content: space-between;` to give space between the `.titles` and the `<nav>`.

    *This is the reason why we wrap the `<h1>` and the `.subtitle` in a `<div>`. Now we can apply the `space-between` to give space and split our `.titles` and `<nav>` as groups*.
- Set `align-items: center` to center both `.titles` and `<nav>` vertically.

```css
.container-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
``` 

![container-nav.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611580154729/pYtGHmKPc.jpeg)


### The `<header>`

What we are going to do here:
- Give it a background color.
- Give padding to the top and bottom, to give some space.
- Apply `box-shadow`, just for some aesthetic purpose.

  ```css
header {
  background-color: #05004e;
  padding: 0.8em 0;
  box-shadow: 2px 2px 10px #f1f6f9;
}
  ``` 
![header-styling.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611664818364/I-DJEd9kd.jpeg)


### Styling The Navbar

### The `nav ul`

Now we will style all `<ul>` inside our `<nav>`.
What we are going to do here:
- Set `list-style` to `none`, to get rid of the bullets.
- Apply `display: flex;` to make the flex items inline.
![style-nav-ul.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611665752648/SJX0Gfg3Q.jpeg)

- Apply `padding: 0;` to get rid of the padding that comes as default.

   ```css
nav ul {
  list-style: none;
  padding: 0;
  display: flex;
}
   ``` 
![apply-padding-nav-ul.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611665922450/9WV9m5Vra.jpeg)

### The  `nav li`

What we are going to do here:
- Apply `margin-left: 2em;` to give space between the `<li>`s.

   ```css
nav li {
  margin-left: 2em;
}
   ``` 

  Now, if we shrink the size, we can see that all `<li>` have space and the first `<li>` is not touching the `.titles`.
  ![style-nav-li.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611666295041/bJ40Pd_Z4.jpeg)

### The `nav a`

What we are going to do here:
- Set `text-decoration` to `none`, to get rid of the link's underline.

We will also:
- Change the color for the link when we hover over them, and when they are on the focus state.

```css
nav a {
  text-decoration: none;
}

nav a:hover,
nav a:focus {
  color: #fd5f00;
}
``` 

![style-nav-a.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611666827862/uKC-z6LC9.jpeg)

This all looks good so far.
Next, we will apply media queries to make our navbar responsive 😊

## Make The Navbar Responsive With Media Queries

We will set the `max-width` of `640px` for all type of media.
This means that all styles in the media queries will be applied from smaller sizes until the maximum width of 640px. Above that width, the initial style will be applied.

What we are going to do in the media queries:
- Center the texts inside `.container`, so when we shrink the page, we will have all texts centered.
![12.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611668352310/5pMtijI-n.jpeg)

- Apply `flex-direction: column;` to the `.container-nav`.

    This will change the direction of the main axis, stack our `.titles` and `<nav>` as a column.
![flex-direction-container-nav.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611668410056/m36eA0-9a.jpeg)

- Apply `flex-direction: column;` to the `nav ul`.
![flex-direction-nav-ul.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611668723718/Bm89RZnFk.jpeg)
    Pay attention to the `<li>`s. They are all go a little bit to the right side. 
    This is because previously we set `margin-left` of `2em` to our `nav li`.
    We will fix this with the next step.

- Set `0.8em` margin-top and -bottom to the `nav li` and `0` margin-left and -right to reset the margin that we set before.

```
@media (max-width: 640px) {
  .container {
    text-align: center;
  }

  .container-nav {
    flex-direction: column;
  }

  nav ul {
    flex-direction: column;
  }
  
  nav li {
    margin: 0.8em 0;
  }
}
```
![apply-media-queries.jpg](https://cdn.hashnode.com/res/hashnode/image/upload/v1611673793980/E_qsWjBwQ.jpeg)

## Closing

And that's it!
Our simple navbar with Flexbox and media queries.
I provide [here](https://codepen.io/adiati/pen/eYdoNxg) the Codepen playground for you to play around.
I hope you enjoy the article and can learn something from it 😊