HTML5 Canvas 3D WebGL (TM) js Library
 

Using CSS Transition Opacity for Fade-In and Fade-Out Fade Effects, Problems and Workarounds

The CSS opacity transition is often used to create fade-in and fade-out effects. Although this works great on the first glance, it can also be the cause of some hard to find bugs with mouse events.

Basic idea is to reduce an elements opacity from 1 (meaning fully opaque) to 0 (meaning fully transparent) in order to fade-out the element. And indeed an element with opacity : 0 appears just as invisible as an element with visibility : hidden. However, it behaves differently. An element with opacity : 0 still receives events and so e.g. reacts when the user clicks on its links. On the other hand links covered by an fully transparent element do not work, although completely visible.

The following first example illustrates this.

<style >
   .c0  { opacity : 0; transition:opacity 1s; }
   .c0:hover { opacity : 1}
</style>
 
<div class="c0">
   Nicely working Sample
</div>
<span class="hoverhere">Hover over the Line Above this Line</span> <br>
 
Nicely working Sample
Hover over the Line Above this Line

The second example now shows the problem with this technique: Here you see an ordinary link, which however has the problem that it does not react when clicked. (If you think this example is a bit constructed, there is a more realistic but also more complex example below.)

<style >
    .c1  { opacity : 0; transition:opacity 1s;
          padding:40px;
          position : absolute;
          margintop:‑75px}
    .c1:hover { opacity : 1}
</style>
 
<div class="c1">
   Sample interfering<br > with link
</div>
<div > Not working link <br >
  <a target="new" href="http://www.taccgl.org">
    http://www.taccgl.org
  </a>
</div>
 
Sample interfering
with link
Not working link
http://www.taccgl.org

The problem is that the element c1 covers the link. It is invisible because of the opacity:0 but it still receives mouse clicks. So these mouse clicks do not get to the link itself and consequently the link does not work. By adding a background color and using opacity:0.5 it immediately becomes clear what is happening:

<style >
    .c2  { opacity : 0.5; transition:opacity 1s;
          padding:40px;
          position : absolute;
          margintop:‑75px;
          background‑color:yellow;
    }
    .c2:hover { opacity : 1}
</style>
 
<div class="c2">
   Sample interfering<br > with link
</div>
<div > Not working link <br >
  <a target="new" href="http://www.taccgl.org">
    http://www.taccgl.org
  </a>
</div>
 
Sample interfering
with link
Not working link
http://www.taccgl.org

More Realistic Example: Pop-Up Menu

The following shows a more realistic example of a pop-up menu. When you hover the mouse over the menu button, a menu appears. The menu is faded-in and -out using an opacity transition. You will notice that the link below the menu button is not working. This is caused my the menu, which is there (although fully transparent due to opacity:0 and hence invisible) and receives the mouse clicks intended for the link.

<style >
    .menu  { opacity : 0; transition:opacity 1s;
             position : absolute;
             background‑color:silver;
             padding:20px;
    }
    .mb    { background‑color:red; padding:5px }
    .mb:hover ~ .menu { opacity : 1}
</style>
<div class="mb">Menu Button Hover Here</div>
<div class="menu">
  This is a sample <br > menu with some <br > links<br >
  <a target="new" href="http://www.taccgl.org">
    http://www.taccgl.org
  </a>
</div>
<div > Not working link <br >
  <a target="new" href="http://www.taccgl.org">
    http://www.taccgl.org
  </a>
</div>
 
Menu Button Hover Here
Not working link
http://www.taccgl.org

Workaround: Combinig CSS Transition Opacity and Visibility

The idea to solve this problem is to use both transitions on the opacity and on the visibility property. The opacity transition for the visual fade-in and fade-out effect and the visibility for hiding the element for mouse clicks as well.

Note, however, that while the fade visual effect is running, the menu element must be visible, because otherwise the effect would not be visible. So on a fade-in the element must become visible immediately while on a fade-out it must become visible only after the opacity transition terminated. Exactly this behaviour is specified using transition:visibility 1s . For a detailed description on css transition visibility and how to combine it with visual effects like opacity and others see the CSS Transition Visibility article.

<style >
    .menu1  {
             opacity : 0;
             visibility : hidden;
             transition:opacity 1s, visibility 1s;
             position : absolute;
             background‑color:silver;
             padding:20px;
           }
    .mb1   { background‑color:red; padding:5px }
    .mb1:hover ~ .menu1 { opacity : 1; visibility:visible}
    .menu1:hover {opacity : 1; visibility:visible}
</style>
<div class="mb1">Menu Button Hover Here</div>
<div class="menu1">
  This is a sample <br > menu with some <br > links<br >
  <a target="new" href="http://www.taccgl.org">
    http://www.taccgl.org
  </a>
</div>
<div > Now working link 
  <a target="new" href="http://www.taccgl.org">
    http://www.taccgl.org
  </a>
</div>
 
Menu Button Hover Here
Now working link http://www.taccgl.org

Conclusion

Using css transition on opacity alone to fade out an element leads to the problem that links on the faded element stay active while links on elements covered by the faded element do not work. We gave examples for this behaviour and a workaround using both css transition opacity and css transition visibility.

Blog Articles

Parallax scrolling with 3D Acceleration
CSS Transition Opacity for Fade Effects
CSS Transition Display
CSS Transition Visibility
WebGL-HTML5 PopUp Animations
3D Objects on HTML pages
Deforming and Morphing of HTML

Demos

3D Configurator
3D Produktkonfigurator

Tutorial Sections

First Example
Basic Shapes
Basic 3D Models
Basic Animations
Colors and Textures
Integration of HTML and WebGL
Timing Transitions
Boxes
JavaScript Embedding
External 3D Models
Parts of Elements
HTML Elements on Canvas
Selectors for Multiple Transitions
Multiple Triangle Animations
Flexibles
Fragment Shaders
Expressions

 

WebGL™ is a trademark of the Khronos Group Inc.