Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore transitions when measuring an elements dimensions

Is there an elegant way to predict the dimension an element will have after the elements transition is complete?

Example:

HTML:

<div id="demo">...</div>

CSS:

#demo {
  max-height: 0;
  overflow:hidden;
  transition: 2s max-height;
}

#demo.expand {
  max-height: 1000px;
}

JS:

 var demo = document.getElementById('demo');
 demo.className = 'expand';
 // Unfortunately the result will be 0px 
 // because the current height is measured
 alert(demo.offsetHeight);

Demo:

codepen

like image 898
jantimon Avatar asked Apr 30 '14 16:04

jantimon


People also ask

Can height be transitioned?

We can't transition height , but we can transition max-height , since it has an explicit value. At any given moment, the actual height of the element will be the minimum of the height and the max-height .

Which properties defines the length of time that a transition takes?

The transition-duration property defines the length of time that a transition takes.

Why is transition-duration not working?

You must set an initial left value for form-container . If there is no initial left value the browser doesn't know from where to animate to the set hover value. This should fix your issue.

How to transition the height of an element?

The height of an element is one CSS property that often needs to be transitioned. Sometimes, we want a part of an element to be collapsed until it is needed. That is, when a button is clicked, the height of an element increases or decreases. See more buttons and bootstrap panels make use of this technique.

Why doesn’t my height transition between two sizes?

You try it out, and… the height doesn’t transition. It snaps between the two sizes as if transition had never been set. After some fiddling, you figure out that this problem only happens when the height starts out or ends up as auto. Percentages, pixel values, any absolute units work as expected.

Can I use a transition on an element with the hidden attribute?

If you’ve ever tried to use a CSS transition on an element with the hidden attribute or display: none;, you know this can be a challenge. I’ve run into this problem a number of times and decided to write an npm package to provide a reusable solution. There are a ton of ways to hide HTML elements.

What is a transition effect in HTML?

When the state of an element is changed, it's pretty cool to have a visual effect to show that an action occurred. Thanks to CSS transitions, we have a wide range of transition effects that can be used on our HTML elements. The height of an element is one CSS property that often needs to be transitioned.


3 Answers

Is there an elegant way to measure the dimension an element will have after the elements transition is complete?

You can use the transitionend event to look at the height of your element after the transition is finished:

$('#demo').on("transitionend", function(e) { 
    console.log($('#demo').height());
}).addClass('expand');

This will get you a value of 20, which I assume is what you are looking for?
jsFiddle

like image 131
CBroe Avatar answered Oct 22 '22 18:10

CBroe


You can check the requested rendering height/width of content through the scrollHeight and scrollWidth properties.

e.g. try adding alert(demo.scrollHeight); to the JS pane.

like image 25
BlakeGru Avatar answered Oct 22 '22 19:10

BlakeGru


BlakeGru's answer works great for the OP's question, but doesn't work for similar problems that I've encountered. For completeness, and in case it's useful for others, here is a general strategy for finding the final dimensions an element will have once any transitions have been completed, before said transitions actually begin.

This example changes the width of an element (with a transition) and gets the height (which is determined automatically by content) that the element will have once the transition has finished.

function resize(element, endingWidth) {
  // First, save any set transitions for later.
  var transitions = window.getComputedStyle(element).transition;
  // Now, disable any transitions so that our calculations will work properly.
  element.style.transition = 'none';
  // Get our current width.
  var startingWidth = element.offsetWidth + 'px';

  // Set a new width.
  element.style.width = endingWidth;
  // And get the element height. Because there are no transitions set, this will be the same height as at the end of any transitions.
  var endingHeight = element.offsetHeight;

  /*
   * Now do whatever calculations we want with the ending height.
   */
  alert(endingHeight);

  // Set the element's width back to when we started, so we have a start point for our transition.
  element.style.width = startingWidth;
  // Force the browser to recalculate the element's dimensions. This seemingly pointless call is absolutely critical for the transition to work.
  element.offsetWidth;

  // Now, we can set our desired transitions and the ending width again, and we're away.
  element.style.transition = transitions;
  element.style.width = endingWidth;
}

Fiddle

The general idea is:

  • Remove any transitions.
  • Make the desired changes to the element's dimensions.
  • Measure whatever final dimensions are required.
  • Reset the element's dimensions to the initial values.
  • Reinstate the transitions.
  • Make the desired changes again.
like image 44
leeman Avatar answered Oct 22 '22 19:10

leeman