What Has Bigger Priority: Opacity or Z-Index in Browsers

What has bigger priority: opacity or z-index in browsers?

This is not a bug and is actually how it's supposed to work. It's a bit confusing as the elaborate description of Stacking Contexts doesn't mention anything about it. However, the visual formatting module links to the color module where this particular gotcha can be found (emphasis mine):

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).

What has bigger priority: opacity or z-index in browsers?

This is not a bug and is actually how it's supposed to work. It's a bit confusing as the elaborate description of Stacking Contexts doesn't mention anything about it. However, the visual formatting module links to the color module where this particular gotcha can be found (emphasis mine):

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).

Possible Opacity Z-Index Bug

This issue is already known.
https://www.google.com/#q=opacity%20change%20z-index

You should use rgba background, which is also a widely supported property.

Checkboxes behind a div turned visible when their opacity is changed

This is caused because opacity causes a new stacking context. This can also happen with the following CSS properties:

  • opacity
  • CSS Transforms
  • Filters
  • CSS Regions
  • Paged Media

Rule 8.2: All opacity descendants with opacity less than 1, in tree order, create a stacking context generated atomically.

.checkboxes {  display: flex;}
.tooltip { position: absolute; width: 300px; height: 20px; background-color: #ccc;}
<div class="container">  <div class="tooltip"></div><!-- own stack context and above the other elements -->  <div class="checkboxes">    <div class="checkbox" style="opacity:0.5"><!-- own stack context and later on the painting order than position -->      <label>        <input type="checkbox">        <span>Bar</span>      </label>    </div>    <div class="checkbox">      <label>        <input type="checkbox">        <span>Bar</span>      </label>    </div>  </div></div>

Elements with transparency appearing over opaque foreground element

Opacity Affects Stacking Order

Consider the following HTML snippet:

<div class="wrapper tweak">
<div class="overlay">
<p>The Overlay Panel</p>
</div>
<div class="content">
<p>The main Content panel with a motif:
<b>♥</b> <b class="foggy">♠</b></p>
</div>
</div>

and the following CSS:

.wrapper {
position: relative;
outline: 1px solid blue;
}
.overlay {
position: absolute;
top: 0;
left: 0;
background-color: white;
border: 1px dotted blue;
width: 400px;
}

.content p b {
background-color: black;
color: white;
padding: 0 10px;
opacity: 1.0; /* default value */
}
.content p b.foggy {
opacity: 0.4;
}

.tweak .overlay {
z-index: 1;
}

Basically, I have a wrapper with two child div's, .overlay and .content. Note that the overlay is ahead of the content in the code (DOM). If it were after, you would not have seen the problem in the first place.

The content has two bold elements with two different opacity values.

See the basic line in the demo fiddle is at: http://jsfiddle.net/audetwebdesign/DxQZv/

When you enable the overlay, the .foggy element with opacity of 0.4 appears in front of the overlay. The stacking order for this arrangement is, from back to front: the in-flow content with opacity of 1.0 (default), the absolutely positioned overlay, then the element with opacity 0.4.

However, if you explicitly set z-index: 1 to the .overlay (add the .tweak class),
then .overlay gets placed higher in the stacking order.

There are other ways of adjusting the z-index value to get the same effect, but this may be the simplest.

Reference:

See 9.9.1 Specifying the stack level: the 'z-index' property in the CSS2 spec

and 3.2. Transparency: the ‘opacity’ property in the CSS3 Color Module spec.

Technically, adding an opacity value (other than 1.0) to an element creates a new stacking context with z-index of 0, which is also what happens with a positioned element.

However, when two elements have the same z-index, they are painted in the order they appear in the DOM (tree order). In this case, the overlay is painted first followed by the bold element with opacity of 0.4, which is why it appears in front of the overlay.

There is also an earlier question that deals with the same issue:

What has bigger priority: opacity or z-index in browsers?

which I found after I posted my answer.



Related Topics



Leave a reply



Submit