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: Get started on your Squarespace website with a free trial

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,
    Very good job !

    I need to hide or show elements but I cannot use the Masonry’s ‘reload’ method to replace my elements. Can you tell me how I have to do ?

    • I second this. I can’t seem to get them to hide and reload or use any of Masonry’s functionality. I looked inside the object prototype and see masonry but can’t use any of the methods.

  2. can u help me to use this awesome effect to wordpress loop? i have an infinite loop and i think is fabolous to apply this effect when scroll..

  3. Nice work here, code runs prefect on my site, but there is one small question when i put a div(with certain height) above ul, so i can scroll my ‘div’ alone not the whole page, but it doesnt load more in div, only body.

  4. Great work!

    Im having a problem with adding a hover state on the images which gets loaded in. The Visible items are working, but not the ones coming into view from the bottom.

    Seems to work OK in firefox, but not in Chrome+Safari+Opera. Removing the keyframe animation does the trick, but that is of course not an option;)

    Any ideas?

  5. How can we make the opposite, I mean the fade out effect if we scroll up again to the page????

    • You need to check if element is out of viewport and if has class “animate” and “shown” , remove this classes.

  6. This is beautiful! Is there any way to make the layout full screen width? Maybe a 4-6 column layout?

    Thank you for sharing this!

    • component.css line 1
      .grid {
      max-width: 1800px; //orwhatever you like depending on element widths

    • But only changing the grid width breaks the mobile layout, where I could see 1 column now there are three of them.

    • Solved with some media queries for the grid, where width is a fraction of how many columns you want to show on each breakpoint

      @media only screen and (min-width: 1301px) {
      .grid li { width: 25%; }
      @media only screen and (min-width: 901px) and (max-width: 1300px) {
      .grid li { width: 33%; }
      @media only screen and (min-width: 481px) and (max-width: 900px) {
      .grid li { width: 50%; }
      @media only screen and (min-width: 300px) and (max-width: 480px) {
      .grid li { width: 100%; }

  7. Hi guys, I like your stuff and its been very helpful. I always want to promote the site by sharing content here but it seems the share buttons are difficult to see! Watsup?

  8. Hello,
    thanks for this!! 🙂
    But how to load images for example 9 to 9 to save server bandwidth?


    • ….Ok I try use this with my php script for load image from folder, but is very slow, for 3 minutes page blank ( 1200 images) after this works! 🙂
      Dont save sever bandwidth but for now is ok!

      Any ideas for reduce times to load images?

  9. Thanks for a great tutorial… I want to do a same thing for my webpage but here u are inserting only images in grid but i require my div to be loaded inside grid.. how can i do?? can anyone help me.. pls pls pls

  10. Don’t know but I only can see 2 columns layout (as if the third column was hidden). Is anyone know why?

    Btw, nice work Mary Lou, the transitions are beautiful.

  11. I tried using the transitions. They work perfect when fullscreen. It do not work on responsive. I need to make the page responsive, so that these transitions work in phone tooo. Please Please let me know, if any solution.

  12. Hi guys I am trying to integrate this plugin with “thumbnai grid with expan preview” from here but those two seman like not going along for some reason, could someone help me with this , please ?

  13. One of my most favourite posts on this site. just stunning work!
    I’m using technique, inspired by Demo 6, and it all works well, but I don’t like how it looks on touch-enabled devices.

    The problem is that scroll event isn’t fired continuously, but only at the end of the user’s action (I’m sure you’re well aware of it).
    Did you managed to make it more natural on the mobile? (Meaning, that images are loaded continuously as user’s scrolling)

    If you like, I could show you my work when I’m finished.

  14. Thx for this mary Lou,

    as I have 3 grids in 3 tabs, how can I init the 3 id’s ? #grid, #grid2, #grid3 .Please?

    Great work anyway.

  15. Im trying to use this effect with 3 images across. I have set my container to width:1028px, with the first two containers at 348px, and the last at 332px,

    Like this:

    ___________________________container width:1028px_____________________________
    _____div1 width 348px_____ _____div2 width 348px_____ ___div3 width 332px___

    and it always bumps down div3 to the next line.

    Any help?