0

Since in 2019, we STILL don't have a working transition from height: auto to a fixed height in CSS, I need to set my height manually via JS.

I would like to set the height, force a "redraw" (that essentially does nothing in the eyes of the user), and then set the height to 0 and have the transition work, all within the SAME function.

I would very much like to avoid a hacky setTimeout(functionThatSetsHeightToZero, 1).

Here is the code:

    /* e = a plus/minus ui element */
    function toggleBox(e) {
        var box = document.querySelector(".box table");
        if(e.innerHTML == "-") {
            if(!(box.getAttribute("data-height") > 0)) {
                box.setAttribute("data-height", box.getBoundingClientRect().height);
                box.style.height = box.getAttribute("data-height")+"px";
                /* INSERT WAY TO FORCE REDRAW HERE */
            } 
            box.style.height = "0";
            e.innerHTML = "+";
        }
        else {
            box.style.height = box.getAttribute("data-height")+"px";
            e.innerHTML = "-";
        }
   }

CSS:

.box table {
    display: block;
    width: 100%;
    border-collapse: collapse;
    transition: height 0.2s ease-out;
    overflow: hidden;
}

EDIT:

Actually, the hacky solution doesn't work either, until I set the timeout high enough. A value of 100ms for example isn't enough for the browser to update and animate the first closing transition. 1000ms works.

Unfortunately, the console.log(box.offsetHeight); tip doesn't seem to be doing anything.

MiK
  • 918
  • 4
  • 16
  • Doesn't `zoom` force a redraw? – Mouser Dec 30 '19 at 11:12
  • 1
    `box.offsetTop;` does the trick. Retrieving the position of an element after the DOM was changed forces a re-calculation of the DOM, and that's enough to update the values for the transition. – Teemu Dec 30 '19 at 11:27

0 Answers0