Best Practices To Design a Perfect HTML Navigation Bar

The navigation bar is an inevitable element in every website. In this post I want to share with you some simple practices and suggestions aimed at designing a perfect HTML navigation bar.

Let’s start illustrating the typical HTML structure. Here is a schematization of a typical navigation bar that contains some links:

The HTML code is really simple, nothing more than <div> layer with an unordered list inside. As you probably know, the HTML5 specification introduced a new element that identifies the navigation bar which is the <nav> tag. The <nav> tag substitutes the more general <div> tag but, as you can see in the following code, it doesn’t change the conceptual structure of the navigation bar.

HTML 4 Code

<div id="nav">
<ul>
<li><a href="/index">Home</a></li>
<li><a href="/link1">Link 1</a></li>
<li><a href="/link2">Link 2</a></li>
<ul>
</div>

HTML 5 Code

<nav>
<ul>
<li><a href="/index">Home</a></li>
<li><a href="/link1">Link 1</a></li>
<li><a href="/link2">Link 2</a></li>
<ul>
</nav>

Using an unordered list for organizing the navigation bar is always a good practice to follow especially when you have to implement a little bit more complex interaction between main links and any submenus. Furthermore, this approach allows you to have more control on the CSS code of the various elements that compose the navigation, thus simplifying the customization.

Here is an example of HTML structure for a basic navigation bar with submenus:

<div id="nav"> <!-- nav container -->
<ul>
<li><a href="/link1">Link 1</a> <!-- main item -->
<ul> <!-- item submenu -->
<li><a href="/s-link1">Sub Link 1</a></li>
<li><a href="/s-link2">Sub Link 2</a></li>
</ul> <!-- close submenu -->
</li>
<ul>
</div>

CSS code suggestions

Now take note of the following three simple suggestions for great CSS code. Set the “height” attribute for the tag <li> equal to the height attribute of the <ul> tag:

For a perfect vertical alignment of the text, set the “line-height” attribute for the tag <li> equal to the height attribute of the <ul> tag:

To make the area of your link fully clickable set the attribute “display” of the tag <a> to block:

Interaction with pages

You can create various kind of interactions between the items of the navigation bar and a certain page visited by the user. A simple interaction consists in changing the status of a specific tag to “active”, for example, if the current page is the home page or if the current post is in a specific category which is present in the navigation bar. In the picture, the current post is in the category “Apple” and the tab “Apple” in the navigation bar is “active”.

If you use WordPress you can use the following code for identify the home page and make the “home” tab of your navigation bar “active”:

<?php if(is_home()){ ?>
<li class="active">Home</li>
<?php } else { ?>
<li><a href="<?php echo get_option('home'); ?>">Home</a></li>
<?php } ?>

If you use a category-based navigation bar you can use the following code to highlight a tab of a specific category when the post is in that category. For example, if your navigation bar has a tab “Apple” and the current post is in the category “Apple” you can make the tab “active” using this code:

<?php
global $post;
$categories = get_the_category();
foreach($categories as $category) {
$cat_name = $category->cat_name;
} ?>
<ul>
<?php if(!is_home() && $cat_name=='Apple'){?>
<li class="active-sn">Apple</li>
<?php } else { ?>
<li><a href="<?php echo get_option('home'); ?>/category/apple">Apple</a>
</li><?php } ?>
<ul>

That’s all. If you have any suggestion or feedback please leave a comment!

  • Habib Ullah Bahar

    helpful for those like me who are software engineers, but sometime need to do some web designing.

    • Anil

      I saw a lot of way of making horizontal menu. It i would also recommend this way. As its simple to start with and robust menu. Easy to extend and most important thing is resuable. Ak @ http://www.mobilebroadbandguru.co.uk

  • Jero

    Thanks for the tips. How can we make appear the submenu with mouse rollover the link?

    Sorry about my english.

    • Antonio Lupetti

      There are several ways to implement that: you can use some complex CSS tricks or JavaScript, for example by using a framework such as jQuery. Take a look here for an interesting example http://apycom.com/

    • Josiah

      I made a simple dropdown menu based on this structure using only CSS, and no JavaScript. It works pretty well. I’ve used a modification of it on about 5 client websites so far. After using it so many times I realize the code could use a little improvement, but its a good place to start and does the job well. http://www.josiahsprague.com/deltagroup/code/dropdown.html

  • Douglas

    Great tutorial, but wordpress generates CSS classes dynamically, so that the active page or category is created when a single class, so it’s only styling of this class. Sorry about my english.

  • Jero

    Thanks again Antonio. I was lookin for a pure CSS solution to a horizontal sub-menu that appear under the main menu. I have founded some solutions for this but non cross-navigator. F*ckin IE6!

    • Adedoyin Kassem

      Hello there Jero, there are more than a dozen ways to go about solving the challenges posed by IE6 when it comes to “pure CSS solutions”. I would be glad to help you solve this one, if you would send me the code that you want tweaked to worked perfect on IE6.

  • Amrinder

    Nice to see the changed navigation plus tutorial on the subject. But I have spotted redundant use of DIVs and some inappropriate naming convention in your markup. Will write about it soon :)

    • Derek

      @Amrinder Did you get those written up yet?

    • Adedoyin Kassem

      @Amrinder After reading through your reply, I carefully went through the markup for both HTML4 and HTML5 and I must point out that I can’t find any redundant DIV(s) in the markup. If you are referring to the DIV tag holding the parent UL, then i would say that it is not redundant depending on the layout and structure of the page in view. i would still be on the look for your own suggestions though!

  • Nello

    Antonio, come al solito le tue guide sono chiare e dettagliate… complimenti per il sito, chissà se avrò il tempo di finire il mio e poterlo finalmente pubblicare. Ancora complimenti

    • Antonio Lupetti

      Thanks a lot for your comment! :)

  • paul

    thanks, what did you use to create the schemas?

    • Antonio Lupetti

      PowerPoint for Mac!

    • Bene

      powerpoint?? :D

    • Antonio Lupetti

      Sure! PowerPoint! :)

  • Stephen

    Instead of using WordPress conditional statements to highlight the current category, wouldn’t it be easier to just use the default classes generated by wp_list_categories, wp_list_pages, or wp_nav_menu?

    .current-cat
    .current-cat-parent
    .current_page_item

    etc?

    Also, which element should have the list-style:none property: ul or li or doesn’t matter?

    • Adedoyin Kassem

      Nice observation on the use of wordpress’ generated classes instead of using an external javascript framework to assign the “active” class to the current or active.
      As to your question on which element should carry the “list-style” CSS property, you could check this rule which i usually define in my core style rules:

      ol, ul, li {
      list-style-type: none;
      margin: 0;
      padding: 0;
      outline: 0;
      }

      NB: this should not be used if you have other rules in mind, or better still you could tweak to serve your purpose.

  • Hector A. Henry S.

    I simple loves this pots antonio i was looking forward for it but here it its at last. Than you.

    And no matter what i love all the themes you use on this blog they really leave me atonish and over all they are unique i will try do fun whit this how to or tutorial.

    Thank you and keep up the nice work.

    • Antonio Lupetti

      Thanks a lot Hector!

    • Jay

      My man, if you don’t know English, please write in your own language, because this post is not understandable.

  • Ailin Hernandez

    Very interesting, I love the simplicity of this post. I’m always looking for nav bar solutions and this made my day. Thanks!

  • amit

    very helpfull article.

  • Walter Earnshaw

    Thanx Antonio for this useful article.
    Now, I would like to ask you a question that has been bothering me for some time.
    What is the difference between sites set up using html/css/etc and sites using wordpress to set them up?
    Is it just a matter of code (I notice a lot of Phps in wordpress)?

    yt Walter Earnshaw

  • TutorialFeed

    Really nice tips. It helps me a lot.

  • Jordan Walker

    Great tutorial they every developer should read up on.

    • Antonio Lupetti

      Thanks Jordan! :)

  • Chris F.A. Johnson

    Two points:

    1. The line-height attribute should not have any unit.

    2. Using a fixed px size for font-size can cause the layout to break if the viewers’ font-size is larger than yours.

    • John Faulds

      Yeah, better to use ems if you have to set a height on the nav at all so that the text will scale when the browser resizes text (not everyone is using page zoom).

  • David

    You say the perfect nav bar, then go into a how to. You dont even justify why you think it’s perfect. I notice it’s the same as the on your site. So are you saying your own nav is perfect?

    I think a little reasoning behind why you think it’s perfect, or at least a more concise title would be preferable.

    • Alex Cristache

      @David: I’m thinking it’s the “perfect navigation” because of the fact that this model is backed up by most of the design community (ul->li->ul->li model), so it does not need to be justified in any way, it’s part of “the Bible”.

      @Antonio: Stephen, a few comments above is right about the use of the default mark-up of WordPress’ default navigation functions. For a tutorial, you would have been better off offering a sample that shapes itself on those, not a customized one. Also, since you’re using get_the_category(), you could have used get_category_link() (more info on WP Codex) to output the permalink. The solution you propose it’s only half flexible, and if you will ever change your permalink structure or slugs, it will break.

      Other than that, a nice how to for those looking to tweak their themes.

    • David

      No harm in repeating it for the new users ;)

    • Jay

      I would agree with David here. You say this model is a standard, then why write about it if not for new users that are unfamiliar with it? Everyone that is coding websites will already have heard of this method. It definitely needs to be justified otherwise there is no point to writing about it. Unless; of course, you just want hits on your blog so you can make money off advertising or whatever and you don’t care about the actual content.

  • Karthik

    Excellent article… Thanks

  • Joao Pereira

    Excelente article with clear and objective tips.

  • Michael

    Once again Antonio, you’ve done a great job of boiling everything down.

    In the section regarding utilization of php to attach attributes to the page being viewed for CSS purposes, do you have any favorite snippets for achieving this on a typical php driven site?

    Thanks for the snips, or perhaps your advice/link to same.

    Michael

  • Chris Morata

    Good article, but I have to disagree about the container you’ve placed around the list. It’s unnecessary markup, and you would more than likely be able to style your navigation how you need to without the extra div and simply applying the id to the tag.

    Also, I don’t think you need to apply a fixed height to the . You can just let the list items float, and apply CSS of overflow: hidden; to the .

    Just my opinion :)

  • Tucker Graczkowski

    I agree that this is a very useful method when it comes to semantic HTML markup. The CSS styling is very easy and powerful, and creating submenus is a breeze.

    This is an incredibly useful post with detailed and informative pictures. Thanks for posting.

  • Max Luzuriaga

    I completely agree with this article, except for one area.

    I sometimes use ul > li > h(1,2,3,4,5, or 6) > a to add more semantic emphasis on the navigation text. I really don’t know if this is more semantically correct, it’s just another way to do it.

    • Alex Cristache

      It’s a really bad idea to use headings there, and should definitely not be “another way to do it”. Not only they don’t give semantic value, but they are misused. Headings are meant for content. Also, by standard you’d have to have only one H1 on any given webpage, and that should be your most important headline/heading on that page. If you use H1′s for your top navigation you’ve pretty much screwed your SEO and nice standards to hell.

  • Court Kizer

    How would one make certain navigation items icons? Would it be a problem to use BG images and span? I’d like to see an example of LINKS with icons next to them. Does anything change?

    • Joe Holtz

      Why not put the images inside of the link tags?

  • Subrato Paul

    Well written and well illustrated. Many tips for navigation bar that every web designer and blogger should take care of, if not already.

  • joker400

    Nice and easy thanks Antonio … i like this way

  • nikos lianeris

    a very helpful tutorial!!It helped me a lot!!Thank you for sharing!! :)

  • Pat

    Hi. I was curious what you used to make the diagrams? Thanks!

  • Felipe

    Great! I am a begginer and these tips of navigation bars help-me a lot. Thank you!

  • Joel

    What’s your thoughts on definition lists instead of unordered lists?

  • Adedoyin Kassem

    In all I do think this was a well written post but for the small details you overlooked in the structure of your get_category() for your wordpress navigation. Asides this, I give you a “thumbs up”!

  • Alex

    Thanks for this helpful tutorial! Another good resource on HTML 5 I found: http://bit.ly/bH2zQ9

  • Ben Davies

    Does this technique work with text-proportion heights like ems? If so, wouldn’t that be a better approach? Thanks

  • Rohan

    Hi Antonio Lupetti, this is very helpful to me. Thanks a lot.
    Your schemas are wonderful, what did you use to make them? Can I expect a blog post on how to create schemas?

  • Dimitris S.

    Amazing tips. Was wondering how to apply a middle vertical position for the a tag, but now i know.

    Thanks

  • Gemma

    In many cases, the div container is not necessary.

  • Russell Bishop

    Nice example, but there’s a little bloat with your HTML (mainly the containing div) and your CSS, but it’s a good example.

    For those asking after how to create a drop-down menu, I don’t think it’s quite right for you to tell them that they’ll need to use ‘complex’ CSS or a JavaScript library, Antonio!

    We recently wrote an article on that topic here;

    http://www.digital-results.com/blog/development/css-dropdown-navigation/

  • Julio's CoRRp!

    Muchas gracias amigo!, de verdad sabes mucho del tema, saludos.

  • Phil @ Outsourcing

    I just took an exam with navigation bar. This really helped a lot. Thanks! I hope someday I could share what I know about html and css.

  • martin

    antonio,

    i have my nav centered in a div but in IE it goes to the left edge, any reason you can think o? thank you!

  • Paulo Oliveira

    Thanks for the tips! Very, very useful.

  • Tinashe

    This is awesome, dude!