O'Reilly

Google Extension Effect with CSS or jQuery or MooTools JavaScript

By on  

Both of the two great browser vendors, Google and Mozilla, have Extensions pages that utilize simple but classy animation effects to enhance the page. One of the extensions used by Google is a basic margin-top animation to switch between two panes: a graphic pane and a detail pane. I've taken a few moments to duplicate that effect with just CSS, and another enhanced version with jQuery and MooTools.

The Base HTML and CSS

I'm using minimal elements within this code since, theoretically, there would be many of these on a given page and large DOM trees can drastically effect page performance:

<div class="item">
	<a href="/angry-birds">
		<div class="item-billboard">
			<img src="angrybirds.jpg" />
			<h3>Angry Birds</h3>
		</div>
		<div class="item-detail">
			<p>There's more detail about the item inside this DIV!</p>
		</div>
	</a>
</div>

Remember that HTML5 says we can wrap block-level elements with A tags, so don't hate on me!

There's a fair amount of base CSS we need too:

.item {
	position: relative;
	width: 240px;
	overflow: hidden;
	border: 1px solid #ccc;
}
	.item {
		height: 200px;
	}
	
	.item a {
		text-decoration: none;
		color: #000;
	}
	
	.item-billboard, .item-detail {
		padding: 10px;
		height: 180px;
	}
	
	.item-billboard {
		margin-top: 0;
		background: #fff;
	}
		.item-billboard h3 {
			font-size: 13px;
			font-weight: bold;
			color: #262626;
			font-family: "Open Sans", arial, sans-serif;
		}
	
	.item-detail {
		background: #ececec;
	}

The only restriction with the CSS above is that we're explicitly setting a lesser height for the billboard and detail blocks because we're adding padding to them. We could use the full 200px height of the parent for each of those blocks, and wrap the content for each in an additional DIV, allowing for animating margin-top to 100%, but that would add 2 extra nodes per block.

The CSS-Only Method

Much like my Google Photo Stack post, the CSS-only version gets us 90% there. Browser-powered CSS animations give us the ability to animate to the second pane...

.item-billboard {
	margin-top: 0;
	background: #fff;
	
	/* add animations! */
	transition-property: margin-top;
	transition-duration: .5s;
}

/* animate on hover */
.itemCss:hover .item-billboard {
	margin-top: -200px;
}

Since the CSS transition settings are on the .billboard elements, the margin will animate both on hover and then back to its original state during mouseleave. Unfortunately you're out of luck if the client doesn't support CSS transitions. That's where we can use MooTools or jQuery to make it happen!

The jQuery and MooTools JavaScript

Overriding the CSS animation with a bit of JavaScript will allow the same animation in older browsers. We can jQuery or MooTools to make that happen:

// MooTools
window.addEvent("domready", function() {
	$$(".itemJs").addEvents({
		mouseenter: function() {
			var billboard = this.retrieve("billboardElement");
			if(!billboard) {
				billboard = this.getElements(".item-billboard")[0];
				this.store("billboardElement", billboard);
			}
			billboard.tween("margin-top", "-200px");
		},
		mouseleave: function() {
			this.retrieve("billboardElement").tween("margin-top", 0);
		}
	});
});

// jQuery
jQuery(document).ready(function() {
	jQuery(".itemJQuery").bind({
		mouseenter: function() {
			var self = jQuery(this), billboard = self.data("billboardElement");
			if(!billboard) {
				billboard = jQuery(jQuery(".item-billboard", this)[0]);
				self.data("billboardElement", billboard);
			}
			jQuery(billboard).stop().animate({
				"margin-top": "-200px"
			});
		},
		mouseleave: function() {
			jQuery(this).data("billboardElement").stop().animate({
				"margin-top": 0
			});
		}
	});
});

In each case, we lazy-find billboard elements when they're hovered over and animate them just as the CSS does. Simple!

I love the design of these blocks by Google. They provide a beautiful default view and allow for more detail when the user shows interest. I can see this strategy and effect being useful in many situations, as behind it is brilliant. A business that sells records could use the same sort of effect, for example. Well done to Google!

O'Reilly Velocity Conference
Save 20% with discount code AFF20

Recent Features

Incredible Demos

  • MooTools Accordion: Mouseover Style

    Everyone loves the MooTools Accordion plugin but I get a lot of requests from readers asking me how to make each accordion item open when the user hovers over the item instead of making the user click. You have two options: hack the original plugin...

  • Spyjax:  Ajax For Evil Using Dojo

    The idea of Spyjax is nothing new. In pasts posts I've covered how you can spy on your user's history with both MooTools and jQuery. Today we'll cover how to check user history using the Dojo Toolkit. The HTML For the sake of this...

Discussion

  1. Alelo

    MT version is the smoothest for me(feeling – Chrome) CSS and jQ are a little bit too fast and dont know, doesnt feel right
    CSS : fasted + “laggy”
    jQ: fast (a little bit too fast)
    MT: perfect(slow and smooth)

    for me

    • Nelson

      I agree with you.
      MooTools has the smoothest experience.

  2. Ah I see you added in stop() to prevent animation queuing! Beat me to it… ;)

    However, can I ask why you have used $.data? Why is there a need to store the element?

    • The alternative is using a query to find the billboard element every time the parent is hovered.

  3. webbeloz

    is an interesting point to make a hidden form .. but the class “item-detail” should stop (fidex) when fully open .. . itemCss: hover. billboard-item {
    margin-top:-200px;
    }

  4. Alex

    For some reason my firefox v11 tab on windows 7 lags somewhat more with mootools than jquery…

  5. A small changes in the example of css:
    A bit more semantic markup, some negative delay with “ease” and another item with “ease-in-out”
    http://jsfiddle.net/kseso/XETSY/2/embedded/result/

  6. I also want to try this effect but i dont have enough knowledge to work with JS and Mootools. Please tell me how and where do i insert the JS code. Please do reply

  7. This works great David, thank you.
    I have implemented it on http://international.anahuacmayab.mx but for some reason on Chrome 21 works buggy (overlapping, blurred text, etc.). The problem seems to happen only when I go to the next billboard before the previous animation ends.
    The Chrome web store actually doesn’t overlap animations, it waits until a billboard’s animation ends before trigger the next one.
    My MooTools skills are very basic. Is possible to delay the billboard’s animation until previous animations ends?
    Thank you in advance.

    • In case someone’s experimenting the same issue, the fix was actually pretty easy. Just added the pseudo :pause(500) to the mouseover event.

      The complete code is like this:

      	$$(".item").addEvent('mouseenter:pause(510)', function(e) {
      		  var billboard = this.retrieve("billboardElement");
      		  if(!billboard) {
      			billboard = this.getElements(".item-billboard")[0];
      			this.store("billboardElement", billboard);
      		  }
      		  billboard.tween("margin-top", "-200px");
      		}
      	);
      	
      	$$(".item").addEvent('mouseleave', function(e) {
      		  this.retrieve("billboardElement").tween("margin-top", 0);
      		}
      	);
      

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Prevent Chrome from Translating a Page

    A while back I shared my favorite Google Chrome extension:  Google Art Project.  I've enjoyed seeing beautiful art when I open a new tab -- it's brought genuine happiness to my day, however small that happiness may be.  About a week ago, however, the art presented had...

  • Create Any Type Of Website With These Multi-Purpose Themes

    We have selected what we believe are the very best multipurpose WordPress themes on the market today. Our list contains a number of best sellers, several newcomers that are proving to be highly popular, and a few themes that are ideal for creating the types of...

  • An Introduction to Static Site Generators

    Static site generators seem to have been becoming more and more popular recently, but they’re not one of those ephemeral novelty things that grow in popularity as quickly as they fall into oblivion shortly after. For over a decade, many different projects — 394 of...

  • Automated Tests for Visual Responsive Layouts

    Today it's all about testing. In 2015, many developers knows about TDD and I personally think that testing is one of the key for quality products. But what about testing in a Front-end environment? How do you guys write your tests for a responsive page or...

  • Getting Dicey With Flexbox

    What if you could build complex CSS layouts in minutes? Flexbox is a new CSS layout spec that makes it easy to construct dynamic layouts. With flexbox, vertical centering, same-height columns, reordering, and direction agnosticism are a piece of cake. There's a popular myth floating around that...