How does z-index work with its default values?

旧街凉风 提交于 2021-02-08 06:37:40

问题


can anyone explain how z-index default value works in this snippet

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  width: 150px;
}

li {
  position: relative;
}
li ul {
  position: absolute;
  background: green;
  left: 20%;
  border: 1px solid;
}

.foo {
  background: red;
}
<ul >
  <li>
    <a href="">main element</a>
    <ul  class="first">
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
        <ul class="foo">
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
        </ul>
      </li>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
    </ul>
  </li>
</ul>

I expected sub ul to be on the top

but I don't know how text from top level wrapped over text from lower level ?

I can notice sub ul [red one] on the top and it can hide the top level border

So I expected that ul here working like container so every child element will follow it


I know If I give it z-index:1

will resolve it but I hope to understand the situation here if is possible


回答1:


It's all about paiting order. First let's add a top value to better see what is happening:

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  width: 150px;
}

li {
  position: relative;
}
li ul {
  position: absolute;
  background: green;
  left: 20%;
  top:-20%;
  border: 1px solid;
}

.foo {
  background: red;
}
a {
  font-size:20px;
  color:#fff;
}
<ul >
  <li>
    <a href="">main element</a>
    <ul  class="first">
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
        <ul class="foo">
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
        </ul>
      </li>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
    </ul>
  </li>
</ul>

Note how the red element is above the first 3 elements and below the last 3 elements. If we check the specification related to the painting order we can read the following:

  1. All positioned, opacity or transform descendants, in tree order that fall into the following categories:
    1. All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order. For those with 'z-index: auto', treat the element as if it created a new stacking context, but any positioned descendants and descendants which actually create a new stacking context should be considered part of the parent stacking context, not this new one.

The main trick is here. All your elements are positionned and no one has z-index specified so all will belong to the same stacking context and we will follow the tree order to paint them.

Following this logic we will have this order:

  1. the ul with class first (the green box)
  2. the first 3 li inside ul.first
  3. the ul with class foo (the red box)
  4. all the li inside ul.foo
  5. the last 3 li inside ul.first

Adding a z-index will change the order and will also create some stacking context.


z-index:0 on ul.foo will create a stacking context but will have no effect since we are already painting all the elements inside it right after it.

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  width: 150px;
}

li {
  position: relative;
}
li ul {
  position: absolute;
  background: green;
  left: 20%;
  top:-20%;
  border: 1px solid;
}

.foo {
  background: red;
  z-index:0;
}
a {
  font-size:20px;
  color:#fff;
}
<ul >
  <li>
    <a href="">main element</a>
    <ul  class="first">
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
        <ul class="foo">
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
        </ul>
      </li>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
    </ul>
  </li>
</ul>

z-index > 0 on ul.foo will move it to the top of everything since it will get painting at the step (9)

  1. Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index order (smallest first) then tree order.

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  width: 150px;
}

li {
  position: relative;
}
li ul {
  position: absolute;
  background: green;
  left: 20%;
  top:-20%;
  border: 1px solid;
}

.foo {
  background: red;
  z-index:2;
}
a {
  font-size:20px;
  color:#fff;
}
<ul >
  <li>
    <a href="">main element</a>
    <ul  class="first">
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
        <ul class="foo">
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
        </ul>
      </li>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
    </ul>
  </li>
</ul>

z-index < 0 on ul.foo will move it to the bottom of everything since it will get painting at the step (3)

  1. Stacking contexts formed by positioned descendants with negative z-indices (excluding 0) in z-index order (most negative first) then tree order.

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  width: 150px;
}

li {
  position: relative;
}
li ul {
  position: absolute;
  background: green;
  left: 20%;
  top:-20%;
  border: 1px solid;
}

.foo {
  background: red;
  z-index:-2;
}
a {
  font-size:20px;
  color:#fff;
}
<ul >
  <li>
    <a href="">main element</a>
    <ul  class="first">
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
        <ul class="foo">
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
        </ul>
      </li>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
    </ul>
  </li>
</ul>

z-index < 0 on ul.foo and z-index different from auto on ul.first will first paint the green box then ul.foo then all the li inside ul.first

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  width: 150px;
}

li {
  position: relative;
}
li ul {
  position: absolute;
  background: green;
  left: 20%;
  top:-20%;
  border: 1px solid;
  z-index:0;
}

.foo {
  background: red;
  z-index:-2;
}
a {
  font-size:20px;
  color:#fff;
}
<ul >
  <li>
    <a href="">main element</a>
    <ul  class="first">
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
        <ul class="foo">
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
          <li class="secound"><a href="">Secound Level</a></li>
        </ul>
      </li>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
      <li><a href="">First level</a>
    </ul>
  </li>
</ul>

Related question to get more details:

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



来源:https://stackoverflow.com/questions/59550932/how-does-z-index-work-with-its-default-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!