11

I'm using the jQuery slideToggle function on a site to reveal 'more information' about something. When I trigger the slide, the content is gradually revealed, but is located to the right by about 100 pixels until the end of the animation when it suddenly jumps to the correct position. Going the other way, the content jumps right by the same amount just before it starts its 'hide' animation, then is gradually hidden.

Occurs on IE7/8, FF, Chrome.

Any ideas on how I would fix this?

Thanks in advance.

Darren Oster
  • 9,146
  • 10
  • 48
  • 66

18 Answers18

35

I have found a workaround, but I'm still not sure of the details. It seemed that when the 'overflow: hidden' style was added by jQuery, the effect that a nearby floated element had changed. The workaround was to place a permanent 'overflow: hidden' on the slideToggle'd div, and also a negative margin-left to counterbalance the effect.

I am surprised that changing the overflow value has such an effect on layout, but there you have it...

Darren Oster
  • 9,146
  • 10
  • 48
  • 66
  • In addition to this, I also found that any CSS transition on the element you are trying to toggle can affect this. I had a generic 'all' transition on everything, once I removed it, the problem went. Something to watch out for! – Michael Giovanni Pumo May 22 '14 at 13:53
7

This is just a shot in the dark, but if the function is manipulating the height css property of your element(s), according to this site you have to separate the padding and display:none in your css to keep it from jumping

Jay Corbett
  • 28,091
  • 21
  • 57
  • 74
5

Solved by adding to the toggled div:

overflow: hidden; position: relative; 
Ben
  • 1,853
  • 19
  • 20
3

Does your document contains any DOCTYPE declaration? Without it, some browser render the page in "quirck" mode which doesn't always lead to the result you are expecting..

see here

To make sure your page render as intended, add the following declaration to the top of the page (that is, before the html tag).

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
matdumsa
  • 16,005
  • 1
  • 22
  • 18
3

setting the height/width of the component you want to slide fixes a bug that causes "jumpyness" using a line like (reference):

$('#slider').css('height', $('#slider').height() + 'px');
DanielBlazquez
  • 1,045
  • 1
  • 13
  • 22
  • I had the case of a table in the div which caused jumpiness. This solution worked for in in combination with setting the internal table height to height:100%; – JimP Mar 28 '12 at 14:47
2

I had the same problem with the .slideToggle, and BenAdler is right. Put everything you want to toggle in a div, and set the style for the div to something that contains overflow:hidden and position: relative. It will work fine after that.

Taryn
  • 242,637
  • 56
  • 362
  • 405
MJohnson
  • 21
  • 1
2

I had this exact same problem but only when the hidden element was a <div>. I tried everything on this page but the only thing that worked was using overflow:hidden;.

But the problem with using overflow:hidden; is that the upper & lower spacing created by the paragraph element was suddenly removed thereby making the layout ugly.

I changed my hidden element from a <div> to a <p> and removed the overflow:hidden;... it worked without messing up the layout and the jumping problem did not return.

EDIT:

On a new site I was determined to use a hidden <div> and I discovered some things about this issue...

1) When div contains p or ul or similar the jumping occurs.

2) When the div only contains text, a links and/or images, no jumping animation.

3) Removing all margins & padding from the elements within the hidden div clears up the issue. Other things like line-breaks can be added to compensate for the lack of padding & margins... not ideal but the animation is smooth again.

Sparky
  • 98,165
  • 25
  • 199
  • 285
  • 1
    More specifically, at least in my case, a top margin causes the issue. Bottom margin is not affected by it. – user247702 Nov 04 '11 at 09:09
  • I've made a bug report, including test case, at http://bugs.jquery.com/ticket/10662 – user247702 Nov 04 '11 at 09:59
  • @Stijn, I never thought to try that... but my `

    ` and `

      ` already have 0 top margin. I wonder what happens if the `div` contains several paragraphs so there are bottom margins throughout the middle of the `div`. Thanks for reporting.
    – Sparky Nov 04 '11 at 14:56
1

you can use a structure like this one:

<div class="details">
    <div class="hidden"> [your toggled info] </div>
</div>

and in your css

.details{
    position:relative;
}
.hidden{
    display:none;
}

i think thats it.

your jquery call must be:

$('.hidden').slideToggle("slow");
Himanshu
  • 31,810
  • 31
  • 111
  • 133
1

Try messing with how the element is positioned/displayed/floated. I've had similar problems which were solved by playing with those settings.

Ben Crouse
  • 8,290
  • 5
  • 35
  • 50
1

Just to share a solution that worked for me.

I am using a responsive layout for a site I am working on and essentially using slidetoggle on one of my columns in my layout, the only solution that worked above was setting a fixed width to my content - however as the column widths are dynamic this is not a solution for me.

Wrapping the content I wanted to toggle in an extra <div> and then using slide toggle on the new div seemed to do the trick. Try adding position:relative to original element you were trying to slidetoggle.

Yes, this does add horrible unnecessary markup but it's the only way I could get it to work.

rmorse
  • 736
  • 6
  • 18
1

Adding CSS3 transition/transform properties always solved any jumping issues for me with slideToggle... Example:

-webkit-transform-origin: top;
-moz-transform-origin: top;
-ms-transform-origin: top;
-o-transform-origin: top;
transform-origin: top;

-webkit-transition: transform 0.26s ease;
-moz-transition: transform 0.26s ease;
-ms-transition: transform 0.26s ease;
-o-transition: transform 0.26s ease;
transition: transform 0.26s ease;
transition: -webkit-transform 0.26s ease;
1

I've encountered the same error, solved it by positioning the element with position: relative; width: 709px; The fixed width did the trick.

0

Accidentally I think that the easiest to use solution is to add custom function to jQuery with animate padding/margin-top/bottom too.

//this function is to avoid slideToggle jQuery jump bug.
$.fn.slideShow = function(time,easing) { return $(this).animate({height:'show','margin-top':'show','margin-bottom':'show','padding-top':'show','padding-bottom':'show',opacity:1},time,easing); }
$.fn.slideHide = function(time,easing) {return $(this).animate({height:'hide','margin-top':'hide','margin-bottom':'hide','padding-top':'hide','padding-bottom':'hide',opacity:0},time,easing);  }

And useage example:

$(this).slideShow(320,'easeOutQuart');
$(this).slideHide(320,'easeOutQuart');

My example animated opacity toggle tu, you can modify it as you need.

Adarchy
  • 551
  • 3
  • 7
  • 17
0

The only thing that helped for me: give the content to scroll a width.

0

had the same problem , found a problem maybe someone else had it .

if you have min-height -> than you have a problem with slideToggle

IdanHen
  • 266
  • 3
  • 11
0

I had the same problem, but overflow:hidden and position: relative had no effect. I put margin-bottom: -10px on the element that was toggling in, and it solved the issue.

Sauce
  • 652
  • 6
  • 12
0

I had this issue when using floated elements inside the element that is toggled. Setting a width of 100% against the toggled element fixed this for me. If you wish to use padding then you may also set the box-sizing to border-box.

Relative positioning is not required but you may wish to use overflow: hidden to clear the floated elements.

nfplee
  • 7,643
  • 12
  • 63
  • 124
0

This is an old one but similar problems still exist, below a working solution with a couple more requirements.

http://jsfiddle.net/bfnGu/7/

Francisco Aquino
  • 9,097
  • 1
  • 31
  • 37