How To Create A Responsive Navigation Bar With Flexbox And Media Queries

Subscribe to my newsletter and never miss my upcoming articles

Hello Fellow Codenewbies 👋

We've learned about Flexbox, justify-content, align-items, flex-direction and media queries.
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 Bigger screen (laptop, etc.)

smaller-screen.jpg 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.

<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

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.

<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. 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.
body {
  background-color: #719fb0;
  font-family: "VT323", monospace;
  margin: 0;
}

body.jpg

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.
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

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.
.container {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
}

container.jpg

📝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.
.container-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

container-nav.jpg

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.

    header {
    background-color: #05004e;
    padding: 0.8em 0;
    box-shadow: 2px 2px 10px #f1f6f9;
    }
    

    header-styling.jpg

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

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

    nav ul {
    list-style: none;
    padding: 0;
    display: flex;
    }
    

    apply-padding-nav-ul.jpg

The nav li

What we are going to do here:

  • Apply margin-left: 2em; to give space between the <li>s.

    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

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.
nav a {
  text-decoration: none;
}

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

style-nav-a.jpg

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

  • 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

  • Apply flex-direction: column; to the nav ul. flex-direction-nav-ul.jpg 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

Closing

And that's it!
Our simple navbar with Flexbox and media queries.
I provide here the Codepen playground for you to play around.
I hope you enjoy the article and can learn something from it 😊

Comments (2)

Devalla Sai Charan's photo

Really helpful content. Thanks for sharing.

Ayu Adiati's photo

Thank you, Devalla! 😊 I'm glad if it helps 😃