Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to slide in divs from off screen into absolute layout using CSS transitions?

I have a grid of absolutely positioned divs (the grid is made up of differently shaped rectangles that fit together to make a large rectangle).

I am trying to animate the display of this grid by having all of the individual rectangles 'fly' into the grid from offscreen. So the rectangles on the left fly in from the left, the ones on the right from the right etc.

I am using CSS3 transitions and when flying in from the top or left it works perfectly, I just use negative margins to position them off screen and then animate this to change to margin-left (or margin-top) = 0 (e.g. the orignal/correct position).

This seems to make more sense than using transforms but please correct me if you think there is a reason that transforms will work/perform better for any reason?

However this obviously won't work for margin-right/margin-top and so i wanted to see if anyone can suggest what the best way to achieve this is from the right and bottom? I can make the parent overflow:hidden and animate the left/top positions which will have the same effect but I wanted to see if there's a generic solution equivalent to negative margins so as to prevent needing separate rules/positions for each off and on screen version? eg when using negative margins i can apply the same negative margin to all boxes that fly in from the same side without having any element specific mark up (but if i animate the top/left then each element will need it's own 'offscreen' position relative to it's final position so it flies in from the right place).

Alternatively if there is a better way in general (CSS3 is fine!) then I would love to hear it!

like image 636
deshg Avatar asked Jun 19 '14 15:06

deshg


2 Answers

Don't animate with margins, always animate with transforms, that is their intended use. Here is a great article on that from Paul Irish

Why moving elements with translate() is better http://paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/

Use overflow-x: hidden to hide the divs coming in from the right. Here is a fiddle I made to show how you can animate with transform without specifying pixel values;

http://jsfiddle.net/P9GNS/3/

HTML

    <div class="box-wrapper loading"><div class="box"></div></div>
    <div class="box-wrapper loading"><div class="box"></div></div>
    <div class="box-wrapper loading"><div class="box"></div></div>
    <div class="box-wrapper loading"><div class="box"></div></div>
    <div class="box-wrapper loading"><div class="box"></div></div>
    <div class="box-wrapper loading"><div class="box"></div></div>

CSS

    body {
        overflow-x: hidden;
    }


    .box-wrapper {
        -webkit-transition-duration: 600ms;
        transition-duration: 600ms;
    }


    .box-wrapper.loading:nth-child(odd) { transform: translate(100%) }
    .box-wrapper.loading:nth-child(even) { transform: translate(-100%) }


    .box-wrapper:nth-child(odd)  .box { background: orange }
    .box-wrapper:nth-child(even) .box { background: red }


    .box {
        margin: auto;
        width: 100px;
        height: 100px;
    }

JAVASCRIPT

    $('.box-wrapper').each(function(index, element) {
        
        setTimeout(function(){
            element.classList.remove('loading');
        }, index * 600);

    });
like image 184
Michael Avatar answered Oct 16 '22 01:10

Michael


Usually transform: translate... gives you better performance on most of the browsers, because they try to render the animation using the GPU.

You can check those results from jsperf.

Anyway another good solution ( without javascript ) would be to attach the animation entirely in CSS with @keyframes and animation: property.

More information on this issue is in this article.

From the guidelines you can read

Use CSS keyframe animation or CSS transitions, if at all possible. The browser can optimize painting and compositing bigtime here.

like image 20
drinchev Avatar answered Oct 16 '22 02:10

drinchev