The best way to learn something like CSS3? Challenge yourself to build something that you’ve seen. I sat down the other day and built Apple’s navigation using only CSS. I know for sure I’m not the first person to build a CSS only Apple style nav, but thinking about this made me wonder, how did Apple build their own navigation? I’ve never seen any examples of that. The reason? It’s not exactly sexy CSS but it works and is a good way to get the desired results.
Here’s how to build it using only CSS. First off, we need to set up the HTML, it’s pretty simple:
1 2 3 4 5 6 7 8 9 10 11 12 | <body> <div id="nav"> <li><a class="first" href="#">Home</a></li> <li><a href="#">Store</a></li> <li><a href="#">Mac</a></li> <li><a href="#">iPod</a></li> <li><a href="#">iPhone</a></li> <li><a href="#">iPad</a></li> <li><a href="#">iTunes</a></li> <li><a class="last" href="#">Support</a></li> </div> </body> |
Pretty simple, standard navigation. I’m not going to go step-by-step with this, you can figure stuff out pretty quickly if you poke around. Here’s the CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | body { margin:0; padding:0; } #nav { width:824px; height:38px; margin: 30px auto 0 auto; } #nav li { display:inline; text-align:center; } #nav li a { background:-moz-linear-gradient(top, #CCC, #999); background:-webkit-gradient(linear, left top, left bottom, from(#CCC), to(#999)); width:103px; height:28px; display:inline-block; float:left; padding-top:12px; text-decoration:none; color:#000; font-family:Arial, Helvetica, sans-serif; font-size:14px; text-shadow: #fff 0 0.5px 0; } #nav li a:hover { background:-moz-linear-gradient(top, #999, #666); background:-webkit-gradient(linear, left top, left bottom, from(#999), to(#666)); } #nav li a:active { background:-moz-linear-gradient(top, #999, #666); -moz-box-shadow:inset 1px 3px 5px #000000; background:-webkit-gradient(linear, left top, left bottom, from(#999), to(#666)); -webkit-box-shadow:inset 1px 3px 5px #000000; } .first { -moz-border-radius:5px 0 0 5px; -webkit-border-radius:5px 0 0 5px; } .last { -moz-border-radius:0 5px 5px 0; -webkit-border-radius:0 5px 5px 0; } |
A decent amount of CSS, but there’s no images or JavaScript, so it will load faster. It doesn’t work in IE7 or IE8, this might work in IE9 when they finalize it, hopefully. The text-shadow doesn’t seem to work in Webkit browsers, but I’m sure Google will change that sooner rather than later. So we can build this, but if it only works in Firefox and Webkit browsers, should we bother? And if it doesn’t work in all browsers, how does Apple do it?
Apple’s solution is pretty simple and works in everything. They use CSS with images and no JavaScript. But the thing I found surprising is they just use one big image, you can check it out here. They just reuse and reposition the same image over and over for their navigation bar. Here’s how Apple does it:
1 2 3 4 5 6 7 8 9 10 | <div id="nav"> <li id="apple"><a href="#">Apple</a></li> <li id="store"><a href="#">Store</a></li> <li id="mac"><a href="#">Mac</a></li> <li id="ipod"><a href="#">iPod</a></li> <li id="iphone"><a href="#">iPhone</a></li> <li id="ipad"><a href="#">iPad</a></li> <li id="itunes"><a href="#">iTunes</a></li> <li id="support"><a href="#">Support</a></li> </div> |
Standard navigation HTML, all the divs with ids are necessary for the positioning of the background images. Here’s my version of the CSS Apple’s using (I simplified it a bit):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #nav { width:982px; height:38px; } #nav li { display:inline; } #nav li a { float:left; width:103px; height:0; overflow:hidden; display:inline-block; padding-top:38px; background:url(globalnavbg.png) no-repeat; } #nav li#apple a {background-position:0 0;} #nav li#store a {background-position:-103px 0;} #nav li#mac a {background-position:-206px 0;} #nav li#ipod a {background-position:-309px 0;} #nav li#iphone a {background-position:-412px 0;} #nav li#ipad a {background-position:-515px 0;} #nav li#itunes a {background-position:-618px 0;} #nav li#support a {background-position:-721px 0;} #nav li#apple a:hover {background-position:0 -38px;} #nav li#store a:hover {background-position:-103px -38px;} #nav li#mac a:hover {background-position:-206px -38px;} #nav li#ipod a:hover {background-position:-309px -38px;} #nav li#iphone a:hover {background-position:-412px -38px;} #nav li#ipad a:hover {background-position:-515px -38px;} #nav li#itunes a:hover {background-position:-618px -38px;} #nav li#support a:hover {background-position:-721px -38px;} #nav li#apple a:active {background-position:0 -76px;} #nav li#store a:active {background-position:-103px -76px;} #nav li#mac a:active {background-position:-206px -76px;} #nav li#ipod a:active {background-position:-309px -76px;} #nav li#iphone a:active {background-position:-412px -76px;} #nav li#ipad a:active {background-position:-515px -76px;} #nav li#itunes a:active {background-position:-618px -76px;} #nav li#support a:active {background-position:-721px -76px;} |
See, all Apple is doing is a lot of repositioning of the background image, which is going to make the navigation look the same in every browser. So, their CSS isn’t as sexy as their design, but it gets the job done. And all this shows that CSS3 is a ways away before you can use it consistently and get the same results in all browsers. But by figuring out how to make things like this in CSS3 will give you a head start when you can finally build these things and not have to worry about cross browser issues.
It’s hard to argue against using background sprites at this point. Obviously at some point CSS3 will be fully viable, but using sprites is a great way to cut down on load time given the current browser landscape.
I completely agree. I was just surprised with the use of the one large image. But it would need only one HTTP request which would speed up loading.