One common situation in web developing is that you want to expand and collapse an element (maybe a DIV) with a smooth animation. It’s a common request because having a smooth animation helps the user to follow what happens on the page without being disorientated by fast changes.
You can easily obtain a smooth animation using CSS transition in all modern browsers, so there’s not much to do except a simple CSS rule. But CSS animations work only if you know exactly the initial and the final value of your property and if you have a DIV with some text inside you can’t now the exact final height.
So the problem is the need to have the height value at the right time and use it properly. Well, here’s my minimal example that solves everything using pure Javascript (any framework is required).
In the example page we have a single div called “div” with a fixed width and some colors to make thing more visible in the example. There are also two buttons that call the expand and collapse javascript functions.
In my example the expand function takes a string and pass it to the init function, the most important function in my three function singleton object 🙂
The init displays as block the element. This is necessary because the browser will compute the actual height only if the element is rendered on page. Then it stores the element’s offsetHeight in a data attribute. You could store this value everywhere you want, even in a Javascript variable, but I preferred to store it directly into the element because so I don’t need to manage other Javascript objects.
So that we know our DIV’s height we set the “smooth” class on it and set the height to zero. You could obviously set the DIV’s class name DIV directly in the HTML code, but I think it’s a good idea to do it using Javascript because this way you can smooth expand any element on the fly, it’s your choice. Setting height to zero at this point will make disappear the DIV without any animation because it has currently no exact height set.
Finally the expand function uses a setTimeout to set the full height to the DIV. This is needed because the javascript engine still needs to “commit” the zero height set by the init function. 20 milliseconds it a very short time, but that’s all we need to make things need.
The collpase function does almost the same, but sets the new height to zero. So if this function is called before expand everything will work and we don’t need the setTimeout trick.
Every following click action on the buttons will simply change the DIV’s height value. In fact the setTimout in the expand function is unnecessary at this point, but keeping it will not change much.
If the DIV’s height changes between one expansion and the next one we will have a wrong value stored, so you have to update the value whenever necessary.