This is similar to our previous test except this time we’re trying to delay the application of `visbility:hidden` using pure CSS. We can do this using the `transition-delay` property, and apply a different delay to the opacity transition (no delay) and to the visibility transition (delay equal to the duration of the opacity transition). Thanks to Roman Komarov for pointing out this technique.
Test link after the hidden content.
The basic CSS code for this example looks like this:
.visible {
visibility: visible;
opacity: 1;
transition: opacity 2s linear;
}
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
When showing the element (by switching to the visible
class), we want the visibility:visible
to kick in instantly, so it’s ok to transition only the opacity
property. And when hiding the element (by switching to the hidden
class), we want to delay the visibility:hidden
declaration, so that we can see the fade-out transition first. We’re doing this by declaring a transition on the visibility
property, with a 0s duration and a delay.
At the end of the fade-out transition, we want to remove the hidden element from the flow, so that it does not leave a blank space in the middle of the page. Sadly we don’t have many options here:
display:none
doesn’t work because it will be applied instantly, and trying to delay it like we did with visibility
won’t work;position:absolute
has the exact same issue;margin-top
(it can be transitioned and thus delayed).In order to use margin-top
to hide the element, we need to have a slightly richer HTML structure:
<div class="visible">
<div>…</div>
</div>
And our CSS code becomes more complex:
.visible,
.hidden {
overflow: hidden;
/* This container should not have padding, borders, etc. */
}
.visible {
visibility: visible;
opacity: 1;
transition: opacity 2s linear;
}
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
.visible > div,
.hidden > div {
/* Put any padding, border, min-height, etc. here. */
}
.hidden > div {
margin-top: -10000px;
transition: margin-top 0s 2s;
}