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; margin‑top:‑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
|
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; margin‑top:‑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
|
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
|
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
|
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.
WebGL™ is a trademark of the Khronos Group Inc.
|