Create Windows 7 start menu using CSS3 only

I am fascinated with how much you can do with so little using CSS3. Many user interface elements that require images in order to have appropriate visual appearance now can be styled only with CSS3. In order to prove that I assigned myself a task to create Windows 7 start menu only with CSS3 (and some icons).

If we decompose the menu we’ll get one div, two unordered lists with a couple of links each and a few icons. Let’s see how each one of those is styled.

Check out the demo

Container

The container named startmenu holds two unordered lists that act as menus. It has linear gradient with three color stops: light blue at the top, dark blue in the middle, and another shade of light blue at the bottom. Transparency is achieved using rgba() which has four parameters. The first three represent red, green and blue color values and the last one is opacity. Two borders are created with border and box-shadow properties.

#startmenu { border:solid 1px #102a3e; overflow:visible; display:inline-block; margin:60px 0 0 20px;
-moz-border-radius:5px;-webkit-border-radius:5px; position:relative;
box-shadow: inset 0 0 1px #fff; -moz-box-shadow: inset 0 0 1px #fff; -webkit-box-shadow: inset 0 0 1px #fff;
background-color:#619bb9;
background: -moz-linear-gradient(top, rgba(50, 123, 165, 0.75), rgba(46, 75, 90, 0.75) 50%, rgba(92, 176, 220, 0.75));
background: -webkit-gradient(linear, center top, center bottom, from(#327aa4),color-stop(45%, #2e4b5a), to(#5cb0dc)); }

Programs menu

This unordered list has white background and two borders created with border and box-shadow properties. Its links, which contain icons and program names, uses gradients and box shadows in hover state.

#programs, #links {float:left; display:block; padding:0; list-style:none;}
#programs { background:#fff; border:solid 1px #365167; margin:7px 0 7px 7px;
box-shadow: 0 0 1px #fff; -moz-box-shadow: 0 0 1px #fff; -webkit-box-shadow: 0 0 1px #fff;
-moz-border-radius:3px;-webkit-border-radius:3px;}
#programs a { border:solid 1px transparent; display:block; padding:3px; margin:3px;
color:#4b4b4b; text-decoration:none; min-width:220px;}
#programs a:hover {border:solid 1px #7da2ce;
-moz-border-radius:3px; -webkit-border-radius:3px;
box-shadow: inset 0 0 1px #fff; -moz-box-shadow: inset 0 0 1px #fff; -webkit-box-shadow: inset 0 0 1px #fff;
background-color:#cfe3fd;
background: -moz-linear-gradient(top, #dcebfd, #c2dcfd);
background: -webkit-gradient(linear, center top, center bottom, from(#dcebfd), to(#c2dcfd));}
#programs a img {border:0; vertical-align:middle; margin:0 5px 0 0;}

Links menu

As in the previous case, links menu is quite simple. But the interesting part comes in hover state. Each link has horizontal gradient with three stops: dark blue on the left and right side, and a bit lighter blue in the middle. Now, unlike programs menu links, here, every links has inner <span> element which contains text. This span element has one more gradient – vertical linear gradient. It is transparent in the upper half and the lower part goes from very dark blue to almost transparent light blue. The combination of two transparent gradients gives exactly the same look as buttons in Windows 7 link menu.

#links {margin:7px; margin-top:-30px;}
#links li.icon {text-align:center;}
#links a {border:solid 1px transparent; display:block; margin:5px 0; position:relative;
color:#fff; text-decoration:none; min-width:120px;}
#links a:hover {border:solid 1px #000;
-moz-border-radius:3px; -webkit-border-radius:3px;
box-shadow: 0 0 1px #fff; -moz-box-shadow: inset 0 0 1px #fff; -webkit-box-shadow: inset 0 0 1px #fff;
background-color:#658da0;
background: -moz-linear-gradient(center left, rgba(81,115,132,0.55), rgba(121,163,184,0.55) 50%, rgba(81,115,132,0.55));
background: -webkit-gradient(linear, 0% 100%, 100% 100%, from(#517384), color-stop(50%, #79a3b8), to(#517384));
}
#links a span { padding:5px; display:block; }
#links a:hover span { background: -moz-linear-gradient(center top, transparent, transparent 49%, rgba(2,37,58,0.5) 50%, rgba(63,111,135,0.5));
background: -webkit-gradient(linear, center top, center bottom, from(transparent), color-stop(49%, transparent),
color-stop(50%, rgba(2,37,58,0.5)), to(rgba(63,111,135,0.5))); }

Here is the preview, but I suggest you to check out the demo. You can play with backgrounds and see how transparency works.

The code works fine in Firefox 3.6+, Safari and Chrome. It degrades gracefully in Opera and IE. I guess I could optimize it a bit so if you have any suggestions please let me know.

70 Responses

  1. Design Informer 6. April 2010 at 23:26

    Awesome job Janko. The demo looks great. I can’t wait until HTML5 and CSS3 becomes the standard for everyone. :)

  2. Janko 6. April 2010 at 23:36

    Thanks, Jad! I hope that time will come soon :)

  3. paki 6. April 2010 at 23:38

    Great!

  4. Mateus 6. April 2010 at 23:52

    As you’ve said, it’s incredible how much you can achieve with so little CSS3.
    I’m really hoping to see all browsers supporting CSS3 soon!

  5. Lam Nguyen 6. April 2010 at 23:57

    Great looking. But it seem it’s getting problem with the HTTP requests and loading time. I would be better if set the fixed height for each link block and use sprites for the icon. It will load faster. Just thought! I definitely love this one! Thank you!

  6. Goran Mitev 7. April 2010 at 00:52

    That’s amazing dude!

  7. Kawsar Ali 7. April 2010 at 02:00

    This is super cool Janko. Very innovative. Can’t wait til IE9 also supports CSS3. Then we can have all this cool stuff on all browsers.

  8. Richie 7. April 2010 at 07:01

    Nice job, Janko. It looks very cool. I have seen a wordpress theme with such a ‘START MENU’ feature but I’m not sure whether its exactly a CSS3 plugin.

    I will let you know once I find the whereabouts of the theme :)

    Thanks for this wonderful tutorial btw :)

  9. Marco 7. April 2010 at 07:34

    Awesome! You showed the demo to me yesterday, but reading the actual tutorial is pretty interesting too – especially to see why you made several choices.

    CSS3 is pretty cool and you’ve shown another great way to use it. Keep up the great work mate!

  10. iPad Interfaces 7. April 2010 at 08:15

    Oh my! That’s truly awesome job! What is interesting that there is generally nothing more than gradienty, box shadow and border radius. Ohhh! And one element (?) with RGBa. Really impressive!

    Btw. Have you chacked it under IE6?:D Just for curiosity

  11. satishkumar 7. April 2010 at 08:16

    Amazing! Thnx for sharing :)

  12. Jireck 7. April 2010 at 08:27

    GREAT !! !! wonderful job Janko !

    missing some jquery toggle and it’s really "Windows 7 start menu" !!!

  13. Janko 7. April 2010 at 08:59

    Good point Lam. The images are so small that I didn’t think there will be any issues. Thanks!

  14. Janko 7. April 2010 at 09:00

    I really hope that IE9 will be at least close to its competitors :)

  15. Janko 7. April 2010 at 09:02

    Haven’t seen such plugin, please let me know if you find it.

  16. Janko 7. April 2010 at 09:04

    Thanks Marco! I am really glad that you like it.

  17. aravind ajith 7. April 2010 at 09:05

    Wow! Brilliant work my friend. I am so impressed with the output. :)

  18. Janko 7. April 2010 at 09:05

    Naaah, I don’t even wanted to see how creepy it would look like in IE6 :D

  19. Janko 7. April 2010 at 09:06

    I was thinking to extend it with second-level menus, but I wanted to keep it just with CSS3. Makes more fun this way :)

  20. Richard 7. April 2010 at 09:12

    Very impressive – keep up the great work!

  21. Josip 7. April 2010 at 09:26

    Very nice :)

  22. Sorin 7. April 2010 at 09:34

    Wow :D, thanks for the cool tutorial Janko :D

    Best wishes

    Sorin

  23. Andrea Pernici 7. April 2010 at 09:53

    You’re always the best !

  24. Webstandard-Blog 7. April 2010 at 10:20

    Very nice idea Janko.

    You already knew http://webstandard.kulando.de/post/2010/03/24/windows-7-fenster-mit-css3-und-jquery-tutorial-teil-2 – Windows 7 window based on CSS3 & jQuery?

  25. Janko 7. April 2010 at 10:42

    Thanks Aravind!

  26. Janko 7. April 2010 at 10:43

    That looks nice. A few more tuts and we’ll have entire Win 7 created in CSS3 :)

  27. olivier 7. April 2010 at 10:45

    Funny that a windows start menu is not working on IE ;-)
    Here is a WordPress theme with a start menu, but not so nice:
    http://fwd4.me/KPl
    Nice tutorial anyway, thanks for sharing !

  28. Janko 7. April 2010 at 10:59

    Everything around IE is a bit ironic :) Thanks for the link.

    I don’t think this concept should be taken seriously in UI design. My example was more just to test CSS3 and make some effects that can be used further, such as glossy buttons.

  29. iPad Interfaces 7. April 2010 at 11:23

    haha! so take it for a ride: http://ninjadock.com/screens/win7menuunderie6.png :D
    sry, I had to check :P

  30. Janko 7. April 2010 at 11:41

    Hahahha this is awesome, I couldn’t expect more from IE6, thanks for sharing!!

  31. Norman 7. April 2010 at 12:38

    looks great. i did something similar to this a while ago trying to recreate windows 7 windows: http://www.normansblog.de/demos/windows-7-emulation-with-css3-and-jquery/ – Windows 7 with CSS3 and jQuery

  32. Janko 7. April 2010 at 12:43

    Hey Norman this looks great. You should finish it :)

  33. Mike M 7. April 2010 at 15:38

    Nice one! Just so you know, Opera now supports border-radius (-o- not needed).

  34. Cory Mathews 7. April 2010 at 15:39

    you forgot the regular border-radius you have the -moz and -webkit hacks but not the normal one. Thus it does not work correctly in opera, or future versions of Gecko/Webkit

  35. Janko 7. April 2010 at 16:33

    Mike, Cory: that’s a good point, thanks!

  36. Lars Weimar 7. April 2010 at 18:22

    Does anybody find it extremely ironic that this doesn’t really work in Microsoft’s own browser? lololol

  37. Evan Byrne 7. April 2010 at 19:06

    Very nice! The only thing you should change is make the mouse pointer always stay the same. If you try out the start menu in windows the mouse cursor never changes. This makes it feel much more smooth.

  38. Paul 8. April 2010 at 04:40

    In this case, sprites would help because there’s 9 HTTP requests vs. 1 for a sprite. The images being small just makes them a bit easier to combine. ;)

  39. gjperera 8. April 2010 at 05:44

    Very nice…did it work in IE9?

  40. arithok 8. April 2010 at 07:13

    two thumbs up :)

  41. Gaurav Mishra 8. April 2010 at 07:49

    That was Janko at wrap speed.
    Amazing out of box thinking

  42. Janko 8. April 2010 at 08:47

    I haven’t tested it in IE9. I hope it works, otherwise it will be another crappy browser :)

  43. Janko 8. April 2010 at 08:48

    I also thought about it, but decided to follow web conventions for links.

  44. Andreas Dantz 8. April 2010 at 09:57

    Nice tech demo. But who wants his menu to look like a crappy OS? :D

  45. Janko 8. April 2010 at 10:00

    Honestly, I think Win7 is much better that its predecessors. So far I am more that satisfied with it :)

  46. InwebDev 8. April 2010 at 10:28

    Amazing tutorial. Its out of box thinking

  47. Kroc Camen 8. April 2010 at 14:44

    How did you work out the colour, transparency and positions of the gradients to replicate in CSS? Did you take a screenshot of the start menu on a white background and transcribe from there?

  48. Jordan Walker 8. April 2010 at 15:47

    Impressive!

  49. Janko 8. April 2010 at 16:52

    Something like that, I made a screenshot on a light blue background in order to get more vibrant colors than original.

  50. kanwaljit 8. April 2010 at 16:57

    Thats genius stuff, love the article, and thissite design too

  51. Charles Roper 8. April 2010 at 17:54

    Sadly, it doesn’t look great in the current IE9 Platform Preview (although it does degrade gracefully); there are no gradients, no transparency (due to there being no gradients), no box-shadow, and no border-radius. Having said that, you’d not expect it to work because the gradients are implemented as vendor specific properties, as are the borders. I believe IE9 supports border-radius, same as Opera, and it supports rgba, so you could use that as a fallback instead of gradients.

    I don’t really blame MS for not adding gradient support just yet as it’s such a moving target. Both Gecko and Webkit have different implementations, so I’d say MS are wise to hold out until the standard settles.

    It’s also worth pointing out that the IE9 platform preview "represents only a portion of the capabilities that will be in the final IE9 Web platform," so there’s hope that we’ll get more goodies in due course. It’s definitely not a crappy browser and certainly brings new things to the table, such as hardware acceleration: http://blogs.msdn.com/ie/archive/2010/04/07/a-closer-look-at-internet-explorer-9-hardware-acceleration-through-flying-images.aspx

  52. Friguron 8. April 2010 at 18:07

    Why not adding the standard way to define border radius (i.e. just plain "border-radius") instead of the non-standard, somewhat silly and annoying, time-consuming -moz-border-radius -webkit-border-radius ?

    Opera has been able to show border-radius for some time…

    Greetings, and NICE WORK anyway :D

  53. Janko 8. April 2010 at 20:54

    IE (any version) wasn’t taken in consideration in this example, one can always use standard properties instead of vendor specific properties if needed.

    Anyway, interesting thoughts on IE9. It might be that the final version will include at least some of CSS3 properties.

  54. Janko 8. April 2010 at 21:09

    I guess it’s just a bad habit of mine :)

  55. glasgow 8. April 2010 at 22:30

    amazin, you should write a tut for nettuts,

    defo booked marked you blog,

  56. victor teixeira 9. April 2010 at 03:37

    If you use border-radius along with moz-border-radius and webkit-border-radius and it will work with Opera 10.51 without problems.

    I think that gradient should also work.

    Opera has added lots of ccs3 stuff and has a new javascript engine.

  57. DerHorst 9. April 2010 at 04:02

    I dont know what in this tutorial should be "out of the box" thinking.
    And, if at all, it it would be thinking outside the box.

    Anyway, that dont change that this is a nice tutorial and the result looks great and works nice, like nearly all of the things coming out of Jankos hands.
    Thanks and keep the good work coming =)

    BTW:
    In the footer there is a typo:
    "Freebises"

  58. n 13. April 2010 at 00:42

    quite non-semantic use of `div` and `img` :x

  59. john 15. April 2010 at 09:21

    This is awesome.

    I’m hoping that in the future, we can start using CSS3, SVG and Canvas to replace images completely.

    I just hope that future browsers can handle all that rendering mass.

  60. Adam 22. April 2010 at 20:42

    Just curious, why did you add a <span> inside each anchor in the "links" <ul>? You can add the padding from the <span> element to the anchor and have the same effect.

  61. Janko 22. April 2010 at 20:56

    There are two gradient backgrounds in each link on the right side of the menu. The vertical one is applied to anchor and covers the entire are while the other, horizontal, is applied to span and covers the bottom half of the link.

  62. website laten maken 23. April 2010 at 09:06

    Very well done Janko! Look impressive. Are you planning to add the submenu’s to0?

  63. Janko 25. April 2010 at 17:28

    That’s a good idea for another tut :)

  64. Thiago Cavalcanti 26. April 2010 at 00:27

    Looks great from here and it degrades really nicely, congratulations!

    The best part of all this is that we don’t have to wait until every browser has implemented the CSS3 needed to make this work as intended because it degrades so well!

  65. jason 28. April 2010 at 17:32

    help…totally unrelated, but the tutorial that i am using is closed and i’m desperate:

    Your tutorial “Reinventing a Drop Down with CSS and jQuery” works fantastic!

    I am using the script from: Update (29.07.2009): Creating DropDown from SELECT.

    I am using this in an include and have no idea how make the options link out – like a jump menu. Can you help me?

    function createDropDown(){
    var source = $("#source");
    var selected = source.find("option[selected]"); // get selected <option>
    var options = $("option", source); // get all <option> elements
    // create <dl> and <dt> with selected value inside it
    $("body").append(‘<dl id="target" class="dropdown"></dl>’)
    $("#target").append(‘<dt><a href="#">’ + selected.text() +
    ‘<span class="value">’ + selected.val() +
    ‘</span></a></dt>’)
    $("#target").append(‘<dd><ul></ul></dd>’)
    // iterate through all the <option> elements and create UL
    options.each(function(){
    $("#target dd ul").append(‘<li><a href="#">’ +
    $(this).text() + ‘<span class="value">’ +
    $(this).val() + ‘</span></a></li>’);
    });
    }

    $(".dropdown dd ul li a").click(function() {
    var text = $(this).html();
    $(".dropdown dt a").html(text);
    $(".dropdown dd ul").hide();
    var source = $("#source");
    source.val($(this).find("span.value").html())
    });

  66. Kadir 17. June 2010 at 21:37

    Wow. This is great. Thank you.
    I changed it a little for my menu :)

  67. Janko 28. June 2010 at 01:08

    Not sure if I understand the problem, can you email me the details?

  68. Chocolate Lime 19. July 2010 at 21:14

    A really neat tut Janko.

    Have you done anything similar for us Mac lovers?

  69. Frank 26. July 2010 at 15:38

    LOL :’D
    don’t work in explorer, Firefox is simply the best!

  70. mare 17. September 2010 at 15:52

    Google Chrome doesn’t support it well too.. It is not transparent there.. :-(