Objective:
Not long ago, colleague S met with a question about position and z-index. He took a day did not fix, mass of e-mail to seek help, I initially thought very simple, on the initiative said to help, after a simple attempt, only to find seemingly not so simple. The problem mainly revolves around position and Z-index.
Problem:
Our project is react, colleague S has a table,table in the row, this table with a third party component, specifically what component does not matter, in short, these row has a CSS property:
Positon:absolute;
Then, with a custom drop-down box component in each row, the drop-down box will pop up with a container of options, and he expects the option's container div (div-options) to be at the top of the page, meaning it won't be obscured by anything else. But the result is obscured by the row after the current row. The initial state is similar to the following example:
Https://codepen.io/bee0060/pen/GGvMxb
In my example, you can simply add a Z-index attribute that is greater than 0 to the div-options solution. Only in my colleague's local, seemingly only this can not be solved, the specific reason was not aware of it, so there is no detailed investigation. But my guess now is that each row has a Z-index attribute on it, similar to the following example: (Yes, div-options in this example will be obscured by the row behind it)
Https://codepen.io/bee0060/pen/PaVwvj
After discovering that only adding z-index to Div-options was unable to solve the problem, I also tried to suggest that my colleagues add a z-index to each row, and that the value is less than div-options Z-index, but div-options is still obscured by the back row.
I thought it was unbelievable, and the whole person was ignorant.
Later, I tried several ways to go home from work without success. On the way to work I want to realize what, I went home to try, found the following two solutions:
1. In the case of all row with Z-ind "WX, give Div-options a large z-index value on row, so that div-options does not need z-index and will not be obscured, https://codepen.io/bee0060/ Pen/ekepzg
2. Extract the div-options out of the table, so that they do not have a parent-child hierarchy, and then to a larger Z-idnex can also be resolved, Https://codepen.io/bee0060/pen/yEozro
In the current project environment, considering that we are using react, I recommend that my colleagues adopt a second solution. Because in the display div-options to modify the z-index of the row, this operation to affect too many objects, and will affect the ancestor (parent) components, feel not very good, you know, the more components affected, will trigger more diff and Re-render, So I still hope that this operation can only be done by notifying as few components as possible.
The problem is solved, but how did the problem arise?
I looked up some information, and here are some of my analyses and speculations, mainly for friends who want to solve problems quickly and get a ballpark idea.
If you need more detailed and accurate explanations, I need to check more information and open another blog, or you can look at other more detailed blog, just that there is an article I feel good.
Well, then I'm going to start acting.
Cause Analysis:
First of all, some nonsense is still to be said.
Let me make a list of key analysis criteria:
1. The Z-index property of only the element that has been positioned (that is, the Position property value is a non-static element) takes effect
2. In the same stack, the Z-index value is large to cover small objects
3. In the same stack, if the Z-index value is the same, subsequent objects obscure the previous object.
4. Elements that are z-index to numbers (including 0) create a stack level (temporary stack b) in the current stacking context (temporarily called Stack a), and stack B can be considered a sub-stack of stack A.
5. An object is only z-index compared to an object in the same stacking context and determines which one is obscured.
6. If the A and B objects are in the same stacking context and are determined by the Z-index rule that B appears above A, then stack B and all of its child stacks will appear on top of stack A and the child stack of stack A. (because the order in which the child stacks are displayed cannot exceed the order of the parent stack, regardless of the number of Z-index)
The term "stacking" appears more than once, and stacking can be understood as a number of small spaces in CSS space that are stacked with each other in the z-axis direction. Many blogs in the legend stacked like a piece of paper, in fact, is not accurate, because the stack can have children stacked, there can be unlimited levels, so I think it is more appropriate to understand the space. Can be understood as a more flat space. A stack is created by default in CSS space (or you can call DOM or HTML space).
After reading the above, it is estimated that we have a clue. In CSS space, if the object is not positioned (position is not static) or has been defined but Z-index is not a number, then the object will be within the stack where the parent element resides, or a new stack will be created in the same stack as the parent object. In general, all objects will be placed in the default stack if they are all not created with stacked objects (not anchored or z-index are not numbers).
The sub-stacks within each stack cannot be displayed in the order of their parent stacks, which should be better understood if the stack is understood as space. In the words of the novel: Zhang San is a person in a certain world, he can not go beyond the world of your own (of course, the general practice of fiction is written to be able to exceed, you can understand my words just fine).
Then the combination of the problems encountered before the understanding.
-By default, when row is only Position:absolute, and none of them are z-index, they are in the default stack and obscured in the order of row, and div-options belong to a row, in order, He uses a display order with his row at most, so it is naturally obscured by the row behind it.
-After adding a z-index greater than 0 to Div-options alone, Div-options creates a stack level on the default stack (that is, the stack on which all row resides), and because Z-index is greater than 0, after comparing all row objects in the same parent stack, Since row has no z-index, the display order and Z-index are the same as 0 o'clock, so div-options will show all above the row and will not be obscured.
-After adding a number to the row Z-index (even 0), subsequent rows will cover the div-options. Because the row that specifies the number Z-index creates its own stack in the parent stack, and div-options creates the stack within the stack of its parent row. The Div-options parent row (temporarily called ROWP) will only be compared to the stack of other row in the same parent stack, so the subsequent row will appear above the ROWP. Div-options is a stacked sub-stack of ROWP, so no matter how large div-options z-index, it cannot exceed the stack where ROWP is located. So div-options will be covered by the following rows.
So my two solution is to start with two things:
1. Give rowp greater z-index to show above all brothers rows, then Div-options no z-index will be covered by subsequent row.
2. Extract the div-options, no longer as the ROWP sub-object, also will not keep the ROWP stacking order effect, and can be implemented so that div-options is not covered by the subsequent row, because div-options and all rows can be in the same parent stack, Who first who is only determined by their respective z-index values.
Well, the analysis of thinking and speculation is here, originally wanted to be as short as possible, but still write so much.
The last sentence is the most important: if there is falsehood, please correct me!
Something:
In the resolution process, did not find the relevant information on the Internet ' I (although later found), and their own previous research is not deep, in line with the principle of dry, to avoid the next encounter and take time to toss, so write this article.
Resources:
1. Deep understanding of cascading contexts and stacking order in CSS
2. The CSS authoritative guide
3. Https://developer.mozilla.org/zh-CN/docs/Web/CSS/z-index
[CSS] A z-index and position problem solving record