Search code examples
javascriptcsshtml-liststransitionnav

CSS transition not applied to max-height switching on UL list


I cannot determine why the specified transition is not applied when I toggle the max-height of the unordered list. The toggle is accomplished by switching classes on the UL. I've tried putting the transition in the max-height classes, but to no avail. I've created a working example on JSFiddle, and the code is supplied below in full. Thanks in advance for any help.

<!DOCTYPE html>
<html lang=en>
<head>
    <title>Transition Problem</title>
<style>
.nav ul {
    overflow: hidden;
    transition: max-height 2s;
    -webkit-transition: max-height 2s;
    white-space: normal;
}

.max-height-150 {
    max-height: 150px;
}

.max-height-none {
    max-height: none;
}
</style>
</head>
<body>
<p>The JavaScript switches the class correctly, and the height of the UL switches as expected, but the transition is not applied.</p>
<button>SWITCH CLASS</button>
<nav class="nav">
    <ul class="max-height-150">
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li>Item 4</li>
        <li>Item 5</li>
        <li>Item 6</li>
        <li>Item 7</li>
        <li>Item 8</li>
        <li>Item 9</li>
        <li>Item 10</li>
        <li>Item 11</li>
        <li>Item 12</li>
        <li>Item 13</li>
        <li>Item 14</li>
        <li>Item 15</li>
        <li>Item 16</li>
        <li>Item 17</li>
        <li>Item 18</li>
        <li>Item 19</li>
    </ul>
</nav>
<script>
// Select the button:
var button = document.getElementsByTagName('button')[0];

// Toggle between the two max-height classes when the button is clicked:
var buttonClickListener = function (e) {
    var navUl = document.querySelectorAll('.nav ul')[0];
    if (navUl.classList.contains('max-height-150')) {
        navUl.classList.remove('max-height-150');
        navUl.classList.add('max-height-none');
    } else {
        navUl.classList.add('max-height-150');
        navUl.classList.remove('max-height-none');
    }
    e.preventDefault();
};

// Add a click listener on the button and register the toggle function on it:
if (button.addEventListener) {
    button.addEventListener('click', buttonClickListener, false);
} else if (button.attachListener) {
    button.attachEvent('click', buttonClickListener);
}
</script>
</body>
</html>

Solution

  • Unfortunately you cannot transition from a set max-height to none (or auto, or 100%, etc). You can only transition between set numbers. Try setting the new max height to the largest value you believe it will have and it should work the way you want.

    .max-height-none {
        max-height: 350px;
    }
    

    Updated fiddle: https://jsfiddle.net/07cgn26r/1/