Bubble Effect with CSS

written by aext on November 22, 2009 in CSS & HTML and Popular with 126 comments

You might be familiar with the plugin jQuery Dock which allows developers to create a menu like Apple Dock. Today, you will create a similar menu with bubble effect by using CSS only. Although it doesn’t have as smooth of an effect as jQuery Dock, it’s helpful for those that just want to make a cool menu by using pure CSS. This tutorial includes two methods: CSS sprites (basic) and the image swapping (advanced).

Big thank to Erik Zettersten as an editor.

Check out the demo or download.

Method 1: CSS Sprites


Using CSS sprites is the simplest way to make the bubble effect. You just need to change the background images- and that’s it.

But at first, your HTML should look like this:

    <ul id="bubble">
      <li>
        <a class="icon feed"href="http://feeds2.feedburner.com/prlamnguyen"title="Full RSS Feed">Full RSS Feed</a>
      </li>
      <li>
        <a class="icon email"href="http://feedburner.google.com/fb/a/mailverify?uri=prlamnguyen&loc=en_U"title="Feed via Emal">Feed via email</a>
      </li>
      <li>
        <a class="icon twitter"href="http://twitter.com/prlamnguyen"title="Full RSS Feed">Follow me on Twitter</a>
      </li>
      <li>
        <a class="icon facebook"href="http://facebook.com/duylamng"title="Full RSS Feed">I'm on Facebook</a>
      </li>
      <li>
        <a class="icon delicious"href="http://delicious.com/save"onclick="window.open('http://delicious.com/save?v=5&amp;noui&amp;jump=close&amp;url=http://aext.net&amp;title=AEXT.NET', 'delicious','toolbar=no,width=550,height=550'); return false;"title="Full RSS Feed">Save me</a>
      </li>
      <li>
        <a class="icon technorati"href="http://technorati.com/faves?sub=addfavbtn&add=http://aext.net"title="Full RSS Feed">Fave me</a>
      </li>
    </ul>

After you prepare the image for sprites, it should look like this:

Prepare the image for css sprites

This is the CSS code you need to make up the list of menus and the default background image of links:

#bubble {
    list-style: none;
    margin: 0px;
    padding: 0px;
}
#bubble li {
    display: inline-block;
    margin: 0px;
    padding: 0px;

}

#bubble li a.icon {
    background: url(images/sprites.png) no-repeat;
    border: none;
    display: block;
    width: 128px;
    height: 128px;
    text-indent: -9999px;
}

It’s very important while using CSS sprites to calculate the dimensions of the background images. You have to make sure to be pixel precise. Refer to the image above. You’ll need to use the CSS below to change the background image of link elements.

#bubble li a.feed {
    background-position: -139px -12px;
}
#bubble li a.feed:hover {
    background-position: -13px -12px;
}
#bubble li a.email {
    background-position: -139px -149px;
}
#bubble li a.email:hover {
    background-position: -13px -149px;
}
#bubble li a.twitter {
    background-position: -139px -283px;
}
#bubble li a.twitter:hover {
    background-position: -13px -283px;
}
#bubble li a.facebook {
    background-position: -139px -422px;
}
#bubble li a.facebook:hover {
    background-position: -13px -422px;
}
#bubble li a.delicious {
    background-position: -139px -559px;
}
#bubble li a.delicious:hover {
    background-position: -13px -559px;
}
#bubble li a.technorati {
    background-position: -139px -698px;
}
#bubble li a.technorati:hover {
    background-position: -13px -698px;
}

And that is Method 1: very easy and simple. Now, let’s go to Method 2, the image swapping.

[smartads]

Method 2: The Image Swapping


With this method, you will use more of HTML, and less CSS. Because we will use 2 images for each link, the complete code of HTML is should look something like this:

    <ul id="bubble2">
      <li>
        <a href="http://feeds2.feedburner.com/prlamnguyen"title="Full RSS Feed">
            <img class="small"src="images/feed.png"alt="Full RSS" />
            <img class="large"src="images/feed_large.png"alt="Full RSS" />
        </a>
      </li>
      <li>
        <a href="http://feedburner.google.com/fb/a/mailverify?uri=prlamnguyen&loc=en_U"title="Feed via Emal">
            <img class="small"src="images/email.png"alt="Feed via Emal" />
            <img class="large"src="images/email_large.png"alt="Feed via Emal" />
        </a>
      </li>
      <li>
        <a href="http://twitter.com/prlamnguyen"title="Follow me on Twitter">
            <img class="small"src="images/twitter.png"alt="Follow me on Twitter" />
            <img class="large"src="images/twitter_large.png"alt="Follow me on Twitter" />
        </a>
      </li>
      <li>
        <a href="http://facebook.com/duylamng"title="I'm on Facebook">
            <img class="small"src="images/facebook.png"alt="I'm on Facebook" />
            <img class="large"src="images/facebook_large.png"alt="I'm on Facebook" />
        </a>
      </li>
      <li>
        <a href="http://delicious.com/save"onclick="window.open('http://delicious.com/save?v=5&amp;noui&amp;jump=close&amp;url=http://aext.net&amp;title=AEXT.NET', 'delicious','toolbar=no,width=550,height=550'); return false;"title="Save me">
            <img class="small"src="images/delicious.png"alt="Save me" />
            <img class="large"src="images/delicious_large.png"alt="Save me" />
        </a>
      </li>
      <li>
        <a href="http://technorati.com/faves?sub=addfavbtn&add=http://aext.net"title="Fave me on Technorati">
            <img class="small"src="images/technorati.png"alt="Fave me on Technorati" />
            <img class="large"src="images/technorati_large.png"alt="Fave me on Technorati" />
        </a>
      </li>
    </ul>

In this method, we will make some changes. The hover effect will make the hover button stay on top of others. The difference between method 1 and this one is that you have to set the height and width for <li> elements. Why? Because we don’t want the list moving and changing sizes when the mouse is over it. So, the CSS code for the list is:

#bubble2 {
    list-style: none;
    margin: 20px 0px 0px;
    padding: 0px;
}
#bubble2 li {
    display: inline-block;
    margin: 0px 5px;
    padding: 0px;
    width: 72px;
    height: 72px;
}

72px is the size of small images. You can set it bigger, but don’t make it too big.

CSS for the links is:

#bubble2 li a img {
    position: relative;
    border: none;
}

#bubble2 li a img.large {
    display: none;
}

#bubble2 li a:hover img.small {
    display: none;
    z-index: 0;
}

#bubble2 li a:hover img.large {
    display: block;
    margin-top: -28px;
    margin-left: -28px;
    z-index: 1000;
}

Remember to set position of the images to relative, because we will set z-index for the large images when mouse over is larger then other, and the z-index works only with position relative or absolute.

native image changing

When the mouse is overtop, we will set margin of images to -28px because when we enlarge the images, we want the large one have the center same as the small one. It’s very important to see the zoom effect. The amount of pixel we need to margin is calculated as: margin-top= – (height of large – height of small)/2 and margin-left= – (width of large – width of small)/2.

Finally, add these code to your HTML file to display correct list in IE:

<!--[if IE 7]> <style type="text/css"> #bubble li, #bubble2 li {     display: inline; } </style> <![endif]-->

And that’s it.


You can use z-index for method one, too. This tutorial just separates the two methods so you can choose. You can choose between two methods above: one you have to write more CSS code but less HTML, another one you have write more HTML code but less CSS code.