Submit your widget

Pure CSS3 Animated Menu

Created 12 years ago   Views 27183   downloads 6689    Author Martin Angelov
Pure CSS3 Animated Menu
View DemoDownload
Share |

In this short tutorial, we will be using the power of CSS3 effects and transitions, to build a JavaScript-free animated navigation menu which you can use to add a polished look to your website or template. We will be using some neat features such as the :target pseudo selector and :after elements.


The first step is to define the HTML backbone of the website. We are using HTML5 tags extensively, so we will need to include the HTML5 enabling script for IE in the head section of the document. As it is enclosed in a conditional comment, it is only going to be requested in IE browsers and will not affect the performance of the others:


<!DOCTYPE html>
        <meta charset="utf-8" />

        <title>CSS3 Animated Navigation Menu | Tutorialzine Demo</title>

        <!-- Our CSS stylesheet file -->
        <link rel="stylesheet" href="assets/css/styles.css" />

        <!-- Including the Lobster font from Google's Font Directory -->
        <link rel="stylesheet" href="" />

        <!-- Enabling HTML5 support for Internet Explorer -->
        <!--[if lt IE 9]>
          <script src=""></script>


            <h1>CSS3 Animated Navigation Menu</h1>
            <h2>&laquo; Read and download on Tutorialzine</h2>

            <ul class="fancyNav">
                <li id="home"><a href="#home" class="homeIcon">Home</a></li>
                <li id="news"><a href="#news">News</a></li>
                <li id="about"><a href="#about">About us</a></li>
                <li id="services"><a href="#services">Services</a></li>
                <li id="contact"><a href="#contact">Contact us</a></li>

        <footer>Looks best in Firefox 4, usable everywhere.</footer>


You can notice that we are including a stylesheet from Google APIs. It contains a @font-face declaration and includes the Lobster font into our page, from Google’s Web Font directory, which has grown to include more than 100 wonderful open source fonts, generously hosted by Google.

In the body of the document, we have the header, nav and footer HTML5 tags, which divide the page into three sections with semantic value. We will be concentrating on the UL element inside the nav tag. This is our navigation menu.

The unordered list has a fancyNav class applied to it, which we will be using to limit the effect of the CSS styles that we will be writing in a moment. This will make the code more portable and limit any possible side effects. Another thing to point out is that each of the LI elements has an unique ID, linked to from the anchor elements inside them. This will enable us to use the :target pseudo-class to style the currently selected menu item.

So lets move on to the CSS styles.


You might find it surprising that the navigation menu we are building does not use any images (except for the home icon – a transparent png). Everything is done with CSS3 gradients, box shadows, and multiple backgrounds.

As for browser support, the menu works in the latest versions of Firefox, Chrome, Safari and Opera, while it is still usable in every IE version from 7 onwards. However, it does look best in Firefox 4, as it supports animating :before and :after pseudo elements via the transition property (other browsers are expected to follow suite).

Our CSS styles are defined in assets/styles.css. I would suggest that you download the menu code from the button above, and open that file in a text editor. We will be focusing primarily on the navigation menu, so I will be skipping the boring parts of the file.

Lets start styling the navigation menu! We first write the rules for the unordered list – targeted with the fancyNav class, and the li items:

	/* Affects the UL element */
	overflow: hidden;
	display: inline-block;

	border-radius: 4px;
	-moz-border-radius: 4px;
	-webkit-border-radius: 4px;

	box-shadow: 0 0 4px rgba(255, 255, 255, 0.6);
	-moz-box-shadow: 0 0 4px rgba(255, 255, 255, 0.6);
	-webkit-box-shadow: 0 0 4px rgba(255, 255, 255, 0.6);

.fancyNav li{
	/* Specifying a fallback color and we define CSS3 gradients for the major browsers: */

	background-color: #f0f0f0;
	background-image: -webkit-gradient(linear,left top, left bottom,from(#fefefe), color-stop(0.5,#f0f0f0), color-stop(0.51, #e6e6e6));
	background-image: -moz-linear-gradient(#fefefe 0%, #f0f0f0 50%, #e6e6e6 51%);
	background-image: -o-linear-gradient(#fefefe 0%, #f0f0f0 50%, #e6e6e6 51%);
	background-image: -ms-linear-gradient(#fefefe 0%, #f0f0f0 50%, #e6e6e6 51%);
	background-image: linear-gradient(#fefefe 0%, #f0f0f0 50%, #e6e6e6 51%);

	border-right: 1px solid rgba(9, 9, 9, 0.125);

	/* Adding a 1px inset highlight for a more polished efect: */

	box-shadow: 1px -1px 0 rgba(255, 255, 255, 0.6) inset;
	-moz-box-shadow: 1px -1px 0 rgba(255, 255, 255, 0.6) inset;
	-webkit-box-shadow: 1px -1px 0 rgba(255, 255, 255, 0.6) inset;


	float: left;
	list-style: none;

Notice the huge list of CSS3 gradient syntaxes. All recent versions of Firefox, Chrome and Safari support gradients. With Opera and IE 10 (currently in platform preview mode), also joining in with their latest versions. Initially there were two competing syntaxes, backed by Mozilla (Firefox) on one side and Webkit (Chrome and Safari) on the other, but Firefox’s gradient syntax has been agreed on as the industry standard.

The next step is to use the :after pseudo element to create the dark shadows, displayed when you hover over a menu item:

.fancyNav li:after{

	/* This creates a pseudo element inslide each LI */	


	/* Gradients! */

	background-image:-webkit-gradient(linear, left top, right top, from(rgba(168,168,168,0.5)),color-stop(0.5,rgba(168,168,168,0)), to(rgba(168,168,168,0.5)));
	background-image:-moz-linear-gradient(left, rgba(168,168,168,0.5), rgba(168,168,168,0) 50%, rgba(168,168,168,0.5));
	background-image:-o-linear-gradient(left, rgba(168,168,168,0.5), rgba(168,168,168,0) 50%, rgba(168,168,168,0.5));
	background-image:-ms-linear-gradient(left, rgba(168,168,168,0.5), rgba(168,168,168,0) 50%, rgba(168,168,168,0.5));
	background-image:linear-gradient(left, rgba(168,168,168,0.5), rgba(168,168,168,0) 50%, rgba(168,168,168,0.5));

	/* Creating borders with box-shadow. Useful, as they don't affect the size of the element. */

	box-shadow:-1px 0 0 #a3a3a3,-2px 0 0 #fff,1px 0 0 #a3a3a3,2px 0 0 #fff;
	-moz-box-shadow:-1px 0 0 #a3a3a3,-2px 0 0 #fff,1px 0 0 #a3a3a3,2px 0 0 #fff;
	-webkit-box-shadow:-1px 0 0 #a3a3a3,-2px 0 0 #fff,1px 0 0 #a3a3a3,2px 0 0 #fff;

	/* This will create a smooth transition for the opacity property */

	-moz-transition:0.25s all;
	-webkit-transition:0.25s all;
	-o-transition:0.25s all;
	transition:0.25s all;

The :after declaration creates a real styleable element. It has a smooth horizontal gradient that darkens the menu item when hovered upon. As it is invisible by default (opacity is set to 0), we are using CSS3 transitions to animate it between zero and full opacity, triggered on hover. Unfortunately only Firefox supports animating pseudo elements at this moment, but other browsers are expected to soon introduce this feature.

Next we will be using the :first-child and :last-child pseudo selectors to target the first and last menu items.

/* Treating the first LI and li:after elements separately */

.fancyNav li:first-child{
	border-radius: 4px 0 0 4px;

.fancyNav li:first-child:after,
.fancyNav li.selected:first-child:after{
	box-shadow:1px 0 0 #a3a3a3,2px 0 0 #fff;
	-moz-box-shadow:1px 0 0 #a3a3a3,2px 0 0 #fff;
	-webkit-box-shadow:1px 0 0 #a3a3a3,2px 0 0 #fff;

	border-radius:4px 0 0 4px;

.fancyNav li:last-child{
	border-radius: 0 4px 4px 0;

/* Treating the last LI and li:after elements separately */

.fancyNav li:last-child:after,
.fancyNav li.selected:last-child:after{
	box-shadow:-1px 0 0 #a3a3a3,-2px 0 0 #fff;
	-moz-box-shadow:-1px 0 0 #a3a3a3,-2px 0 0 #fff;
	-webkit-box-shadow:-1px 0 0 #a3a3a3,-2px 0 0 #fff;

	border-radius:0 4px 4px 0;

.fancyNav li:hover:after,
.fancyNav li.selected:after,
.fancyNav li:target:after{
	/* This property triggers the CSS3 transition */

Applying different styles to the first and last items is necessary, as we don’t want to display ugly borders that span outside the menu. We also round the appropriate corners of these elements.

After this we need to apply a fix to the menu. It is to hide the currently selected element when we hover on the menu again:

.fancyNav:hover li.selected:after,
.fancyNav:hover li:target:after{
	/* Hides the targeted li when we are hovering on the UL */

.fancyNav li.selected:hover:after,
.fancyNav li:target:hover:after{
	opacity:1 !important;

And lastly all that is left is to style the anchor elements that reside in the LIs.

/* Styling the anchor elements */

.fancyNav li a{
	color: #5d5d5d;
	display: inline-block;
	font: 20px/1 Lobster,Arial,sans-serif;
	padding: 12px 35px 14px;
	position: relative;
	text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.6);
	text-decoration:none !important;

.fancyNav a.homeIcon{
	background:url('../img/home.png') no-repeat center center;
	display: block;
	overflow: hidden;
	padding-left: 12px;
	padding-right: 12px;
	text-indent: -9999px;
	width: 16px;

With this our animated CSS3 menu is complete!

The article source:

Tag: css3 menu