Back to the intro page

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.

How it works

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.

How do we remove the hidden element from the flow?

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:

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;
}