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. 

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 :


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.

I'm a front-end developer, WordPress developer and trainer. Otherwise coding, cooking and doing yoga. Polish, married to a french guy Joe Vains with whom we live in the very center of Paris.
Follow @PeHaa on twitter and on CodePen.


Comments (26)

    1. 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.

      1. 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%; }
        1. 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 :)

  1. 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

  2. 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

  3. 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.

  4. 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.

Leave a reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.