Css-only Lavalamp-like Fancy Menu Effect

Lavalamp-like menu effect - css-only - tutorial preview

This time let’s get inspired by the sliding menu effect, also known as the Lavalamp effect (ex. here). We’ll recreate it with pure css – using css3 transitions and the general sibling combinator selector. Below we’ll discuss three simple examples (make sure to see the demo first).

Step 1 – Prerequisites

We use a Unica One google web font. In the “heart & arrow” example we use three images combined into a sprite image as below :


Step 2 – HTML

For each of the three examples the html is the same. We’ll just switch the ph-line-nav class name to ph-dot-nav and ph-heart-nav.

<div class="nav ph-line-nav">
  <a href="#">Home</a>
  <a href="#">About</a>
  <a href="#">Gallery</a>
  <a href="#">Contact</a>
  <div class="effect"></div>

The general sibling selector uses a tilde character combinator (E ~ F) and matches elements that are siblings of a given element. The elements don’t have to be adjacent siblings but the first element (E) has to occur before the second (F) one. They also have to share the same parent.
That’s why in the markup below the <a> elements and the div.effect are nested together within a div.nav.

Step 3 – CSS – all examples

Let’s start with the styles that are common for all three examples. The parent element div.nav is positioned relatively. The <a> elements are adjacent floats.
(Note that we omit the vendor prefixes for the sake of simplicity).

.nav {
  overflow: hidden;
  position: relative;
  width: 480px; }
  .nav a {
    display: block;
    position: relative;
    float: left;
    padding: 1em 0 2em;
    width: 25%;
    text-decoration: none;
    color: #393939;
    transition: .7s; }
    .nav a:hover {
      color: #c6342e; }

The crucial part of the lavalamp-like effect happens here :

.effect {
  position: absolute;
  left: -12.5%;
  transition: 0.7s ease-in-out; }
.nav a:nth-child(1):hover ~ .effect {
  left: 12.5%; /* the middle of the first <a> */}
.nav a:nth-child(2):hover ~ .effect {
  left: 37.5%;  /* the middle of the second <a> */ }
.nav a:nth-child(3):hover ~ .effect {
  left: 62.5%; /* the middle of the third <a> */}
.nav a:nth-child(4):hover ~ .effect {
  left: 87.5%; /* the middle of the forth <a> */}

When the mouse is over one of the < a > elements, the div.effect moves smoothly toward its middle.
Don’t hesitate to experiment with the transition-timing-function (ex. here). Here we use the “ease-in-out” function so that the transition starts and end slow.

Step 4 – Into the details (1)

Let’s start with the easiest example, the one with a floating line.
You just have to define the dimensions and colors of the line and position it vertically.

.ph-line-nav .effect {
  width: 90px;
  height: 2px;
  bottom: 36px;
  background: #c6342e;
  box-shadow: 0 1px 0 white; 

In each case we will set the margin-left equal to the half the length of the element so that it is always centered with the hovered link, see the image below :

Step 5 – Into the details (2)

Now, let’s discuss the effect with the dot. We add a horizontal 1px height line to the div.nav. To do so we make use of the :after pseudo-element. We also add little dots, positioned on the line below each menu item, again we use :after pesudo-elements. The div.effect is now a 10px circle and its properties are analogous to those from the previous example.

.ph-dot-nav:after {
  content: "";
  display: block;
  position: absolute;
  width: 100%;
  height: 1px;
  background: #c6342e;
  bottom: 40px; }
.ph-dot-nav a:after {
  content: "";
  position: absolute;
  width: 4px;
  height: 4px;
  bottom: 38px;
  left: 50%;
  margin-left: -2px; 
  background: #c6342e;
  border-radius: 100%; }
.ph-dot-nav .effect {
  width: 10px;
  height: 10px;
  bottom: 36px; 
  margin-left: -5px;
  background: #c6342e;
  border-radius: 100%; }

Step 6 – Into the details (3)

Finally, let’s have a look at the heart-and-arrow example. The heart is composed of two elements, added as :before (the left half of the heart) and :after (the right one) pseudo-elements. The a:after has z-index set to 1 so that it is positioned above the arrow – that makes the trick works :)

.ph-heart-nav .effect, .ph-heart-nav a:after, .ph-heart-nav a:before {
  background: url('../images/heart.png') no-repeat; }

.ph-heart-nav .effect {
  position: absolute;
  bottom: 26px;
  background-position: 0 0;
  height: 8px;
  width: 62px; 
  margin-left:-31px; }

.ph-heart-nav a:before, .ph-heart-nav a:after {
  content: "";
  display: block;
  position: absolute;
  left: 50%;
  bottom: 20px;
  background-position: -62px 0;
  height: 20px;
  width: 11px;
  margin-left: -11px; }

.ph-heart-nav a:after {
  z-index: 1;
  background-position: -73px 0; }

Thats all – I hope you enjoyed this tutorial and got inspired. Looking forward to your comments. Thanks.

Terms of use :

You may use the effects demonstrated in tutorials in your own work, both commercial or non-commercial without any attribution. You may not reproduce entire nor large parts of our tutorials. The outcome of our tutorials may not be re-saled nor redistributed.

About the author

I'm a web designer and a front-end developer. I particularly like writing tutorials (maybe because I was a prof in my previous life...). My other speciality is creating seamless patterns for Photoshop and Illustrator. I'm Polish, living with Joe Vains in the center of Paris. Follow @PeHaa on twitter and on dribbble.


View all articles by PeHaa


  1. speedy

    WOW…. nice one.. thanks for tutorial )

  2. aleguarita

    Nice one!
    I’ll use it, for sure :)

  3. Michael

    Cheers from Poland :)

  4. this is simply useful techniques you have for development skills improvements. thanks

  5. Hey.
    You can do it without any extra markup. Just use pseudo-element and fake transitions on it.

    See it: http://codepen.io/iamvdo/pen/GsIxk

  6. humm, really impressive.

    I just tested it in FF 17.0, Is this working cross-browser??

  7. Chrysto Panayotov


    Great tut. Here is another menu like lava lamp http://codepen.io/burnandbass/pen/cvdjG :)

  8. Thanks, you open my eyes a little bit wider about the possibilities of CSS3

  9. mirela

    your site dont works in explorer 7 and 8 so…do something

    • looncraz

      Then don’t use garbage browsers, silly. Internet Explorer (<9)makes for a poor support target. I would just tell users to use a real browser, but I always make sure my sites function in IE – regardless of how bad it usually looks.

  10. chro

    Cheers from korea :)

  11. cool man, i used something like this on a project last year it was called a minitab slider, it looked very similar, this ones a tad slower to slide – nice post good few examples well planned :)

  12. Amazing…Keep IT UP!! :)

  13. Ali

    Very nice menu examples. Thanks for tutorial. :)

  14. fei

    thanks! very nice work..

  15. Pritesh

    This is great. Can you tell me how I can retain effect on ‘selected’ menu?

    • ADI

      I want know that too. How to retain the effect on selected menu?

      • Hi, you can use a ‘active’ class and add some styles for this class, for example

        .nav .active {
        	    color: #c6342e; }


        	.nav a:nth-child(1):hover ~ .effect,  a:nth-child(1).active ~ .effect {
        	  left: 12.5%; }
        	.nav a:nth-child(2):hover ~ .effect,  a:nth-child(2).active ~ .effect {
        	  left: 37.5%; }
        	.nav a:nth-child(3):hover ~ .effect,  a:nth-child(3).active ~ .effect {
        	  left: 62.5%; }
        	.nav a:nth-child(4):hover ~ .effect,  a:nth-child(4).active ~ .effect {
        	  left: 87.5%; }
        • Ullistrator

          The additional .nav class is important to have for the :hover selector so it can be stronger than the .active one. Just wanted to stress that as I was pretty confused that not too much good happened when I simply duplicated my selectors replacing :hover with .active :)

  16. Your comment is awaiting moderation.
    Hey, awesome menu!
    I really want to use it, and i have it on a hidden test page on my site… just wondering, how do you change the width of the menu?
    So more Items can be on the first row?
    Thanks, please try to get back to me ASAP!
    -Christian From Doolgo.com

  17. salem

    awesome tutorial. I’ll use this for my project. Thanks for sharing.

  18. ariel

    How do I add an additional menu button?

  19. Marilyn

    HI I was wondering how can you have the arrow/dot stick on the active link when clicked? Ex. If you click on about how do you make it stay on about? Thanks

  20. Jigar

    Hey @Christian . i think you have a problem when you add new menu.when you add new menu it will goes bottom of rest of four menu. i have a solution just go to css file in that .nav a{……….width:25%; } instead of 25% change it to lets say 20%. thats it.
    thank you.

  21. Hi, I have been searching for such solution and following your tutorial no doubt you put such awesome efforts here as lava-lamp menu.

    My issue: There are 4 menu items in your example so you divided them 25% of each within 100%, but I have 6 menu items in my project I am so weak to perform mathematics do you have some solution if we have more than 4 items such as I mentioned here.

    Many thanks.

  22. wasi

    Awesome Effect……. I’ll use this for my project. Many Thanks For Sharing….. :( :) :P :D <3

Leave a Comment

Share This