Coding Apple’s Navigation Bar Using CSS Sprites

78

by Shane Jeffers

applebarcode

Here is the follow up tutorial to my most recent tutorial on how to create Apple’s navigation bar in photoshop. This tutorial is not going to go in depth about all the benefits of sprites, but will show you how to use the technique correctly.

What are CSS Sprites, and why use them?

In lamens terms CSS Sprites are multiple images combined into one to reduce the amount http requests and server load time. Have you ever used the hover attribute with a background image that shows up on hover? Yep that’s right, when you hover over it for the first time there is a slight flicker, or moment where the image does not show. This happens because the browser doesn’t load that image until the hover state, therefore causing a slight flicker the first time the image is hovered over. CSS Sprites get rid of that flicker because instead of using two images and calling a separate image on hover you combine the two images into one and position it on hover. This might sound a little confusing at first, but keep doing it and you will get it.

Ok, Lets Get Started

1. Click here to download our starting image for this tutorial

2. Create a new HTML file and a CSS file with your favorite editor.

Setting up the HTML

We are going to use an unordered list because they are great especially for navigation. So create an unordered list like the one below. You can see that we have an LI tag for each section on our navigation, this is very important. You can also see that each LI tag has an ID assigned to it. This is also very important because we will need to specify the width of each list item later.

	<ul id="nav">
	          <li id="list1"><a href="#"><span>Apple</span></a></li>
	          <li id="list2"><a href="#"><span>Store</span></a></li>
	          <li id="list3"><a href="#"><span>Mac</span></a></li>
	          <li id="list4"><a href="#"><span>iPod + iTunes</span></a></li>
	          <li id="list5"><a href="#"><span>iPhone</span></a></li>
	          <li id="list6"><a href="#"><span>Downloads</span></a></li>
	          <li id="list7"><a href="#"><span>Support</span></a></li>
	</ul>

That is all of the HTML code you will need for this technique, CSS takes care of the rest.

Setting up the CSS

Ok first and foremost I am hoping you have already linked your style sheet to your HTML file, if not do so now.

3. The first selector we will be working with is our Unordered list which we gave the ID of “nav.” We are going to set our main image as the background of our unordered list. Now, our images total height is 76px, but we only want half of the image to show at first correct? Yes thats correct, because we do not want the bottom half of the picture to show up until one of the buttons on the nav is hovered over. So we are setting the height of the Unordered list to 38 which is half of 76. Margin: 0 auto is just to center the Unordered list in your browser window that piece of code is not necessary. Check out the code below


* { margin: 0px; padding: 0px; }

#nav {
      background: url(nav.png);
      height: 38px;
      width: 876px;
      margin: 0 auto;
}

#nav span {
     display: none;
}

4. Next we need to get the list items to be horizontal because that is the orientation of our navigation. So we float the list items to the left so that they line up horizontally. We also want to get rid of the bullets because they are just getting in the way! The next step is to give a height to our anchor tags. The anchor tags determine which part is going to be clickable which we are giving a height of 38px. If we want all of those 38px to be clickable we have to use display: block.

#nav li {
	list-style-type: none;
	float: left;
}

#nav a {
	height: 38px;
	display: block;
}

It’s Measuring Time

5. Now we have to measure out exactly how wide each of the “buttons” on out navigation our, so lets head back to photoshop. Open up nav.png and grab your ruler tool which is underneath your eyedropper tool and click on the very left edge of the document and drag to the dark middle separator between the second button. Make sure you ZOOM IN so you can be more accurate

measure

6. Repeat step five for each of the buttons until you get all the way to the other end. If you measure correctly they should all add up to be 876px wide. If yours do not match that width move on for now and you can change it later. Now we have to get all of our selectors ready for each individual list item.

#list1 { width: 112px; }
#list2 { width: 120px; }
#list3 { width: 128px; }
#list4 { width: 125px; }
#list5 { width: 137px; }
#list6 { width: 131px; }
#list7 { width: 123px; }

7. Now that we have the widths set we need to position the rollover on hover. So how do we do that? We are going to use background positioning. So we choose our first selector which is #list1, and we set the background image as our nav.png. When using background positioning you have two choices move along the X-axis (horizontal) or the Y-axis (Vertical). Since are rollover image is underneath our active state we need to shift the image up the Y-axis. So how much do we shift it up? Well since our image is split directly in two we can just use the same height as we set for our Unordered list which was 38px, but we need to use a NEGATIVE 38 because the negative makes it go up the Y-axis where as a positive 38 would shift it down.

#list1 a:hover {
      background: url(nav.png) 0px -38px no-repeat;
}

8. The -38px for the Y-axis will be the same on each one of the list items because we always want it to shift to the rollover section of our image, but the x-axis will change. The x-axis in the example above is set to zero because it is all the way to the left. So for the next list item we need to shift it over the amount of the previous list items width (Hopefully that makes sense). So we go back and look at the width of the first list item, which we see is 112px so we add that as a negative number to our x-axis on #list2.

#list2 a:hover {
      background: url(nav.png) -112px -38px no-repeat;
}

9. We keep repeating this process for the other 5 list items. Just keep adding the previous widths so by the time you get to the end you should be adding six widths together. Here is what it should look like complete.

#list1 a:hover {
      background: url(nav.png) 0px -38px no-repeat;
}

#list2 a:hover {
      background: url(nav.png) -112px -38px no-repeat;
}

#list3 a:hover {
      background: url(nav.png) -232px -38px no-repeat;
}

#list4 a:hover {
      background: url(nav.png) -360px -38px no-repeat;
}

#list5 a:hover {
      background: url(nav.png) -485px -38px no-repeat;
}

#list6 a:hover {
      background: url(nav.png) -622px -38px no-repeat;
}

#list7 a:hover {
      background: url(nav.png) -753px -38px no-repeat;
}

All Done!!

If you have followed all of the steps I have laid out above you should have a beautiful Apple Navigation Bar coded using CSS Sprites. If you have any questions please comment on this post. Please subscribe to my blog if you enjoyed this post. Thanks everyone

Written by Shane Jeffers

Shane Jeffers is the Creator and Author of Three Styles. I have a unique passion for design trends and tutorials. Follow me on twitter @ThreeStyles

Enjoy this post? Subscribe by RSS or Email

Apple Stuff, CSS, Tutorials

  • Mike

    Hi Shane,

    Great tutorial – thanks for sharing.

    Could you advise how to implement a CSS drop down menu into this CSS sprite navigation?

    Thanks in advance,

    Mike

  • Joe

    can anyone help me? the css below wont display properly in IE :/

    html #main-menu {
    list-style : none;
    padding : 0px;
    height : 38px;
    width: 1000px;
    float: left;
    margin-top: 75px;
    margin-right: 0px;
    margin-bottom: 0px;
    margin-left: 3px;
    }
    html #main-menu li a {
    display : block;
    float : left;
    height : 37.5px;
    background : url(../img/navigation_img/main_navigation_menu_bar.png);
    font-family : “Trebuchet MS”, Arial, Helvetica, sans-serif;
    font-size : 12px;
    font-weight : bold;
    color : #fafafa;
    text-decoration : none;
    text-align : center;
    line-height : 37.5px;
    }
    html #main-menu li a.home {
    width : 92px;
    background-position : 0% 0%;
    display : block;
    text-indent : -999px;
    margin : 0;
    padding : 0;
    }
    html #main-menu li a.SalarySurveys {
    position : relative;
    width : 134px;
    background-position : -92px 0%;
    }
    html #main-menu li a.hr {
    width : 170px;
    background-position : -226px 0%;
    }
    html #main-menu li a.benefits {
    width : 121px;
    background-position : -396px 0%;
    }
    html #main-menu li a.news {
    width : 120px;
    background-position : -517px 0%;
    }
    html #main-menu li a.online_services {
    width : 172px;
    background-position : -637px 0%;
    }
    html #main-menu li a.webdemos {
    width : 185px;
    background-position : -809px 0%;
    }
    html #homefade span.hover {
    position : absolute;
    display : block;
    height : 37.5px;
    width : 93px;
    background : url(../img/navigation_img/main_navigation_menu_bar.png);
    background-position : 0% -37.5px;
    }
    html #main-menu li a.home:visited {
    display : block;
    height : 37.5px;
    width : 93px;
    background : url(../img/navigation_img/main_navigation_menu_bar.png);
    background-position : 0% -37.5px;
    }
    html #main-menu li a.SalarySurveys:hover {
    display : block;
    background-position : -93px -37.5px;
    color : #cecece;
    }
    html #main-menu li a.SalarySurveys:active {
    color : #0cf;
    }
    html #main-menu li a.hr:hover {
    background-position : -226px -37.5px;
    color : #cecece;
    }
    html #main-menu li a.hr:active {
    color : #0cf;
    }
    html #main-menu li a.benefits:hover {
    background-position : -396px -37.5px;
    color : #cecece;
    }
    html #main-menu li a.benefits:active {
    color : #0cf;
    }
    html #main-menu li a.news:hover {
    background-position : -517px -37.5px;
    color : #cecece;
    }
    html #main-menu li a.news:active {
    color : #0cf;
    }
    html #main-menu li a.online_services:hover {
    background-position : -637px -37.5px;
    color : #cecece;
    }
    html #main-menu li a.online_services:active {
    color : #0cf;
    }
    html #main-menu li a.webdemos:hover {
    background-position : -808px -37.5px;
    color : #cecece;
    }
    html #main-menu li a.webdemos:active {
    color : #0cf;
    }

  • Sahil

    Thank Very Much

  • Pingback: Navigation 20bar | Completehmsolutions

  • lebisol

    Cool tutorials and nice use of mac terms for visitor magnet :)
    Still don’t get the need for spans…since when the extra and unused markup makes it easier to update???
    Other than that, nice work!

  • Mark

    Hi Shane,

    Just want to say that this is by far the best tutorial for sprites I have followed. Very easy to understand and doesn’t come across as daunting, advanced CSS code at all (which some tutorials do!). It worked a treat first time. Will definitely be looking to your tutorials if I need help again.
    :)

    • http://shanejeffers.com Shane Jeffers

      @Mark

      I’m glad it was a helpful resource to you!

  • angie hodder

    Hi Shane,

    I’m new to this and your tutorial worked really well for me, but I can’t figure out how to make the active state? How can we make this state for the page we are on?

    Thanks!!

  • http://www.chokaproductions.be Brent Van den Abbeele

    Thanks, great tutorial. To bad dreamweaver can’t take it when you preview it in safari, but everything’s fine when uploaded.

  • http://www.cadencemed.com Matt

    I still don’t see a comment where it has solved this nav’s inability to “stick” to a certain color for the current active page. Could someone please answer this for me and all of those who have already expressed a need for it?

    Thank you!

  • http://shanejeffers.com Shane Jeffers

    @angie

    How to add an active state

    1. You would need to create the active state image and add it to the bottom of the sprite.
    2. Use jQuery to add the active class.
    3. Adjust the CSS down to the active state portion of the sprite when the class is applied.

  • http://www.gugudesign.com googoo

    this is a very clear tutorial for a person who new to css. THANK YOU!

  • http://kunals.com Kunal

    Another cool implementation of CSS sprite: Dynamic CSS Sprite implementation to give a painting effect. Read how to implement it by reading an easy to follow tutorial at http://blog.kunals.com/dynamic-css-sprite-implementation-gives-a-painting-effect/

  • http://blackfalcon-modding.x10.mx z8137

    It would be nice if you could supply the .PSD for this… Took me a while to get the exact measurements.

  • http://www.basekit.com/ BaseKit

    Great tutorial. Really helpful comments too! Thanks.

  • Sameer Khan

    Great tutorial…
    Thanks!!!!

  • Behrouz

    Hi
    Thanks for tutorial, but I have a question for you, as well.
    How we can make the current page list(menu) highlighted?
    As you know when we select any pages(let’s say support) how the user should know on which page he/she is visiting at the time?!

    Thanks again

  • http://thewebdesignbay.com Gustavs Jurisons

    Very nice tutorial indeed!
    I think this needs a little update because adding highlighting to the current page will make navigation more user-friendly.

  • http://wordpressidx.com/custom Custom IDX Solutions

    AWESOME tutorial…. Menu’s are always tuff to deal with especially without guidance.

  • http://n.v.t. Tiennes

    I and some minor changes made ​​to the script so the navigation bar to fit for my site, just hover does not work. I can not get out. What am I doing wrong?

    HTML CODE:

    Home
    Over Mij
    Fotogallerij
    Portofolio

    CSS CODE:

    *{
    margin: 0px;
    padding: 0px;
    }

    #navigation-top{
    background-image:url(images/navigation-bar.png);
    height:38px;
    width:900px;
    margin: 0 auto;
    margin-top:50px;
    }

    #navigation-top span{
    display:none;
    }

    #navigation-top li{
    list-style-type:none;
    float:left;
    }

    #navigation-top a{
    height:38px;
    display:block;
    }

    #lijst1{
    width:112px;
    }

    #lijst2{
    width:120px;
    }

    #lijst3{
    width:128px;
    }

    #lijst4{
    width:125px;
    }

    #lijst1 a:hover{
    background-image:url(images/navigation-bar.png);
    padding:0px;
    padding-left:-38px;
    background-repeat:no-repeat;
    }

    #lijst2 a:hover{
    background-image:url(images/navigation-bar.png) -112px -38px no-repeat;
    }

    #lijst3 a:hover{
    background-image:url(images/navigation-bar.png) -232px -38px no-repeat;
    }

    #lijst4 a:hover{
    background-image:url(images/navigation-bar.png) -360px -38px no-repeat;
    }

  • Splungeman

    Hello, I loved the tutorial and have adapted it in the creation of many new sprites, all based on this first tut. I have a dumb question, I can’t wrap my head around why a negative value is given to each tab when it progress to the right. I know it works and I read your explanation but could you diagram it for me, I am a bit right brained and numbers work when I do them with out question but I want to be able to run with this technique. I get confused with starting with a zero value and then applying a negative value for the next tab, I know they are offset but the zero value comes up as just a point and not a space? Do I make sense? Your patients is appreciated.

  • Splungeman

    Could you demo a vertical sprite tutorial just like this one?

  • http://www.designhosting.biz/testdesign.html Melinda

    Hi,

    I have tried and tried but still the over images are offset to the right for some reason.

    First I made the one image and divided the backgrounds individually behind each text like a regular button would be. Then I tried a single background image with vertical dividers and that didn’t help either.

    The css is here:
    http://www.designhosting.biz/internal/css/test2012Global.css

    The website is:
    http://www.designhosting.biz/testdesign.html

    If you could look at this I would really appreciate it. I absolutely cannot find where the problem is.

    Thank you!

  • http://www.designhosting.biz/testdesign.html Melinda

    Hi,

    I found the problem. I had a normalize.css file that I hadn’t really looked at as it seemed to even things out between browsers when I first put it on but after removing this file the navigation worked as it should.

    Thank you for this wonderful tutorial!

    I hope you can also show us how to make the background button stay in place like apple does when you click on “mac” … the background behind mac stays the darker color while on that page.

  • http://shanejeffers.com Shane Jeffers

    You cannot add a highlight to the current tab using strictly CSS. You will need some kind of javascript to add this in. I would recommend using jQuery to toggle a class on click.

  • http://techrepair.ie Ryan

    Nice menu, I was thinking of implementing something like this on my website. Have you considered adding some dropdown menus when you hover over the main links?

  • Pingback: :: Building Faster Websites with CSS Sprites :: TOP 10 Tutorials of Sprites :: « Designers BLOG :: Updates, Resources, Tutorials for Designers:: HTML5, CSS3, HTML, CSS, JQUERY