Pseudo elements with custom attributes to create a css3 menu that will bounce

27/08/12

You must have already seen this (what I call “bouncing”) hover effect in navigation menus. Curious how to recreate it easily ?
Below you’ll find my approach, for a simple 1-level menu as well as a drop-down one.
It’s pure css, I use an :after pseudo-element with a custom attribute.
Make sure you’re using a modern browser (support for css3 transitions is required) and click on the image below to see the demo.

Bouncing css3 menu using pseudo elements with custom attributes - demo

The mark-up is typical

<nav class="ph-lift">
<ul>
	<li class="active"><a href="#home" data-title="Home">Home</a></li>
	<li><a href="#portfolio" data-title="My works">My works</a></li>
	<li><a href="#about" data-title="Who am I?">Who am I?</a></li>
	<li><a href="#contact" data-title="Contact me">Contact me</a></li>
</ul>
</nav>

Note that I added a data-title attribute containing the link label to each a.
The idea is to have a li element with overflow:hidden. The first on-hover effect is to change its background color and add some inner shadow with a smooth transition (don’t forget the vendor prefixes !).

nav.ph-lift ul li {
    float: left;
    height: 90px;
    line-height: 90px;
    background: white;
    overflow: hidden;
    transition: all.6s ease; }
    nav.ph-lift ul li:hover {
      box-shadow: 0 0 15px rgba(0, 0, 0, 0.3) inset;
      background: teal; }

With :after pseudo element I generate a “copy” of the link element, that is positioned below the link. For its content I use the “data-title” attribute.
On mouse-hover the link changes its margin-top property (again, with a smooth transition).

	nav.ph-lift ul li a {
      display: block;
      text-decoration: none;
      color: #007e7e;
      padding: 0 45px;
      margin-top: 0;
      transition: all.6s ease; }
    nav.ph-lift ul li:hover a {
      margin-top: -90px;
      color: white;
      text-shadow: 0 1px 2px  black; }
      nav.ph-lift ul li a:after {
        content: attr(data-title);
        display: block; }

In the case of drop-down menu, we can no longer have the li {overflow:hidden}. In this case I change the mark-up:

<nav class="ph-lift1">
<ul>
	<li class="active"><a href="#home" data-title="Home"><span data-title="Home">Home</span></a>
<ul>
	<li><a href="#"><span data-title="Featured">Featured</span></a></li>
	<li><a href="#"><span data-title="Top 10">Top 10</span></a></li>
</ul>
</li>
	<li><a href="#portfolio"><span data-title="My works">My works</span></a>
<ul>
	<li><a href="#"><span data-title="Web design">Web design</span></a></li>
	<li><a href="#"><span data-title="Illustrations">Illustrations</span></a></li>
	<li><a href="#"><span data-title="Patterns">Patterns</span></a></li>
</ul>
</li>
	<li><a href="#"><span data-title="Who am I?">Who am I?</span></a></li>
	<li><a href="#"><span data-title="Contact me">Contact me</span></a>
<ul>
	<li><a href="#"><span data-title="Email me">Email me</span></a></li>
	<li><a href="#"><span data-title="Network">Network</span></a></li>
</ul>
</li>
</ul>
</nav>

The main idea is still the same. Now, I apply overflow:hidden to the a element, and generate the pseudo element for my span.

 nav.ph-lift1 > ul > li {
    float: left; }
  nav.ph-lift1 ul li {
    height: 80px;
    line-height: 80px;
    background: white;
    -webkit-transition: all.6s ease;
    -moz-transition: all.6s ease;
    -o-transition: all.6s ease;
    -ms-transition: all.6s ease;
    transition: all.6s ease; }
    nav.ph-lift1 ul li ul {
      max-height: 0;
      -webkit-transition: all.6s ease;
      -moz-transition: all.6s ease;
      overflow: hidden;
      display: block; }
    nav.ph-lift1 ul li:hover {
      box-shadow: 0 0 15px rgba(0, 0, 0, 0.3) inset;
      background: darkolivegreen; }
    nav.ph-lift1 ul li:hover ul {
      max-height: 300px; }
	nav.ph-lift1 ul li a {
      display: block;
      overflow: hidden;
      text-decoration: none;
      color: #546a2f;
      height: 80px; }
    nav.ph-lift1 ul li ul li a {
      color: #7e7e00; }
    nav.ph-lift1 ul li ul li:hover {
      background: olive; }
	nav.ph-lift1 ul li a span {
        -webkit-transition: all.6s ease;
        -moz-transition: all.6s ease;
        -o-transition: all.6s ease;
        -ms-transition: all.6s ease;
        transition: all.6s ease;
        display: block;
        padding: 0 40px; }
    nav.ph-lift1 ul li:hover > a span {
      margin-top: -80px;
      color: white;
      text-shadow: 0 1px 2px  black; }
      nav.ph-lift1 ul li a span:after {
        content: attr(data-title);
        display: block; }

Don’t hesitate to play with this effect, it’s just a basic idea.
I hope you enjoyed this tutorial, if so – please share with the others. I’m looking forward to your feedback. Thanks.

8 Responses to “Pseudo elements with custom attributes to create a css3 menu that will bounce”

  1. Joe Vains

    Aug 27th, 2012

    WOW. On dirait un truc mieux fait et plus intelligent que… Je ne dirai pas le nom. Juste les initiales. NR. T’es juste WOW.

  2. Anna Paquin

    Aug 29th, 2012

    I was looking for exact this elements to create a css2 menu. so you understand my situation that was helped me lots.

  3. Denis Mckillop

    Sep 23rd, 2012

    great tutorial thanks

  4. Thank you for sharing!

  5. Aakash

    Nov 25th, 2012

    that was neat buddy!! :-)

  6. Ali

    Nov 25th, 2012

    Very nice menu example. Thanks.

  7. modra ideja

    Jan 7th, 2013

    Wow, great menu, can’t wait to use it on my new website :)

  8. nirmal

    Aug 25th, 2013

    awesome .. example.thanks

Leave a Reply