Creative CSS3 Animation Menus

Being in the mood for experimenting with CSS3, I’d like to show you some creative menu hover effects in today’s tutorial. The idea is to have a simple composition of elements, an icon, a main title and a secondary title, that will be animated on hover using only CSS transitions and animations. We’ll be exploring some different effects for the elements.

Being in the mood for experimenting with CSS3, I’d like to show you some creative menu hover effects in today’s tutorial. The idea is to have a simple composition of elements, an icon, a main title and a secondary title, that will be animated on hover using only CSS transitions and animations. We’ll be exploring some different effects for the elements.

The icons used in the demos are actually a Web Symbols typeface that we’ll include with @font-face. The typeface is done by the Just Be Nice studio.

Tiny break: 📬 Want to stay up to date with frontend and trends in web design? Subscribe and get our Collective newsletter twice a tweek.

The Markup

The HTML structure for the menu will be an unordered list where each item is a link element that consists of an icon span and a content div that will contain the main title and the secondary title:

<ul class="ca-menu">
	<li>
		<a href="#">
			<span class="ca-icon">A</span>
			<div class="ca-content">
				<h2 class="ca-main">Exceptional Service</h2>
				<h3 class="ca-sub">Personalized to your needs</h3>
			</div>
		</a>
	</li>
	...
</ul>

As we are using a symbol font for the icons, we write letters for the icons.

The CSS

The common style for all the examples will be the inclusion of the symbol typeface:

@font-face {
    font-family: 'WebSymbolsRegular';
    src: url('websymbols/websymbols-regular-webfont.eot');
    src: url('websymbols/websymbols-regular-webfont.eot?#iefix') format('embedded-opentype'),
         url('websymbols/websymbols-regular-webfont.woff') format('woff'),
         url('websymbols/websymbols-regular-webfont.ttf') format('truetype'),
         url('websymbols/websymbols-regular-webfont.svg#WebSymbolsRegular') format('svg');
    font-weight: normal;
    font-style: normal;
}

The path of the files is relative to the CSS file, hence, they will be in the folder css/websymbols/.

The great advantage of having a font for the icons is that we can apply all those nice effects to it, for example a text shadow. We can also scale it to our needs.

The style for the unordered list will almost be the same for every example, we’ll just adapt the width of it, so that we can center it on the screen:

.ca-menu{
    padding: 0;
    margin: 20px auto;
    width: 500px;
}

In the following examples, I will show you the styling of the elements that will be subject to the effects.
In the first example we’ll look at the styling of all elements and in the other example we’ll be focusing on the adaptions.

Note: In the following examples I will not write any browser specific prefixes because I don’t want to bloat the CSS, but you’ll find all the necessary prefixes in the demo files.

Example 1

CreativeCSS3Menu_Example1

In this example we’ll have stacked menu where we will change the sizes of the elements and the background color of the whole item.

Let’s define the list item style:

.ca-menu li{
	width: 500px;
	height: 100px;
	overflow: hidden;
	display: block;
	background: #fff;
	box-shadow: 1px 1px 2px rgba(0,0,0,0.2);
	margin-bottom: 4px;
	border-left: 10px solid #000;
	transition: all 300ms ease-in-out;
}
.ca-menu li:last-child{
    margin-bottom: 0px;
}

The transition will be for all properties since we’ll want to change the border color and the background color.

The link element will have the following style:

.ca-menu li a{
    text-align: left;
    display: block;
    width: 100%;
    height: 100%;
    color: #333;
    position:relative;
}

Let’s define the style for the single elements.
The icon span will have the following style, placing it at the left side:

.ca-icon{
    font-family: 'WebSymbolsRegular', cursive;
    font-size: 20px;
    text-shadow: 0px 0px 1px #333;
    line-height: 90px;
    position: absolute;
    width: 90px;
    left: 20px;
    text-align: center;
    transition: all 300ms linear;
}

As you can see, we’ll use the web symbols as the font family. Each letter will be an icon.
The wrapper for the content elements will have the following style:

.ca-content{
    position: absolute;
    left: 120px;
    width: 370px;
    height: 60px;
    top: 20px;
}

The content elements will vary in their font size and have a linear transition:

.ca-main{
    font-size: 30px;
    transition: all 300ms linear;
}
.ca-sub{
    font-size: 14px;
    color: #666;
    transition: all 300ms linear; 
}

And now it comes the interesting part. On hover over the list element we will change the font sizes and the colors:

.ca-menu li:hover{
    border-color: #fff004;
    background: #000;
}
.ca-menu li:hover .ca-icon{
    color: #fff004;
    text-shadow: 0px 0px 1px #fff004;
    font-size: 50px;
}
.ca-menu li:hover .ca-main{
    color: #fff004;
    font-size: 14px;
}
.ca-menu li:hover .ca-sub{
    color: #fff;
    font-size: 30px;
}

Since we defined a transition for each of those elements, the change will be “animated”.

Example 2

CreativeCSS3Menu_Example2
In the second example we’ll add some animations for the content elements. The idea is to animate them from the top and the bottom:

.ca-menu li:hover{
    background: #e1f0fa;
}
.ca-menu li:hover .ca-icon{
    font-size: 40px;
    color: #259add;
    opacity: 0.8;
    text-shadow: 0px 0px 13px #fff;
}
.ca-menu li:hover .ca-main{
    opacity: 1;
    color:#2676ac;
    animation: moveFromTop 300ms ease-in-out;
}
.ca-menu li:hover .ca-sub{
    opacity: 1;
    animation: moveFromBottom 300ms ease-in-out;
}

Let’s define the two animations. The first one will start from putting the respective element 200% down the Y Axis which means that it will be pushed down. Also, it will have an opacity of 0. Then it will animate to the origin by setting the translateY to 0%, basically saying we’ll go back to the point we were initially:

@keyframes moveFromBottom {
    from {
        opacity: 0;
        transform: translateY(200%);
    }
    to {
        opacity: 1;
        transform: translateY(0%);
    }
}

The second animation will move an element from the top with the same principles:

@keyframes moveFromTop {
    from {
        opacity: 0;
        transform: translateY(-200%);
    }
    to {
        opacity: 1;
        transform: translateY(0%);
    }
}

Example 3

CreativeCSS3Menu_Example3
In this example we want to change the background and text color on hover. We will also rotate and enlarge the icon. That we can do with the transform property and by enlarging the font size of the icon:

.ca-menu li:hover{
    background-color: #000;
}
.ca-menu li:hover .ca-icon{
    color: #f900b0;
    font-size: 120px;
    opacity: 0.2;
    left: -20px;
    transform: rotate(20deg);
}
.ca-menu li:hover .ca-main{
    color: #f900b0;
    opacity: 0.8;
}
.ca-menu li:hover .ca-sub{
    color: #fff;
    opacity: 0.8;
}

Example 4

CreativeCSS3Menu_Example4
Example 4 to example 8 will use a different layout for the menu. The items will be floating next to each other:

.ca-menu li{
    width: 200px;
    height: 300px;
    overflow: hidden;
    position: relative;
    float: left;
    border: 5px solid #fff;
    background: #e2f0ff;
    box-shadow: 1px 1px 2px rgba(0,0,0,0.2);
    margin-right: 4px;
    transition: all 300ms linear;
}
.ca-menu li:last-child{
    margin-right: 0px;
}

The icon will be placed on the upper half in the center of the item:

.ca-icon{
    font-family: 'WebSymbolsRegular', cursive;
    color: #c5e4f4;
    font-size: 90px;
    text-shadow: 1px 0px 1px rgba(255,255,255,0.7);
    line-height: 150px;
    position: absolute;
    width: 100%;
    height: 50%;
    left: 0px;
    top: 0px;
    text-align: center;
    transition: all 200ms linear;
}

The content wrapper will be placed on the lower part of the item:

.ca-content{
    position: absolute;
    left: 0px;
    width: 100%;
    height: 50%;
    top: 50%;
}

The main title and the secondary title will have the following style:

.ca-main{
    font-size: 30px;
    color: #005382;
    opacity: 0.8;
    text-align: center;
    transition: all 200ms linear;
}
.ca-sub{
    text-align:center;
    font-size: 14px;
    color: #666;
    line-height: 40px;
    opacity: 0.8;
    transition: all 200ms linear;
}

On hover we want to blur the icon while we slide it from the top, change the background color and slide the content items from the top and bottom:

.ca-menu li:hover{
    background-color: #fff;
}
.ca-menu li:hover .ca-icon{
    text-shadow: 0px 0px 20px #c5e4f4;
    color: transparent;
    animation: moveFromTop 400ms ease;
}
.ca-menu li:hover .ca-main{
    color: #000;
    animation: moveFromTop 300ms ease;
}
.ca-menu li:hover .ca-sub{
    color: #000;
    animation: moveFromBottom 500ms ease;
}

The blurring of the icon happens when we set its color to transparent and give it a text shadow with a lot of fuzziness.
The animations will be the same ones we used in one of the previous examples with the exception of the translate values for the moveFromTop animation. Here we will set the translateY to -300%.

Example 5

CreativeCSS3Menu_Example5
In the fifth example we want to slide the icon in from the left, the title from the right and the secondary title from the bottom:

.ca-menu li:hover{
    background:#fff;
}
.ca-menu li:hover .ca-icon{
    color: #afa379;
    font-size: 90px;
    opacity: 0.1;
    animation: moveFromLeft 400ms ease;
}
.ca-menu li:hover .ca-main{
    color: #afa379;
    animation: moveFromRight 300ms ease;
}
.ca-menu li:hover .ca-sub{
    color: #000;
    animation: moveFromBottom 500ms ease;
}

The moveFromBottom animation we know already, let’s take a look at moveFromLeft that moves the respective element to the left by setting the translateX to -100% and then moves it back to its origin:

@keyframes moveFromLeft{
    from {
        transform: translateX(-100%);
    }
    to {
        transform: translateX(0%);
    }
}

In the moveFromRight animation we’ll set it to translateX(100%) initially.

Example 6

CreativeCSS3Menu_Example6
In this example we want to slide in the title from the left and also rotate it at the same time:

.ca-menu li:hover{
    background-color: #000;
}
.ca-menu li:hover .ca-icon{
    color: #fff;
    font-size: 90px;
}
.ca-menu li:hover .ca-main{
    color: #00ccff;
    animation: moveFromLeftRotate 300ms ease;
}
.ca-menu li:hover .ca-sub{
    color: #fff;
    animation: moveFromBottom 500ms ease;
}

The moveFromLeftRotate animation will move an item and rotate it:

@keyframes moveFromLeftRotate{
    from {
        transform: translateX(-100%) rotate(-90deg);
    }
    to {
        transform: translateX(0%) rotate(0deg);
    }
}

Example 7

CreativeCSS3Menu_Example7
In this example, we’ll set the secondary title to be at the bottom of the item:

.ca-sub{
    text-align:center;
    font-size: 14px;
    color: #666;
    line-height: 40px;
    opacity: 0.8;
    position: absolute;
    bottom: 0;
    width: 100%; 
    transition: all 200ms linear;
}

We want to slide it in from the bottom and change its background color.
The icon will slide in from the bottom while the main title will appear to increase from small to big:

.ca-menu li:hover{
    background-color: #000;
}
.ca-menu li:hover .ca-icon{
    color: #ff2020;
    animation: moveFromBottom 300ms ease;
}
.ca-menu li:hover .ca-main{
    color: #ff2020;
    animation: smallToBig 300ms ease;
}
.ca-menu li:hover .ca-sub{
    color: #000;
    background-color: #ff2020;
    animation: moveFromBottom 500ms ease;
}

The smallToBig animation is an example on how to use the scale transfrom:

@keyframes smallToBig{
    from {
        transform: scale(0.1);
    }
    to {
        transform: scale(1);
    }
}

Example 8

CreativeCSS3Menu_Example8
In this example, we want to enlarge the whole list item when hovering. We’ll do that by scaling it to 1.1.
We also have a special icon span with the ID #heart. This span will be red and on hover we’ll use the smallToBig animation in a special way: we’ll alternate the animation infinitely creating a lovely heart-beat effect.

.ca-menu li:hover{
    background-color: #000;
    z-index:999;   
    transform: scale(1.1);  
}
.ca-menu li:hover .ca-icon{
    color: #ccff00;
    font-size: 90px;
    opacity:0.3;
}
.ca-menu li:hover .ca-icon#heart{
    animation: smallToBig 900ms alternate infinite ease;
}
.ca-menu li:hover .ca-main{
    color: #ccff00;
    animation: smallToBig 300ms ease;
}
.ca-menu li:hover .ca-sub{
    color: #ccff00;
    animation: moveFromBottom 500ms ease;
}

Example 9

CreativeCSS3Menu_Example9
The last two examples will be circles, so we’ll change the style for the list elements:

.ca-menu li{
    width: 230px;
    height: 230px;
    border: 10px solid #f6f6f6;
    overflow: hidden;
    position: relative;
    float:left;
    background: #fff;
    margin-right: 4px;
    box-shadow: 1px 1px 2px rgba(0,0,0,0.2);
    border-radius: 125px;
    transition: all 400ms linear;
}

In order to create a circle we need to set the border radius to half of the element’s outer width/height.
Placing the elements in the list item absolutely and centering them, we’ll do the following on hover:

.ca-menu li:hover{
    background: #f7f7f7;
    border-color: #fff;
    transform: rotate(360deg);
}
.ca-menu li:hover .ca-icon{
    color: #555;
    font-size: 60px;
}
.ca-menu li:hover .ca-main{
    display: none;
}
.ca-menu li:hover .ca-sub{
    opacity: 0.8;
}

The item will be rotated 360 degrees and the main title will disappear, letting the secondary item appear (its opacity was initially set to 0).

Example 10

CreativeCSS3Menu_Example10
In the last example, the list items are going to have a left margin of -48px. This will make overlap. Then on hover, we will scale them and increase the z-index, so that the hovered item stays on top:

.ca-menu li:hover{
    border-color: #333;
    z-index: 999;
    transform: scale(1.1);
}
.ca-menu li:hover .ca-icon{
    color: #000;
    font-size: 60px;
    text-shadow: 0px 0px 1px #000;
    animation: moveFromBottom 300ms ease;
}
.ca-menu li:hover .ca-main{
    color: #000;
    animation: moveFromBottom 500ms ease;
}

And that’s it! I hope you enjoyed these little experiments and find them inspiring and useful!

Please note that these animation and transitions will only work in the latest versions of truly modern web browsers, such as Google Chrome, Apple Safari and Mozilla Firefox.

Manoela Ilic

Manoela is the main tinkerer at Codrops. With a background in coding and passion for all things design, she creates web experiments and keeps frontend professionals informed about the latest trends.

Stay in the loop: Get your dose of frontend twice a week

Fresh news, inspo, code demos, and UI animations—zero fluff, all quality. Make your Mondays and Thursdays creative!

Feedback 122

Comments are closed.
  1. is the @font-face the reason for the swap out of the icon to the regular character and then back again? will the embedded font just not behave within the animation? it’s a very distracting swap during the animation that I can’t imagine isn’t a bug on my viewing in safari. see it here: http://screencast.com/t/SYKiCxx9
    really cool animations if you can resolve the character swap. cheers.

  2. Fantástico. Con cada post me enseñáis algo nuevo. Como dice Ángel me habéis abierto infinitas posibilidades.
    Gracias

  3. Good Work Manoela!

    For @Assadotcom

    please remove this content, those are my tutorials, and does not seem right that they do pass as your inventions or experiments, please delete it immediately from any media including your blog.

  4. That is amazing! When I see this kind of amazing work I just know Web Developers dont need Flash anymore. Sorry Adobe…

  5. Great example to teach css3 animation features, but this style of animation kind of reminds me in a bad way of AweSomeCoolFlashSites from 200X…

  6. Mary Lou, você é simplesmente, FANTÁSTICA eu amo os seus posts.
    Valeu!

    Mary Lou, you are simply FANTASTIC I love your posts.
    Thanks!

  7. Thank you all for the great feedback!
    @Jeremy, that is indeed annoying… are you testing in Safari on a Mac? On Windows it seems fine… Thanks a lot, cheers, ML

  8. css3 is just amazing. I uninstalled flash as soon as i heard animations could be done

  9. very nice demo, but i would still prefer using images or svgs for icons.

    screenreader users would wonder what those letters mean? they mean nothing – and shouldn’t be in the markup.

    a possible solution could be using css after / before pseudo-elements to insert the letters. this way you could avoid screenreaders from reading them out and would keep the presentional elements to the css.

    problem: still some current versions of modern browsers lack support of animations on pseudoelements.

  10. too late for comment 😀
    it’s more full stylish of the blur menu 😉
    ty for times & creativity \m/

    More creativity :-“

  11. You have showcased amazing menus awesomely but i wonder if you could do things like this with images e.g thumbnails?

    And btw, most of the people liked example 9 but i think great work done with example 6 and 10.

  12. Great tutorial, and the examples are amazing. For me one of the best things about CSS3 is the scalability and versatility of it. I love being able to zoom in on an object and watch it scale perfectly as if it was made to be that size.

    I will no doubt be incorporating this technique into one of my designs in the future.

  13. Supeeerrbb.. !!! Mary, I love this collection so much.. Especially example number 2 and of course “the heart beat” animation..Genius..

  14. I want to use your #9 for my virtual CV with a little tweaking. How can I make it have an active link _blank to another page on each of the action circles ?

  15. Really awesome……..

    It would be great if you can provide jquery alternative too for all css3 tutorials/scripts so that it will work on all browsers…

  16. Very Cool.

    How about a jQuery backup as well, for those that are on browsers that don’t support CSS3.

  17. The concept is great, and with some tweaking they could be used for a many different types of project. However without wanting to seem melodramatic some of the examples are nothing short of seizure inducing. I do, however, greatly applaud the use of CSS3 in such a creative way.