псевдоэлемент перекрывает исходный даже с z-индексом - PullRequest
0 голосов
/ 08 мая 2018

Пожалуйста, кто-нибудь может мне объяснить это: почему, черт возьми, z-index не работает?

html,body,div {margin:0;padding:0;}
.bz {
    position: absolute;
    z-index: 1;
    display: block;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    width: 25px;
    height: 25px;
    border: 2px solid #000;
    background: #0f0;
    border-radius: 50%;
}
.bz:before {
    content: '';
    display: block;
    position: absolute;
    z-index: -1;
    bottom: 0;
    right: 0;
    width: 8px;
    height: 25px;
    transform: rotate(315deg);
    background: #f00;
}
.bz:after {
    content: '';
    display: block;
    position: absolute;
    z-index: -1;
    bottom: 0;
    right: 0;
    width: 8px;
    height: 25px;
    transform: rotate(45deg);
    background: #00f;
}
<div class="bz">
  
</div>

в этом случае псевдоэлементы не должны перекрывать исходный, верно?

Я немного поиграл (да!) И обнаружил, что z-index работает правильно на самих псевдоэлементах:

:after (z-index: 0) > :before (z-index: 0)

:after (z-index: -1) < :before (z-index: 1)

Так что, черт возьми, здесь происходит?!

1 Ответ

0 голосов
/ 08 мая 2018

Я полагаю, что это из-за "стековых контекстов". Контекст наложения подобен колоде карт, вы можете управлять порядком наложения в пределах одной колоды, но если у вас есть две колоды, порядок наложения одного не влияет на порядок наложения другого. Псевдоэлементы (::before и ::after) находятся в контексте стека, отличном от самого основного элемента, и, как следствие, z-index этих псевдоэлементов не сопоставимы с z-index основного элемент.

С MDN :

Каждый контекст стека полностью независим от своих братьев и сестер: При обработке суммирования учитываются только элементы-потомки .

Изменяя структуру HTML таким образом, чтобы все визуализированные элементы были родственными элементами и потомками общего родителя, z-index работает как надо.

#wrapper { 
  position:absolute;
  top:50%;
  left:50%;
}

.bz {
    display: block;
    width: 25px;
    height: 25px;
    border: 2px solid #000;
    background: #0f0;
    border-radius: 50%;
    z-index: 1; /* Not actually necessary because the other z-indexes now apply */
}

.red {
    content: '';
    display: block;
    position: absolute;
    z-index: -1;
    bottom: 0;
    right: 0;
    width: 8px;
    height: 25px;
    transform: rotate(315deg);
    background: #f00;
}
.blue {
    content: '';
    display: block;
    position: absolute;
    z-index: -1;
    bottom: 0;
    right: 0;
    width: 8px;
    height: 25px;
    transform: rotate(45deg);
    background: #00f;
}
<div id="wrapper">
  <!-- Now, all the child elements are in the same stacking context. -->
  <div class="bz"></div>
  <div class="red"></div>
  <div class="blue"></div>
</div>
...