Simple Horizontal Navigation

Note: This post was originally written 3+ years ago and in web development years, that is an eternity. I have redone the snippet to use better CSS.

In this tutorial I explore two different methods for making the navigation horizontal on large screens. The snippet is responsive. It will create a vertical menu on smaller screens and a horizontal menu on larger screens.

See the Pen Simple Responsive Horizontal Navigation by Lisa (@lisa_c) on CodePen.

Preferred Learning Method?

Code Snippets
If you just want the code and don’t need a description.

Watching a Video
If you like being shown how something works with some explanation watch the video.

Reading a description
If you learn better by reading, I am including the transcript of the video with corresponding code snippets embedded.

Code Only

See the Pen Simple Responsive Horizontal Navigation by Lisa (@lisa_c) on CodePen.

See the Pen Simple Responsive Horizontal Navigation by Lisa (@lisa_c) on CodePen.



Let’s start with the HTML. I have a simple un-ordered list of links. Each list item has a class name related to its name.

    <div class="nav">
        <li class="home"><a href="#">Home</a></li>
        <li class="tutorials"><a href="#">Tutorials</a></li>
        <li class="about"><a href="#">About</a></li>
        <li class="news"><a href="#">Newsletter</a></li>
        <li class="contact"><a href="#">Contact</a></li>

I’ll use a mobile-first approach and start styling this list as a vertical navigation so it will look good on phones and smaller tablets.

I’m clearing out margin and padding and giving a background color to the body first.

    body {
      margin: 0;
      padding: 0;
      background: #ccc;

Next I’ll style the list to remove the bullets and give it a background color. I want the text centered. It doesn’t look perfectly centered yet, but if I remove padding it will. Clearing the margin will make it hug the top of the page which I want.

I am targeting ul inside of .nav because I would probably want different styling on non-navigational unordered lists.

    .nav ul {
      list-style: none;
      background-color: #444;
      text-align: center;
      padding: 0;
      margin: 0;

On the list items inside of nav (.nav li) I will set the typography.

    .nav li {
      font-family: 'Oswald', sans-serif;
      font-size: 1.2em;
      line-height: 40px;
      height: 40px;
      border-bottom: 1px solid #888;

I’m setting the line-height and height both to 40px so that the text is centered vertically on each line. I also am giving a subtle border to distinguish the lines.

Finally, I’ll turn off the underlines and make the text white in the links.

    nav a {
      text-decoration: none;
      color: #fff;

Again I’m only targeting anchor tags inside of .nav, because I don’t want to assume all anchor tags will be styled this way.

The links are only clickable when I am actually on top of the words in the link. I want the link to span the entire block. So I need to add display: block to these links. Now I can click anywhere to go to a different page.

I’d like to make the color different when we hover over the link. I can do that with this:

    nav a:hover {
      background-color: #005f5f;

It would be nice to have a little transition effect on the hover as well, so I will add that.

    transition: .3s background-color;

I add it to the a tag though and not the hover selector. This will allow the transition to happen both when you mouse over the link and also when you move your mouse away.

The final thing I want to do before styling the wider screen navigation and making it horizontal, is to style the active class.

I have an active class on the “news” link right now. I can style the active links with this. {
      background-color: #fff;
      color: #444;

But we have a problem when I hover over the active link. I don’t want that color to change. So I will add .nav at the beginning so this selector has more specificity and will override the .nav a:hover that was previously defined.

I’d like to change the cursor: default; so it doesn’t look like clicking on this link will do anything.

So things are working nicely, and this would look fine on a phone. However, if we are on a wider screen, it looks strange.

When the screen is larger than 600px I’d like to switch to a horizontal navigation, so that will be my break point.

Anything less than 600px will show navigation vertically, and anything with more resolution will show it horizontally.

I can add a media query.

  @media screen and (min-width: 600px) {


Then I can target the .nav li inside of the media query. So when on a screen that is at least 600px wide it will use this code:

    .nav li {
      width: 120px;
      border-bottom: none;
      height: 50px;
      line-height: 50px;
      font-size: 1.4em;

I am making each menu item 120px wide since there are 5 items and 5*120 is 600. I’m removing the border and making the menu text and bar just a little bit larger.

If we move the viewport a little we can see how it changes.

Now we have two options for making this horizontal. One option is to display the list items as inline-block, and another option is to use floats. The first method is simpler but you may have a reason for wanting to use floats, so I will explain both options. Either option will work on IE8, however, IE8 will not understand the media query. So later we will need to copy this code to an IE8 only style sheet.

Even though I’m still targeting the .nav li selector, I’ll put the different option code outside of this first selection so I can easily distinguish between the two options.

If I add

    .nav li {
      display: inline-block;

the navigation works pretty well. We do have a slight problem around 600px wide where the last menu item jumps to another line. Also, if I hover over the other items, you can see we have this little gap of gray showing. That is because when using inline-block there is a bit of margin that is introduced. We can deal with it, by adding a small negative margin.

    margin-right: -4px;

And now everything looks great.

So this method works, and we could stop there. I’m not sure if there is a down-side to this, but you might want another option and see how floats would work.

    .nav li {
      float: left;

And this almost works, but the gray bar disappeared. That is because the parent element collapsed when the children where taken out of the flow by floating them.

If I turn on the Live Preview Highlight, you can see each li tag with it’s border. But the ul tag, is just this one line here which means is it collapsed.

There are numerous ways to fix this, and I have an entire video explaining all the ways. In this case, I will just add

    .nav ul {
      overflow: auto;

which is simple and will work.

However, we have a new issue, and that is that the navigation is not centered anymore. Depending on your website, this might not be an issue. But if we want to fix this we can add this:

    width: 600px;
    margin: 0 auto;

to center it.

And one final change is to make the entire nav bar have the dark gray color so it extends.

So, the inline-block method is a lot less code and simpler. But I thought it might be useful to see both methods. I used to always use the float method and getting it right sometimes caused headaches.

Finally, this code works well in all modern browsers, including IE9 and above. If we looked at this in IE8 we would only see the vertigal navigation like this, regardless of how wide the screen was, because IE8 does not recognize media queries.

To make it work in IE8 we can use a conditional style sheet and add the code we just added to our media query.

<!--[if lt IE 9]><link rel="stylesheet" href="ie.css"><![endif]-->
    .nav li {
      width: 120px;
      border-bottom: none;
      height: 50px;
      line-height: 50px;
      display: inline-block;
      margin-left: -4px;

This won’t ever display the vertical navigation in IE Browsers, but it is unlikely anyone using IE would be viewing this on a phone, so it should be okay.

If I had styled the horizontal menu first, we wouldn’t need an IE specific style sheet. I could have used a max-width instead of a min-width and flipped how I wrote the code. But I wanted to take a mobile first approach. The code ended up being simpler than when I approached it from the larger screen originally.

I hope that was helpful, if you have any questions, please post them at

43 thoughts on “Simple Horizontal Navigation

  1. Thanks,
    I can’t count how many of these I looked at and studied, this is the most straight forward and most of all logical !!! It is also able to be built upon, which I like. I give it an A++++, thanks again!

    All the best,

    Dan H.

  2. I know this may sound like a silly question, but how do I get the nav bar to have the active colour on the curent page? This bit seems quite unclear to me and I’m not sure how to do it. Apart from that, A+

    1. Hi Martin,

      Definitely not a silly question. I actually ignored the topic, but in my first version of this tutorial, I had tried to explain one possible way to do it.

      The part that gives the ‘active’ color on the current page is:

            background-color: #fff;
            color: #444;

      but the trick is to get that active class on the current page’s anchor tag. There are different ways to do that. It could come from the back-end when you serve up the page, or you could use some jQuery (or plain JavaScript) to add the class active to the menu item.

      If you want a pure CSS solution, here is a description of the way I handled it in this tutorial before:

      Highlighting Current Page with CSS

      Note, the date on that article is quite old. I would avoid using all the IDs and use classes instead. It should still work fine.

      ~ lisa

    1. Hi Mike,

      I’m not having that problem actually. It is staying on one line regardless of the size of my viewport. There is probably something different in what you are doing, because it should work.

      ~ lisa

  3. Hi Lisa. Thanks for your reply.

    I intended to use your code at the referenced website, on the top line. The line has several two-word references in it which caused the line to increase in size with vertical word alignment. I took the code out and substituted someone else’s code, so I can’t tell you for sure what element of your code I modifieded to get the div small enough to fit in the space available for it.

    1. Hi Mike,

      I put my demo code on so that anyone can play with the code now. If I change to “My Home” it works, but if I change “Tutorials” to something longer like “Sass Tutorials” it does have to go to 2 lines.

      The problem is that there just isn’t enough room for the text based on the font-size and width I am using. I suspect that is the problem you had using the code snippets from here.

      I’m talking about this block of code in the media query:

        .nav li {
          width: 120px;
          border-bottom: none;
          height: 50px;
          line-height: 50px;
          font-size: 1.4em;

      If I change the font-size to be a little smaller and/or make the width to be a little larger the problem is fixed.

      It sounds like you solved your problem already, but I just wanted to share this explanation in case anyone else needs help.

      ~ Lisa


  4. Hey Lisa,

    I have been working for about an hour now changing lineheight and height to larger numbers but I cannot get the height of the colored area to change I need t taller for a logo that is on the left.

    1. If you don’t mind the text still being centered on the menu bar, you should just make the height and the line-height bigger, inside of the @media query.

      I tried it it here on code pen. You should be able to play with the code there.

      See the Pen Simple Responsive Horizontal Navigation by Lisa (@lisa_c) on CodePen.

      I’m guessing the problem is you are trying to change the line-height and height on the regular code and not in the media query. Since I made this “mobile-first” that is the collapsed menu. You need to change the code in the media-query for larger screens.

      If that isn’t what you meant, let me know.

      ~ Lisa

  5. Hi Lisa, is there a reason you chose to use a class of ‘nav’ rather than the html5 ‘nav’ element? I’m wondering if this is just preference or whether there are advantages to using class selectors?


    1. Tony,

      It was mostly because I try to address using IE8 in my tutorials still, and I didn’t want to get distracted talking about how you need a shim to use the HTML semantic elements like nav in your CSS if you support IE8. It was purely for simplicity.

      I would use the nav element on a real website and I probably should have mentioned that.

      ~ lisa

  6. hey lisa! great video and excellent explaination . i want the navigation menu to be fixed at top even the user scrolls down . Can you please explain

  7. Never have I commented on blogs but I had to on this one, Lisa your teaching style is very professional and I just love how you’ve taken the consideration to not only acknowledge but also accommodate the different learning styles. Very helpful and useful tutorial also. Thanks!!

  8. There’s a missing ‘ . ‘ on the ‘nav a’ styling. It isn’t defined as a class currently without the period.

  9. This simple horizontal navigation tutorial is awesome. I am beginner in web design but your article is very easy to understand .Thanks

  10. A simple question here. I’d like to know if it’s possible to modify your code so when they’re on a smaller screen or the window gets resized to a smaller window (600px or so), the menu bar changes to say Menu (that’s centered) and have a three line bar on the right side and when the user hovers over the bar or clicks the navigation bar, the menu pops out from the side? If they want it to go away, just click the nav bar again. Hovering over it brings it out, clicking brings it out and takes it back… Is this possible? I can’t seem to figure out how it’s done. I can use :hover on the bar itself, but I can’t seem to modify an element outside the bar (ie, the menu that’s supposed to pop out from the side). If this is possible, how would I go about doing it? Thank you!

  11. I LOVE IT…

    However, i will like to know how, and maybe in an example.. on how after selecting one of the items you would see the item selected.. for instance we select the newsletter and still about keeps selected in white.

    Other than that : EXCELENT.. very easy to follow.

  12. Hi,
    In 5:32 you used “Live preview Highlight” What browser do you use? I can’t find it 🙁 I use chrome und firefox

    1. I’m using Chrome. Are you saying you can’t find the option in Brackets, or that you don’t see the outline in your browser?

      ~ lisa

      1. hi,
        ok! Now I see – this is Brackets option 🙂 I thought it is option in chrome
        I use sublime Text 2 🙂


  13. i love this article. i searched so many website for this but no one have as easy explanation as this website. good work from your team 🙂

  14. Being a newbie to CSS and HTML this was the best explanation! Providing all the options for code and the video really helped!

  15. This snippit is fantastic. I’m looking at updating a website which uses vertical navigation. Currently each link has a number of sub-menus (one level only); i.e. A, B, C, D (listed top to bottom). When my users click on a menu item (e.g. A), and the sub-menus appear below (e.g. A, A1, A2, A3, B, C, D), it means the other menus (B, C and D) move further down the page. This can be very confusing for some of my users. I think a horizontal menu could fix this, where the sub-menus appear below the top level menus; e.g. I only want the sub-menus to appear once the user has clicked on the top level menu item. Reason being, each menu item is password protected, for different kinds of users. I’ll have a crack at working this out myself, but if you can point me to any other sources which cover this style of menu, that would be greatly appreciated!

  16. Hello,
    I am trying to put this html and css on blog but i am not getting exact result like u shown here..
    i do not understand where to put the css or whether i have to delete some code from my html blog or what..
    please tell me how to put that html and css well to get the great results..
    my blog is at

Leave a Reply

Your email address will not be published. Required fields are marked *