Offspring that has opacity will not be able to show up beneath the sibling of their parent with z-index

I'm perplexed by the behavior of stacking order when applying an opacity level other than 1 to a child element. It seems that setting any other opacity value causes the child element to always dominate its siblings in terms of stacking.

.element {
  width: 500px;
  height: 100px;
  background: orangered;
}

.child {
  height: 150px;
  width: 100px;
  background: grey;
  
  opacity: 0.5;
  z-index: 1;
}

.sibling {
  width: 400px;
  height: 100px;
  background: skyblue;
  
  z-index: 2;
}
<div class="element">
  <div class="child"></div>
</div>
<div class="sibling"></div>

If the opacity property is removed (or set back to 1) for the .child element, it behaves as expected and stacks behind the .sibling element. However, any non-1 opacity values seem to alter this stacking relationship. This leads me to think that .element might be establishing a stacking context, although upon review, I couldn't find evidence of this based on MDN's criteria.

The CSS standard doesn't offer much insight into this:

It mentions that an element with less than full opacity creates a new stacking context, but beyond that, there isn't guidance on how opacity impacts stacking orders within elements. My example involving .child suggests that while it may create a stack context internally, its position relative to surrounding elements remains consistent. Further tests using display: flow-root confirm this behavior even without the opacity adjustment.

So what exactly is happening here?

Answer №1

Initially, the application of the z-index seems unnecessary as no elements are positioned (source). The code can be simplified as shown below:

.element {
  width: 500px;
  height: 100px;
  background: orangered;
}

.child {
  height: 150px;
  width: 100px;
  background: grey;
  
  opacity: 0.5;
}

.sibling {
  width: 400px;
  height: 100px;
  background: skyblue;
}
<div class="element">
  <div class="child"></div>
</div>
<div class="sibling"></div>

The issue is not about stacking context but rather painting order. Your reference to stacking context is accurate, but irrelevant in this scenario as there are no elements within .child.

According to your quote:

If an element with opacity less than 1 is not positioned, then it is painted on the same layer, within its parent stacking context, as positioned elements with stack level 0.

By examining the painting order,

  1. All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order

From the explanation stated above, it's evident that an element with opacity less than 1 will be painted like positioned elements at step (8). Other elements without a stacking context will be painted before them:

  1. For all its in-flow, non-positioned, block-level descendants in tree order:

Replacing opacity with position:relative would yield the same result.

.element {
  width: 500px;
  height: 100px;
  background: orangered;
}

.child {
  height: 150px;
  width: 100px;
  background: grey;
  
  position:relative;
}

.sibling {
  width: 400px;
  height: 100px;
  background: skyblue;
}
<div class="element">
  <div class="child"></div>
</div>
<div class="sibling"></div>

If you make the sibling element positioned, it will also be painted in step (8) and appear above the .child due to following the tree order.

.element {
  width: 500px;
  height: 100px;
  background: orangered;
}

.child {
  height: 150px;
  width: 100px;
  background: grey;
  
  opacity:0.5;
}

.sibling {
  width: 400px;
  height: 100px;
  background: skyblue;
  
  position:relative;
}
<div class="element">
  <div class="child"></div>
</div>
<div class="sibling"></div>


In conclusion, creating a stacking context becomes relevant when dealing with child elements, as it dictates their painting order inside that context.

For further details, refer to these related questions:

Why can't an element with a z-index value cover its child?

Why does position:relative; appear to change the z-index?

Answer №2

If you want to maintain the height of .element but prevent .child from overflowing outside of it, you can simply add the CSS property overflow: hidden to .element.

.element {
  width: 500px;
  height: 100px;
  background: orangered;
  overflow: hidden;
}

.child {
  height: 150px;
  width: 100px;
  background: grey;
  
  opacity: 0.5;
  z-index: 1;
}

.sibling {
  width: 400px;
  height: 100px;
  background: skyblue;
  
  z-index: 2;
}
<div class="element">
  <div class="child"></div>
</div>
<div class="sibling"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with tab focus causing dropdown menu to be unresponsive

I'm currently experimenting with a bootstrap example featuring a dropdown menu. Here is the live example: http://jsfiddle.net/p73vc8Lv/ My goal is to have the dropdown menu display when the user clicks on the link. I've attempted to achieve thi ...

Obtain the URL of the chosen file from the input file in an HTML/AngularJS framework

Currently, I am developing a web app in MVC-5 using AngularJS. Below is the structure of the div that I am working on: <div class="row form-clearify" style="margin-top:3px;"> <div class="col-md-6 col-sm-6 col-xs-12" style="background-color:w ...

Assistance with CSS Flexbox: How to align items in a grid format (images, titles, text)

I'm currently working on constructing the layout displayed in the image below. The aim is to have the image on the left with a fixed width, while the text on the right adjusts to the available width. Furthermore, the objective is for these items to s ...

Create a JavaScript script within a CSS file

I'm attempting to create this using only CSS: Codepen and I would like to achieve the same effect but solely with CSS. This is what my CSS looks like: .text{ --a: calc(var(--a);*0.82+(1.5-var(--b);)/10); --b: calc(var(--b);+var(--a);); transfor ...

Ways to include the name of the parent element in a child element

I am facing an issue with two input elements having the same ID when trying to edit. To solve this problem, I need to add the parent div ID to the child input element. How can I append the parentId to the childId? <div class="wrapper-merge-input"> ...

How can you add a border before and after text as well as around the entire box

Is there a way to add borders to the image below? I would like to include a border that looks similar to this: text added before and after the entire box How can I achieve a border using css either with before, after, or background? ...

Create a div element that is set to be 30 pixels smaller than its containing div

I am trying to achieve a specific layout where I have a nested div structure. The parent div has a width set in percentage (80%) and I want the child div to be slightly narrower by 30px. Can anyone provide guidance on how I can accomplish this? Do I need ...

Incorporating the parent object into a nested JavaScript function

I have come across similar questions, but my situation seems unique to me. I have simplified my code and turned one line into a comment, but the core concept remains unchanged... function myFunction(options) { var button; options.widgets.forEach(f ...

What is the purpose of setting the image border to inline block?

When I added a span element as the circular border to my image, which is placed inside a span tag, I observed that the span tag was being pushed down. By giving the span a display:inline-block property, the issue was resolved. But why does this happen? ...

The template in AngularJS route fails to display

I am currently facing an issue with loading multiple pages using AngularJS $routeProvider and two controllers. Whenever I click on a link from the first partial to go to the second one, the second partial fails to render properly, displaying only template ...

Can we incorporate modulo into the loop?

I have a JavaScript function with HTML code inside. I need the ".one-card" div to repeat four times within each ".row" div. The ".row" div is being repeated in a foreach loop. I want to check if the result of modulo (4) is not equal to zero, then display t ...

The amazing property of AngularJS - Scope

I have saved this HTML code in a file. Here is the HTML : <!-- checkbox 1 --> <input type="checkbox" name="checkbox1" id="checkbox-group1" ng-model="checkbox1" value="group1"> <input type="checkbox" name="checkbox1" id="checkbox-group2" ng ...

Creating an arrow dialog box in Material UI: A step-by-step guide

I have successfully created an arrow box (div) using custom CSS and HTML. However, I am facing difficulty in implementing the same design in Material UI with React JS. The code below demonstrates how to achieve this using custom CSS. My question is: How ...

Looking for recommendations on effective jQuery plugins for drag and drop file uploading?

Can anyone recommend any drag-and-drop jQuery plugins that offer similar functionality to Gmail's attachment dragging and dropping feature? I would like the ability to track the upload progress. However, I am specifically looking for options without ...

Interacting with a PNG file using a border radius in Internet Explorer 9 is causing issues with its transparency

Encountering an issue with IE9 where a white to gray gradient box appears around the transparent PNG on hover/selection. There is also a border radius applied to the thumbnail. Any ideas on how to fix this problem? Here is an example of the issue: https ...

Having two ng-click events and two distinct classes in an ng-repeat based on the selected option

There are two buttons in my code that should remove a div within an ng-repeat loop. Depending on which button is clicked, a custom CSS class should be added to the effect. The CSS changes based on the option selected. When I click on a button, either &apo ...

Show equally sized elements using a grid system

I need assistance with displaying fields in a row using CSS grid. I want to display 3 fields in a row with equal width, and if there are only 2 fields, they should also have equal widths. Additionally, if there is only one field, it should take up the full ...

Performing functions in a sequence with JQuery

I've encountered an issue with executing functions in sequence. In my HTML file, I have the following code: <body onload="start();"> <div id="title"><div id="welcome">WELCOME</div></div> Within my JS code, I have a ...

HTML5 Boilerplate and optimizing the critical rendering path by deferring scripts and styles

Previously, I constructed my website layouts using the HTML5 Boilerplate method: incorporating styles and Modernizr in the head section, jQuery (either from Google CDN or as a hosted file) along with scripts just before the closing body tag. This is an exa ...

Trouble with card alignment in Bootstrap

I've been experimenting with creating a grid layout using cards and utilizing ng-repeat for generating the cards. Unfortunately, I'm running into an issue where there is no spacing between each card, as depicted in the image. https://i.stack.img ...