CSS box model is a stack of 2-dimensional layers in which the default behaviour is:
- Each child element is on top of parent element
- For sibling elements, current node appear on top of previous one
Every element in a document is stacked up with the base root element. It is well known that we can alter this stacking bahaviour with change of any of these default properties:
Recently I came to know that
opacity can also make changes in stacking context!
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’.
- W3C CSS Color Module Level 3 - Transparency
Here is an example: in the following codepen sample code, Fig. A shows the default stacking with respect to the root of the document. (There are 3 divs - red, green and blue, each surrounded by div containers.)
In Fig. B, red has got
z-index: 1 which introduces a new stacking context. All elements are stacked up against root with
z-index: 0), while red will be raised from the that layer. So it appears on topmost layer.
Question: how can we bring the red layer to the bottom without changing
Answer: use opacity < 1 for parent of red.
The container div of red is set with property
opacity: 0.9 in Fig. C, so a new stacking context will be induced in that div. Therefore the
z-index: 1 for red will be applied with respect to the parent div, instead of w.r.t root node. Thus it appears below green and blue blocks.