iOS opacity/visibility animation bug

by Carosn Shold

HTML

<p><em>Click on the boxes below to toggle the inner div</em></p>

<div class="nav-item">
    <pre>-webkit-transition: transform...</pre>
    <pre>transition: transform...</pre>
    <p>Animation <strong>does not</strong> work on iOS</p>
    <div class="sub-nav sub-nav-1">
        <ul>
            <li>Test 1</li>
            <li>Test 2</li>
        </ul>
    </div>
</div>

<div class="nav-item">
    <pre>-webkit-transition: -webkit-transform...</pre>
    <pre>transition: transform...</pre>
    <p>Animation <strong>works</strong> on iOS, but is buggy/delayed</p>
    <div class="sub-nav sub-nav-2">
        <ul>
            <li>Test 1</li>
            <li>Test 2</li>
        </ul>
    </div>
</div>

The only difference between the two animations is that the first one tries to use:
<pre><code>-webkit-transition: transform ...</code></pre>
While the second uses:
<pre><code>-webkit-transition: -webkit-transform ...</code></pre>

<hr>

<div class="nav-item">
    <pre>transition: all 400ms;</pre>
    <p>Animates nicely</p>
    <div class="sub-nav sub-nav-3">
        <ul>
            <li>Test 1</li>
            <li>Test 2</li>
        </ul>
    </div>
</div>
    
<div class="nav-item">
    <pre>transition: all 400ms ease-in-out;</pre>
    <p>Animates nicely</p>
    <div class="sub-nav sub-nav-4">
        <ul>
            <li>Test 1</li>
            <li>Test 2</li>
        </ul>
    </div>
</div>

CSS

.sub-nav {
    opacity: 0;
    visibility: hidden;
    -webkit-transform: translateY(-5px);
    transform: translateY(-5px);
    background-color: lightblue;
}

.nav-item {
    background: #f6f6f6;
    border-bottom: 1px solid #ccc;
    margin-bottom: 20px;
    -webkit-tap-highlight-color:rgba(0,0,0,0);
}

.no-touch .nav-item:hover .sub-nav,
.nav-item.show-dropdown .sub-nav {
    opacity: 1;
    visibility: visible;
    -webkit-transform: translateY(0px);
    transform: translateY(0px);
}

.sub-nav-1 {
    -webkit-transition: transform 400ms ease-out, opacity 150ms ease-out 100ms, visibility linear 200ms;
    transition: transform 400ms ease-out, opacity 150ms ease-out 100ms, visibility linear 200ms;
}

.sub-nav-2 {
    -webkit-transition: -webkit-transform 400ms ease-out, opacity 150ms ease-out 100ms, visibility linear 200ms;
    transition: transform 400ms ease-out, opacity 150ms ease-out 100ms, visibility linear 200ms;
}

.sub-nav-3 {
    -webkit-transition: all 400ms;
    transition: all 400ms;
}

.sub-nav-4 {
    -webkit-transition: all 400ms ease-in-out;
    transition: all 400ms ease-in-out;
}

JavaScript

if ('ontouchstart' in window) {
    $('html').addClass('touch');
} else {
    $('html').addClass('no-touch');
}

$('.nav-item').on('click', function() {
    $(this).toggleClass('show-dropdown');
});