From our sponsor: Ready to show your plugin skills? Enter the Penpot Plugins Contest (Nov 15-Dec 15) to win cash prizes!
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
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
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
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
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
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
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
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
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
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
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.
Amazingly amazing !
Wow.. just amazing. Love it.
bro, is this some kind of vodoo css shit?! WOW, my jaw just dropped.
amazing!
r.
just saw this site and I totally love it, amazing design and tutorial. Nice work guys 😀
hello,
great tutorial! but i have a quick question,
for some reason, when i keep hovering over the elements, at one point the screen will flash black for a split second.
is there a way to resolve this? unfortunately i get that with the 4th, 6th and 7th styles.
thanks!
Thank you very much for wonderful scripts, appreciate your taste and intelligence.
These transitions are so sick and an excellent starting point for learning CSS3.
thanks for this…
I tried integrating this into a website, in which I just gave animation to a simple text. But it doesn’t work for me in chrome or IE but works perfectly in Mozilla.
Any inputs?
I have a strong argument about this effects with my friend. He claims, there is a JQuery used for this. I’ve checked the code and there is a link to JQ at the end of body tag. But when I removed it, effects still working. Is this JQ link only for website, not for menu effects? I need an explanation, I want to win this ‘battle’ with my friend. Beside that, thank you for those animations. There are stunning. I just wish that all the browsers wereup to date :))) THX
You won! 🙂 Cheers, ML
Exist a way to can show this amazing css3 on IE?, I try everything, and not work, my web client insist on 100% compatibility!
I would have to agree, this is some pretty cool stuff
Awesome~~
Wow such a nice animation for menus. I never thought this would be easy in CSS3.
wow……. beautyfull…. thank u very much.. it halp on my design.. thank u…
Awesome!
I just adopted on my site.
Thanks!
Thanks for sharing!
Example 8 is really nice
Amazing! I’ve been working with this today, but it doesn’t quite center how I want it too, but it doesn’t look too bad. Thanks so much!