jQuery - Animate element that has children absolutely positioned outside it - blinking
Asked Answered
A

4

12

Forgive me if this has been addressed before, couldn't find anything.

I am animating a content bar that that has children absolutely positioned outside it (via negative margins). The idea is that the children will animate with the bar as it expands.

What happens is as soon as the animation starts the children disappear, and then reappear when the animation is complete. It's as if the animation need to complete before the browser knows where to put the children.

I have uploaded a really simple example here, all scripts included on page: http://www.ismailshallis.com/jdemo/

What is actually happening? What are my options to work around this?

Many thanks in advance,

Belinda

Alphabetical answered 6/7, 2009 at 2:43 Comment(0)
S
12

When jquery is animating either the height or width of an element, it will automatically set overflow: hidden on the element while the animation is happening. Since your child element is positioned outside, it's technically part of the overflow. The comment in the jquery source near the code that does this says "//Make sure that nothing sneaks out." If you include the uncompressed jquery source and comment out line 4032 of jquery-1.3.2.js (inside the animate function):

//this.style.overflow = "hidden";

You will see that the animation works the way you intended. I'm not sure of a workaround other than modifying the jquery source by commenting out that line above.

Superfecundation answered 6/7, 2009 at 3:35 Comment(4)
Thank you both for your input. Matt provided the explanation and Jeff the solution, I opted for a wrapper around the lot. Not ideal as I now have to animate two boxes, but at least it works. Thanks!Alphabetical
That was some very good detective work Matt. I learned something new today, thanks!Lipetsk
Wow. Just ran into this problem and your solution fixed it, Matt. Thanks! The line number is naturally incorrect in newer versions of jQuery, but searching for this.style.overflow = "hidden"; found it.Multicolored
Setting the animated element CSS to overflow: visible !important; works, too. Per this answerBombproof
H
7

As of jQuery 1.4.3 there is another solution that does not require modifying jQuery. If you set the 'overflow' style of the element that you are animating as an inline style before starting the animation then jQuery will not set the 'overflow' style to hidden. For example:

<script type="text/javascript">
    $(document).ready(function() {
        $("#box a").click(function() {
            $("#box")

            // Prevents absolutely positioned elements from getting clipped.
            .css('overflow', 'visible')

            .animate({
                height: "410px"
            })

            // Reset the 'overflow' style.  You could also put this in the 
            // animate() callback.
            .css('overflow', '');
        });
    });
</script>
Hester answered 17/11, 2010 at 21:16 Comment(2)
I'm sorry. This trick is pretty old. jQuery's animation has probably changed a lot since version 1.4.3.Hester
Awesome. Worked for me (JQuery 1.10)Baggett
H
1

Well - it seems that it's a function of the browser or jQuery, not necessarily of the way you've constructed your HTML or Javascript. I say this because it seems only the pixel area inside the bounding box of the DOM element seems to be rendered (try moving the text so that half of the text is outside, and half inside... you see a "cut off" piece of text as it animates.)

So here's the work around: It uses a wrapper DIV around "#box" and "#outside" such that both are inside the wrapper's bounding box.

CSS:

    #boxWrapper {
        position: fixed;
        top: 50%;
        left:  50%;
        width: 200px;
        height: 200px;
        margin-left: -100px;
        margin-top: -120px; /* extra 20px for the #outside */
        background:#ccc;
    }

    #box {
        background: #000;
        height:100%;
        width:100%;
        margin-top:20px; /* give 20px for the #outside */
    }

    #outside {
        background:darkblue;
        position: absolute;
        top: 0px;
        right: 0; }

And the HTML:

<div id="boxWrapper">
    <div id="box">
        <a href="#">CLICK ME</a>
        <div id="outside">
            I'm positioned OUTSIDE the box
        </div>
    </div>
</div>

And the Javascript:

<script type="text/javascript">
    $(document).ready(function() {

            $("#box a").click(function(){
                $("#boxWrapper").animate({ 
                        height: "410px",
                        opacity: 0.9,
                        top: "25%"
                      }, 1000 );
                return false;
            });
        }); 

</script>   
Hawthorn answered 6/7, 2009 at 3:47 Comment(0)
F
0

Alternatively, you can indicate your preference that the element remain visible by using the !important specification.

#box {
  overflow: visible !important;
}
Foredo answered 26/8, 2014 at 23:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.