Avoid z-index working relative to the parent element - css

I come with a question about an odd behavior regarding the z-index property. The situation in terms or layers is the following:
div#wrapper
div#sidebar (fixed position and 5 as z-index)
div#pop-up (absolute position and 15 as z-index)
div#black-layer (fixed position and 10 as z-index)
The thing then is that I want to have a semi-transparent black layer over everything, with the next exception: over it I want another arbitrary div (depending on the case). A bit like the typical light-box.
What's happening now is that the pop-up, which is supposed to be over the black-layer, since their z-index is higher, is actually under it.
My conclusion after several tries is that the reason this occurs like so is because #pop-up is a child of #sidebar. Indeed, if I put it outside, it works as I pretend. Like:
div#wrapper
div#sidebar
div#pop-up
div#black-layer
But this is not a good solution at all. First because it is not semantically correct from the point of view of the HTML. And also because I have the necessity of having more "pop-ups" in other parts of the code and is not a good idea split the logic this way by keeping separately all of them.
Thank you in advance.
Update: It is even more strange now. I haven't changed anything, but just made a test in Firefox instead of Chrome, and it works there as I expected, so the pop-up is in fact over the black-layer. And also in Opera. And it does not work in Maxthon. Just as a note, I'm using Linux.

What's happening now is that the pop-up, which is supposed to be over the black-layer, since their z-index is higher, is actually under it.
As it perfectly well should be. z-index is perfectly well defined, for example in this part of the spec:
Each box belongs to one stacking context. Each positioned box in a
given stacking context has an integer stack level, which is its
position on the z-axis relative other stack levels within the same
stacking context. Boxes with greater stack levels are always formatted
in front of boxes with lower stack levels. Boxes may have negative
stack levels. Boxes with the same stack level in a stacking context
are stacked back-to-front according to document tree order.
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.
Within each stacking context, the following layers are painted in
back-to-front order:
the background and borders of the element forming the stacking context.
the child stacking contexts with negative stack levels (most negative first).
the in-flow, non-inline-level, non-positioned descendants.
the non-positioned floats.
the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
the child stacking contexts with positive stack levels (least positive first).
You are incorrectly assuming z-indexes are shared amongst the entire document, while they are only valid within their own stacking context, which is actually created for every z-indexed element - therefore your #popup is the highest element in #sidebar, but both are stacked underneath #black-layer as it is higher in the root stacking context. Older versions of IE (in quirks mode) actually used the model you are expecting, but that was fixed later on.
So, you'll need to move some elements around. Semantically, that doesn't matter at all since you'll be needing JS anyway to clone/generate the popups in practice.

Related

CSS Container / Grid stacking issue [duplicate]

This property make me confuse.
well.. i searched in google:
What is the z-index?
The z-index property specifies the stack order of an element.
An element with greater stack order is always in front of an element with a lower stack order.
Note: z-index only works on positioned elements (position:absolute, position:relative, or position:fixed). Answer Source
What is the z-index uses?
The order of which the elements overlap one another.
For that purpose, you can assign each element a number (z-index). The system is that an element with a higher number overlaps an element with a lower number. Answer Source
Ok i understand now , it organize the elements and we can use any number ... the higher z-index number appears on all elements..ok nice.
z-index and jquery..very simple and very nice
...but i noticed from the answers that it depend on position property, so -->...(google)..
What is the relation between z-index and position?
demo--> >>source
Ok ... so z-index and position are couple..must be together..
need more information ::
dose it make any conflicts in browsers(IE7,IE8,chrome,...etc)?
What are the z-index uses or what can we do with z-index(depending on the Tags)?
...etc?
correct me if i understand wrong...
Thanks in advance.
Z-index is the property that determines which html element appears on top of another html element when they overlap. The basic idea is that the element with the highest z-index is "on top".
By default, elements have a z-index of zero, but setting the css property on one element to 1, and another to 5 will make the latter element be "on top" of the former, if they overlap.
So far, so simple, but there are several things to look out for.
One, as already mentioned in another answer, is that z-index only has an effect if the element is positioned with position absolute, fixed or relative. (i.e. the css property "position"). An unpositioned element has a z-index of zero.
To complicate things further (and in my experience the area that is often not understood) is the concept of the stacking context. More info can be found in articles such as this. In short though, each time you explicitly set a new z-index, you start a new stacking context. All child elements of the one on which the z-index was set are now in this new stacking context, which may be above or below a stacking context on another unrelated element.
What does this stacking context mean? It means that an element with a z-index of 100 is not necessarily on top of an element with z-index of 1. If they are in different stacking contexts, only the z-indexes of the stacking contexts themselves matters.
I would suggest to have a look at this property on SmashingMagzine.
The Z-Index CSS Property: A Comprehensive Look
It covers all nuts and bolts of this property with great examples and demonstrations.
the most important thing to remember is that z-index works ONLY if the element has position relative, absolute or fixed
I'm not entirely sure what you're asking but for the most-part you only ever need to use z-index if you're doing complicated styling e.g. hover tooltips or dropdown navigations, simply to ensure that they display over other page content.
For basic designing you should generally be avoiding using the position and z-index properties as you can usually achieve the same effects with better performance and browser compatibility with just floats etc.
The Smashing Magazine link posted by Sarfraz is an excellent article on the topic and a good point of reference if you're still struggling to understand the functionality of the property.

How does a web browser determine the z-index if the style is not explicitly defined

I am really curious. You can obtain the z-index from an element but If a page is "just built" without a definition of z-indices, how would that resolve. How does the browser do it? Can we access this via javascript to obtain the browsers definition of the z-index instead of using the computer style component?
Why am i asking? Well, style returns AUTO a loot, but i am curious as to what "auto" is according to the browser etc.
How does the browser do it?
It simply follows the CSS spec as described in section 9.9. In particular:
auto
The stack level of the generated box in the current stacking context is 0. The box does not establish a new stacking context unless it is the root element.
And:
Each box belongs to one stacking context. Each positioned box in a given stacking context has an integer stack level, which is its position on the z-axis relative other stack levels within the same stacking context. Boxes with greater stack levels are always formatted in front of boxes with lower stack levels. Boxes may have negative stack levels. Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.
As for how to actually obtain the stack level for a given element, I don't think the DOM exposes this information because it's more of a CSS implementation detail than anything else (plus it would be zero anyway for all non-positioned elements with auto z-index, because it is a relative value and not an absolute one). And as already mentioned this information is not available through getComputedStyle() either.
There is a natural stacking order that the browser use to determine how elements stack
Below is a list showing the order that items fit into a stacking
context, starting with the bottom of the stack. This list assumes none
of the items has z-index applied:
Background and borders of the element that establish stacking context
Elements with negative stacking contexts, in order of appearance
Non-positioned, non-floated, block-level elements, in order of
appearance
Non-positioned, floated elements, in order of appearance
Inline elements, in order of appearance
Positioned elements, in order
of appearance
For more information check out: http://coding.smashingmagazine.com/2009/09/15/the-z-index-css-property-a-comprehensive-look/

In CSS 2.1, if a parent establish a stacking context, why can the children's text go under the parent but the background color cannot?

This is an advanced CSS question.
In the JSFiddle: (as tested on Chrome 26.0, Firefox 20.0, and IE 10)
http://jsfiddle.net/4yRrm/10
The parent establishes a stacking context, and the children have higher z-index than the parent and cover the parent up, so that's all fine.
But what about in http://jsfiddle.net/4yRrm/11
Now the children have a lower z-index than the parent. The text of the children now go under that parent's text (as you can see the parent's text in blue color covering up the black color of the children's text), but why do the children's background color go above the parent instead? Please substantiate your answer with the spec. Why is there such a behavior -- does that achieve a certain purpose?
As it is, the background of the parent is the lowest layer, and then the children's background, and then the children's text, and then the parent's text. So the parent's painting are at the "extreme end" -- the background as the lowest layer, and the text as the topmost layer, and the children's content are "sandwiched" inside these two extremes.
And related is: how do you make the parent go above the children completely even for the backgrounds, when the parent establishes a stacking context? Please do not answer to remove the positive: relative or to remove the z-index: 0 of the parent, as that will fail to establish a stacking context for the children. That is, the parents MUST have a position of either relative, absolute, or fixed, and at the same time, have a z-index of an integer (and cannot be auto).
CSS2.1 states:
Each box belongs to one stacking context. Each positioned box in a given stacking context has an integer stack level, which is its position on the z-axis relative other stack levels within the same stacking context. Boxes with greater stack levels are always formatted in front of boxes with lower stack levels. Boxes may have negative stack levels. Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.
Within each stacking context, the following layers are painted in back-to-front order:
the background and borders of the element forming the stacking context.
the child stacking contexts with negative stack levels (most negative first).
the in-flow, non-inline-level, non-positioned descendants.
the non-positioned floats.
the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
the child stacking contexts with positive stack levels (least positive first).
As you can see from items 1 and 2, the child stacking contexts with negative stack levels (i.e. your child elements) are always painted above the background of the current stacking context (i.e. your parent element).
The text of the parent element is then painted above the child elements, as in item 5.
It is not possible to make a stacking context sit completely above any of its descendants — its background and borders will always be painted at the very bottom no matter what you do. Since a box may only appear in one stacking context at a time (stacking contexts can be nested but that's not relevant here), you'll have to move those elements out of the parent stacking context if you want them to sit completely under the parent, while allowing the parent to establish its own stacking context for its other contents. For example, you can move them just outside the parent such that they become siblings instead, sharing the same stacking context which in your case is the root stacking context.
Very interesting question:
Why is there such a behavior?
Based on the definitions,
http://www.w3.org/TR/CSS21/visuren.html#z-index
and
http://www.w3.org/TR/CSS21/zindex.html
If you follow the steps, it gets rendered as it is defined.
(Image from http://www.vanseodesign.com/css/css-stack-z-index/)
Within each stacking context, the following layers are painted in
back-to-front order:
1- the background and borders of the element forming the stacking context.
2- the child stacking contexts with negative stack levels (most negative first).
3- the in-flow, non-inline-level, non-positioned descendants.
4- the non-positioned floats.
5- the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
6- the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
7- the child stacking contexts with positive stack levels (least positive first).
How do you make the parent go above the children completely even for the backgrounds, when the parent establishes a stacking context?
If a standard browser is following the definition, then you can't do that for a stacking context and its children, because that would be in conflict with the definition.
Your text node :
Hello Chip Hello Chip Hello Chip Hello Chip
also gains a stacking context :
#chip01 : imaginary-stack-context: 0
#chip01 "Hello Chip..." - imaginary-stack-context: 1
#chip02 - imaginary-stack-context: 0
#chip03 - imaginary-stack-context: 0 ( since you have z-index: -1 makes it behind all other elements with positive / auto z-indexes. )
The CSS 2.1 specs were given already by #BoltClock.

Which CSS properties create a stacking context?

I'm studying about stacking contexts and doing some tests with the properties that create a stacking context.
I did several tests and found that, in addition to z-index, of course, the following properties also create a stacking context:
transform other than none;
opacity other than 1;
And perspective.
Are there other properties that apply a stacking context?
One or more of the following scenarios will cause an element to establish its own stacking context1 for its descendants:
The root element always holds a root stacking context. This is why you can start arranging elements without having to position the root element first. Any element that doesn't already participate in a local stacking context (generated by any of the other scenarios below) will participate in the root stacking context instead.
Setting z-index to anything other than auto on an element that is positioned (i.e. an element with position that isn't static).
Note that this behavior is slated to be changed for elements with position: fixed such that they will always establish stacking contexts regardless of their z-index value. Some browsers have begun to adopt this behavior, however the change has not been reflected in either CSS2.1 or the new CSS Positioned Layout Module yet, so it may not be wise to rely on this behavior for now.
This change in behavior is explored in another answer of mine, which in turn links to this article and this set of CSSWG telecon minutes.
Another exception to this is with a flex item and a grid item. Setting z-index will always cause it to establish a stacking context even if it isn't positioned.
Setting opacity to anything less than 1.
Transforming the element:
Setting transform to anything other than none.
Setting transform-style to preserve-3d.
Setting perspective to anything other than none.
Creating a CSS region: setting flow-from to anything other than none on an element whose content is anything other than normal.
In paged media, each page-margin box establishes its own stacking context.
In filter effects, setting filter to anything other than none.
In compositing and blending, setting isolation to isolate and setting mix-blend-mode to a value different from normal
In will change, setting will-change to a property whose any non-initial value would create a stacking context.
In masking, setting clip-path/mask with a value other than none.
Note that a block formatting context is not the same as a stacking context; in fact, they are two completely independent (although not mutually exclusive) concepts.
1 This does not include pseudo-stacking contexts, an informal term that simply refers to things that behave like independent stacking contexts with respect to positioning, but actually participate in their parent stacking contexts.

possible to set z-index rules which only affect child elements of a certain div?

Is it possible to set z-index that only applies to a certain 'scope', such as only affecting children of a certain element.
I've got an containerDiv with z-index 0. It contains a bunch of circles which should be placed on top of eachother in various depths, but I don't want them to affect any other elements on the page.
I've got a bunch of other elements on the page (popups, dropdowns etc) which have z-index 1, and I would like them to be placed on top of the containerDiv and all of it's childelements.
Since I'm lazy I'd preferably want to avoid having to adjust these element's z-index values based on the circle with the highest z-index...
Much be awesome if there was some way that all other elements could view the containerDiv and all it's children as having the same z-index.
Is this possible to achieve with css?
The answer depends on whether or not your other elements are descendants of the containerDiv or not. To answer the question: Yes, it's almost certainly possible, given a bit of shuffling of the markup.
But what you need to understand is the concept of stacking context:
http://www.w3.org/TR/CSS2/visuren.html#layers
Stacking context is not inherited the way other properties are: "A stacking context is atomic from the point of view of its parent stacking context; boxes in other stacking contexts may not come between any of its boxes." It's not like every element on the page with z-index:2 will be behind everything on the page with z-index:4. Z-index (combined with a position declaration) is typically (though not exclusively) used to resolve the stacking order when two elements share a containing element.

Resources