Loading Effects for Grid Items with CSS Animations

Some inspiration for loading effects of grid items using CSS animations.
Grid Loading Effects

From our sponsor: Reach inboxes when it matters most. Instantly deliver transactional emails to your customers.

Today we’d like to share some loading effects for grid items with you. The idea is to show items in a grid with an animation once they are in the viewport. The possibilities are infinite and we’d like to give you some inspiration. Some of the effects are from the awesome CSS3 scroll effects by Hakim El Hattab and the idea is inspired by the tile animation seen in the Google Plus app.

Since Masonry is a popular library for laying out grids, we thought it might be a good idea to use it in this demo. If you’d like to use something else or no library at all, you’ll have to remove the initialization from the script and adjust the selectors etc. That should be pretty straightforward.

Please note: this only works as intended in browsers that support the respective CSS properties. Modern browsers only!

The beautiful illustrations featured in the demos are by Erika Mackley. Visit her website Erika Noel Design or check out her shop. If you’d like your artwork to be featured in one of our demos just contact us.

So, we’ll use an unordered list for the grid and we’ll simply add the respective effect class:

<ul class="grid effect-4" id="grid">
	<li><a href="http://drbl.in/fWMM"><img src="images/1.jpg"></a></li>
	<li><a href="http://drbl.in/fWPV"><img src="images/2.jpg"></a></li>
	<li><a href="http://drbl.in/fWMT"><img src="images/3.jpg"></a></li>
	<li><a href="http://drbl.in/fQdt"><img src="images/4.png"></a></li>
	<!-- ... -->

The idea is to add a class to the items already shown in the viewport when we load the page. The items that will appear when we scroll them into the viewport will get a class called animate. In the CSS we define the animation that will happen for each effect and the individual styles that are needed:

/* Effect 4: fall perspective */
.grid.effect-4 {
	perspective: 1300px;

.grid.effect-4 li {
	transform-style: preserve-3d;

.grid.effect-4 li.animate {
	transform: translateZ(400px) translateY(300px) rotateX(-90deg);
	animation: fallPerspective .8s ease-in-out forwards;

@keyframes fallPerspective {
	100% { transform: translateZ(0px) translateY(0px) rotateX(0deg); opacity: 1; }

There are a couple of things that we can set. For adding some randomness, you can define a minimum and a maximum duration of the animation. Items that are appearing in the viewport will have an animation duration between those values. The viewportFactor defines how much of the appearing item has to be visible in order to trigger the animation. For example, if we’d use a value of 0, this would mean that it would add the animation class as soon as the item is in the viewport. If we were to use the value of 1, the animation would only be triggered when we see all of the item in the viewport (100% of it).

new AnimOnScroll( document.getElementById( 'grid' ), {
		minDuration : 0.4,
		maxDuration : 0.7,
		viewportFactor : 0.2
	} );

Note that we had to remove the transitions for Masonry so that there’s no conflict with the animations.

I hope you enjoyed this little experiment and find it inspiring!

Tagged with:

Mary Lou

ML is a freelance web designer and developer with a passion for interaction design. She studied Cognitive Science and Computational Logic and has a weakness for the smell of freshly ground peppercorns.


Stay up to date with the latest web design and development news and relevant updates from Codrops.

CSS Reference

Learn about all important CSS properties from the basics with our extensive and easy-to-read CSS Reference.

It doesn't matter if you are a beginner or intermediate, start learning CSS now.

Feedback 116

Comments are closed.
  1. hi guys
    im trying to work with this beautiful effect but i get this error at consol

    Uncaught ReferenceError: ImagesLoaded is not defined


    i have the imageloaded.js and its well referenced in the header.

    can someone show me a way to solve this ?

    thank you .

  2. i HATE that you dont do this cool stuff with mootools 🙁
    i would use so much of this…

  3. Hi,
    it is a very nice plugin thx for develop.

    But I have one question.
    How can I configure to show only one column like?

    My text1
    My text2
    My text3

    Hope you can help me.

  4. Thank you for this tutorial! But how can i animate even the first elements when the page loads?

    • You need to modify plugin 🙂 replace code from line 106-111 in AnimOnScroll.js

      self.items.forEach( function( el, i ) {
      if( inViewport( el ) ) {
      classie.add( el, 'animate' );
      } );

  5. Thank you so much for featuring my work and crediting me on your tutorial!! 🙂

    • Is possible you need to replace line 89 whit this:
      this.items = this.el.toArray();

      and your init code will looks like:

      new AnimOnScroll( $('.yourBoxClass'), {
      minDuration : 0.4,
      maxDuration : 0.7,
      viewportFactor : 0.2
      } );

      Basic change is to select all items with this class 🙂

  6. I love these demo’s and as a matter of fact i love Codrops. I really wish though you would use JQuery in your examples… The whole world uses JQuery nowadays and the JS code would be much compact. Keep it up ! Cheers

  7. Hey Manoela, great script. We are having issues in Safari, and I cannot nail what the issue is.
    I initially, had to change : *, *:after, *:before { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } from * to li ( it was affecting footer li list )

    Link to issue ( please view in Safari ) Grid Loading

    Only affects Safari, the 3rd row of loaded grid items are zoomed weirdly. Any suggestions

  8. LOL another Steve . G’day 🙂

    For our purposes we used grid effect 5

    The fix was hard to track down, simple to implement.

    .grid.effect-5 li.animate {
    -webkit-transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
    transform-style: preserve-3d;
    /*-webkit-transform-origin: 50% 50% -300px;
    -moz-transform-origin: 50% 50% -300px;
    transform-origin: 50% 50% -300px;*/
    -webkit-transform: rotateX(-180deg);
    -moz-transform: rotateX(-180deg);
    transform: rotateX(-180deg);
    -webkit-animation: fly .8s ease-in-out forwards;
    -moz-animation: fly .8s ease-in-out forwards;
    animation: fly .8s ease-in-out forwards;

  9. Hi all, thanks for this awesomness ML!!

    I just wanted to ask, can one do this effect on a series of divs instead of list items?

    Thanks everyone!

  10. I can’t get this to work, I just get the following errors:

    TypeError: EventEmitter is not a constructor
    imagesLoaded( this.el, function() {
    [AnimOnScroll.js (line 96)]

    ReferenceError: imagesLoaded is not defined
    imagesLoaded( this.el, function() {
    [AnimOnScroll.js (line 96)]

    The js files are being called in the following order: imagesloaded.js, classie.js, AnimOnScroll.js

    I have got version 1.8.2 jQuery also being included above these.

    Any help would be appreciated.


  11. I had troubles with AnimOnScroll.js setting the ‘shown’ class on each element immediately. For some reason it set the ENTIRE website document length as the view port height in the client variable. I got it to work for me by editing the getViewportH function:
    var client = docElem[‘clientHeight]
    var client = document.getElementsByTagName(‘body’)[0].clientHeight

    Hope this helps someone.

    • Man, your code doesn’t work. Can you please give exact codes you used? I tried to implement above one you gave but doesn’t work!

  12. Its posible to add more columns, because only i have two columns and i want four, thank you