Hide element after fade out using only CSS

Based on the answer of @Rev I created a proof of concept. It works nicely (see fiddle).

When you add the class 'fadeOut' to the div it'll fade out and end with a visibility: hidden state. Remove the class and it fades in again. You can tell that it is really hidden by hovering your mouse over it: if hidden it will no longer give the "text selection" mouse pointer.

HTML

<div class="page">
    Lorem ipsum etc etc etc. 
</div>

CSS

  .page {
      -moz-animation-name: fadeIn;
      -webkit-animation-name: fadeIn;
      -ms-animation-name: fadeIn;
      animation-name: fadeIn;
      -moz-animation-duration: 1s;
      -webkit-animation-duration: 1s;
      -ms-animation-duration: 1s;
      animation-duration: 1s;
      -moz-animation-timing-function: ease-in-out;
      -webkit-animation-timing-function: ease-in-out;
      -ms-animation-timing-function: ease-in-out;
      animation-timing-function: ease-in-out;
      -moz-animation-fill-mode: forwards;
      -webkit-animation-fill-mode: forwards;
      -ms-animation-fill-mode: forwards;
      animation-fill-mode: forwards;  
    }

    .page.fadeOut {
      -moz-animation-name: fadeOut;
      -webkit-animation-name: fadeOut;
      -ms-animation-name: fadeOut;
      animation-name: fadeOut;
    }

    @-moz-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}
    @-webkit-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}
    @-ms-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}
    @-keyframes fadeIn { 0% { opacity: 0; visibility: hidden; } 100% { opacity: 1; visibility: visible; }}

    @-moz-keyframes fadeOut { 0% { opacity: 1; visibility: visible; }  100% { opacity: 0; visibility: hidden; }} 
    @-webkit-keyframes fadeOut { 0% { opacity: 1; visibility: visible; }  100% { opacity: 0; visibility: hidden; }} 
    @-ms-keyframes fadeOut { 0% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden; }} 
    @-keyframes fadeOut { 0% { opacity: 1; visibility: visible; } 100% { opacity: 0; visibility: hidden;  }} 

Some additional remarks:

  1. If you have child elements in the .page element that have explicitly visibility: visible set on them then they will react to interaction via mouse. This is because hey are not hidden just invisible due to the opacity: 0. The twitter bootstrap collapse plugin does this for instance. You can solve this by setting their visibility to inherit instead of visible. This will cause them to only be visible if their parent is. For instance the collapse plugin can be made to behave using this additional css:

    .page .collapse { visibility: inherit; }

  2. This does not work in IE 9 and below.

  3. You need the browser prefixes as seen in my code to make this work. I tested this without the prefixes and both the latest chrome (42) and firefox (37) did not work without them. This is ugly but can be made easier by using something like SASS with Compass. Here's the same code using that approach:

SASS with Compass

.page { 
  @include animation(fadeIn 1s ease-in-out forwards); 
}

.page.fadeOut { 
  @include animation-name(fadeOut); 
}

@include keyframes(fadeIn) {
  0% { opacity: 0; visibility: hidden; }
  100% { opacity: 1; visibility: visible; }
}

@include keyframes(fadeOut) {
  0% { opacity: 1; visibility: visible; }  
  100% { opacity: 0; visibility: hidden; }
}

Not completely JS-only, but when you start the fade animation, also add a class to the form container with the following CSS:

.disableMouse * {
  pointer-events: none;
}

This will disable clicks (but it won't disable scrolling). Works in all current browsers, but IE support was only added in version 11. So this may not be the best option for you if you need to support IE10 and earlier.