Transitions on the CSS display property

You can concatenate two transitions or more, and visibility is what comes handy this time.

div {
  border: 1px solid #eee;
}
div > ul {
  visibility: hidden;
  opacity: 0;
  transition: visibility 0s, opacity 0.5s linear;
}
div:hover > ul {
  visibility: visible;
  opacity: 1;
}
<div>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
  </ul>
</div>

(Don't forget the vendor prefixes to the transition property.)

More details are in this article.


You need to hide the element by other means in order to get this to work.

I accomplished the effect by positioning both <div>s absolutely and setting the hidden one to opacity: 0.

If you even toggle the display property from none to block, your transition on other elements will not occur.

To work around this, always allow the element to be display: block, but hide the element by adjusting any of these means:

  1. Set the height to 0.
  2. Set the opacity to 0.
  3. Position the element outside of the frame of another element that has overflow: hidden.

There are likely more solutions, but you cannot perform a transition if you toggle the element to display: none. For example, you may attempt to try something like this:

div {
    display: none;
    transition: opacity 1s ease-out;
    opacity: 0;
}
div.active {
    opacity: 1;
    display: block;
}

But that will not work. From my experience, I have found this to do nothing.

Because of this, you will always need to keep the element display: block - but you could get around it by doing something like this:

div {
    transition: opacity 1s ease-out;
    opacity: 0;
    height: 0;
    overflow: hidden;
}
div.active {
    opacity: 1;
    height: auto;
}