Last Updated: June 11, 2021
·
4.378K
· letsallplaygolf

Rid yourself of jumps caused by collapsing margins on hidden elements

I really like the behaviour of collapsable margins on block elements, however, it can be quite annoying when it takes affect on a hidden container which you are sliding/fading into view. Take this, for example:

<h1>Hello</h1>
<div style="display:none">
    <h2>Hidden sub-heading</h2>
</div>

If the hidden div is opened using jQuery:

$('div').slideDown(500);

...the bottom margin of the h1 and the top margin of the h2 won't collapse until the slideDown() animation has completed, resulting in a noticeable 'jump'.

An easy way to rid yourself of this problem is to apply a top and bottom padding of at least 1px to the parent container (in this case, the hidden div), effectively putting a little barrier between the h1 and h2, which stops the margins from collapsing at all.

That's easy enough to do by giving the hidden container a classname and setting top/bottom padding with CSS. For example:

.hidden
{
    display: hidden;
    padding: 1px 0;
}

-

<h1>Hello</h1>
<div class="hidden">
    <h2>Hidden sub-heading</h2>
</div>

In one of my more recent builds, I had a few hidden containers which didn't have any top/bottom padding set via CSS, and I wasn't keen on adding another classname to them, so I wrote a little piece of jQuery to check if the container element had any top/bottom padding before running the slideDown() function. Here is the example, with a nice little link to set it all off.

<h1>Hello</h1>
<div id="more" style="display:none">
    <h2>Hidden sub-heading</h2>
</div>
<p>
    <a href="#" data-target="#more">Show the element with an ID of 'more'!</a>
</p>

-

$('[data-target]').on('click', function(e) {
    e.preventDefault();
    var target_selector = $(this).data('target');
    var target_element = $(target_selector);

    if (target_element.css('paddingTop') == '0px')
        target_element.css({paddingTop: '1px'});

    if (target_element.css('paddingBottom') == '0px')
        target_element.css({paddingBottom: '1px'});

    target_element.slideDown(500);
});

You can see it in action at artlines.co.uk - just click the orange reveal arrows.

I hope this proves handy to a few people!

1 Response
Add your response

Nice, but I would use CSS animations over jQuery ones to help improve performance. Although it requires a little more work to calculate heights etc. as slideDown() does all that for you.

over 1 year ago ·