Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS: hover not working due to opacity

Tags:

css

opacity

hover

I'm having a strangs CSS problem.

Below is a very simple code sample, demonstrating the problem.

<html>
  <head>
     <style>
      .hover {
        float: right;
      }
      .hover:hover {
        background-color: blue;
      }
      .blocker {
        opacity: 0.5;
      }
    </style>
  </head>
  <body>
    <div class="hover">hover</div>
    <div class="blocker">blocker</div>
  </body>
</html>

I have a div A, floating over another div B, which has an opacity of 0.5. And I want to add a CSS hover rule to the floating div. But for some reason I can't.

Whether I float right or left, doesn't matter.

But when I change the opacity to 1, the hover rule works all of a sudden.

Can anybody explain this behaviour?

I can "fix" the problem by wrapping the content of the blocker div in a span, but it feels like I shouldn't have to.

Here's a jsFiddle, demonstrating the problem: http://jsfiddle.net/ed82z/1/

like image 379
Jipo Avatar asked Jun 02 '14 13:06

Jipo


1 Answers

Simply put - it is "above" it if the opacity has a less than 1 value.

The key term here is a Stacking Context.

By setting opacity to a value less than one, it is layered differently according to the specification since it receives a new stacking context and is positioned beneath the element.

It is specified here float and in opacity:

The root element forms the root stacking context. Other stacking contexts are generated by any positioned element (including relatively positioned elements) having a computed value of 'z-index' other than 'auto'. Stacking contexts are not necessarily related to containing blocks. In future levels of CSS, other properties may introduce stacking contexts, for example 'opacity' [CSS3COLOR].

From opacity:

Since an element with opacity less than 1 is composited from a single offscreen image, content outside of it cannot be layered in z-order between pieces of content inside of it. For the same reason, implementations must create a new stacking context for any element with opacity less than 1. If an element with opacity less than 1 is not positioned, implementations must paint the layer it creates, within its parent stacking context, at the same stacking order that would be used if it were a positioned element with ‘z-index: 0’ and ‘opacity: 1’. If an element with opacity less than 1 is positioned, the ‘z-index’ property applies as described in [CSS21], except that ‘auto’ is treated as ‘0’ since a new stacking context is always created. See section 9.9 and Appendix E of [CSS21] for more information on stacking contexts. The rules in this paragraph do not apply to SVG elements, since SVG has its own rendering model ([SVG11], Chapter 3).

How to fix it:

You can set pointer-events to none , see this fiddle.

like image 140
Benjamin Gruenbaum Avatar answered Oct 18 '22 11:10

Benjamin Gruenbaum