Create Windows 7 start menu using CSS3 only

April 6, 2010

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.

Let's discuss this on twitter.

70 Comments

  • Design Informer (April 6, 2010)

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

  • Janko (April 6, 2010)

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

  • paki (April 6, 2010)

    Great!

  • Mateus (April 6, 2010)

    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!

  • Lam Nguyen (April 6, 2010)

    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!

  • Goran Mitev (April 7, 2010)

    That’s amazing dude!

  • Kawsar Ali (April 7, 2010)

    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.

  • Richie (April 7, 2010)

    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 :)

  • Marco (April 7, 2010)

    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!

  • iPad Interfaces (April 7, 2010)

    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

  • satishkumar (April 7, 2010)

    Amazing! Thnx for sharing :)

  • Jireck (April 7, 2010)

    GREAT !! !! wonderful job Janko !

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

  • Janko (April 7, 2010)

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

  • Janko (April 7, 2010)

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

  • Janko (April 7, 2010)

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

  • Janko (April 7, 2010)

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

  • aravind ajith (April 7, 2010)

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

  • Janko (April 7, 2010)

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

  • Janko (April 7, 2010)

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

  • Richard (April 7, 2010)

    Very impressive – keep up the great work!

  • Josip (April 7, 2010)

    Very nice :)

  • Sorin (April 7, 2010)

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

    Best wishes

    Sorin

  • Andrea Pernici (April 7, 2010)

    You’re always the best !

  • Webstandard-Blog (April 7, 2010)

    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?

  • Janko (April 7, 2010)

    Thanks Aravind!

  • Janko (April 7, 2010)

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

  • olivier (April 7, 2010)

    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 !

  • Janko (April 7, 2010)

    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.

  • iPad Interfaces (April 7, 2010)

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

  • Janko (April 7, 2010)

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

  • Norman (April 7, 2010)

    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

  • Janko (April 7, 2010)

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

  • Mike M (April 7, 2010)

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

  • Cory Mathews (April 7, 2010)

    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

  • Janko (April 7, 2010)

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

  • Lars Weimar (April 7, 2010)

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

  • Evan Byrne (April 7, 2010)

    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.

  • Paul (April 8, 2010)

    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. ;)

  • gjperera (April 8, 2010)

    Very nice…did it work in IE9?

  • arithok (April 8, 2010)

    two thumbs up :)

  • Gaurav Mishra (April 8, 2010)

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

  • Janko (April 8, 2010)

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

  • Janko (April 8, 2010)

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

  • Andreas Dantz (April 8, 2010)

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

  • Janko (April 8, 2010)

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

  • InwebDev (April 8, 2010)

    Amazing tutorial. Its out of box thinking

  • Kroc Camen (April 8, 2010)

    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?

  • Jordan Walker (April 8, 2010)

    Impressive!

  • Janko (April 8, 2010)

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

  • kanwaljit (April 8, 2010)

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

  • Charles Roper (April 8, 2010)

    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

  • Friguron (April 8, 2010)

    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

  • Janko (April 8, 2010)

    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.

  • Janko (April 8, 2010)

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

  • glasgow (April 8, 2010)

    amazin, you should write a tut for nettuts,

    defo booked marked you blog,

  • victor teixeira (April 9, 2010)

    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.

  • DerHorst (April 9, 2010)

    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"

  • n (April 13, 2010)

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

  • john (April 15, 2010)

    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.

  • Adam (April 22, 2010)

    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.

  • Janko (April 22, 2010)

    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.

  • website laten maken (April 23, 2010)

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

  • Janko (April 25, 2010)

    That’s a good idea for another tut :)

  • Thiago Cavalcanti (April 26, 2010)

    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!

  • jason (April 28, 2010)

    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())
    });

  • Kadir (June 17, 2010)

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

  • Janko (June 28, 2010)

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

  • Chocolate Lime (July 19, 2010)

    A really neat tut Janko.

    Have you done anything similar for us Mac lovers?

  • Frank (July 26, 2010)

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

  • mare (September 17, 2010)

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