Это базовая проблема со слоями. Давайте разберем спецификацию CSS на визуальном форматировании , чтобы выяснить, почему.
Порядок, в котором дерево рендеринга нарисовано на холсте, описывается в терминах стековых контекстов.
Хорошо, давайте посмотрим, в каком «стековом контексте» мы находимся. Для этого нам нужно знать, когда создается новый стековый контекст.
[Значение z-index для целого числа] ... - это уровень стека сгенерированного блока в текущем контексте стека. Блок также устанавливает локальный контекст стека, в котором его уровень стека равен «0».
Ну, у нас нет значений z-index - так что все они автоматически.
Корневой элемент формирует корневой контекст стека. Другие контексты суммирования генерируются любым позиционированным элементом (включая относительно позиционированные элементы), имеющим вычисленное значение «z-index», кроме «auto».
Нет, позиционированных элементов тоже нет. Похоже, мы все в «контексте укладки корня».
Ящики с одним и тем же уровнем стека в контексте стекирования укладываются в обратном порядке в соответствии с порядком дерева документов.
Это, безусловно, объясняет, почему .right1
закрашивает .left1
- это после него в исходном порядке. (Обратите внимание, что проблема с закрашиванием будет лучше, если вы удалите margin-left: 200px
из .right2
).
Итак, теперь, когда мы знаем проблему (и что она соответствует спецификации) - как мы можем это исправить? Проще всего было бы сделать z-индекс .left1
выше .right1
. Поскольку они находятся в одном и том же контексте стека, более высокий z-индекс переопределит исходный порядок:
.variant2 .left1 { position: relative; z-index: 1; }
Или, если мы продолжим читать спецификацию - мы заметим, что:
Каждый контекст стека состоит из следующих уровней стека (от спины к фронту):
- фон и границы элемента, формирующего контекст стека.
- контексты суммирования потомков с отрицательными уровнями стека.
- уровень стека, содержащий непозиционируемых потомков в потоке, не расположенных на уровне строки.
- уровень суммирования для непозиционированных поплавков и их содержимого.
- уровень стека для непозиционированных потомков in-level in-flow.
- уровень стека для позиционируемых потомков с z-index: auto и любой контекст стека потомков с z-index: 0.
- контексты укладки потомков с положительными уровнями стека.
, что означает, что мы можем просто сделать:
.variant2 .left1 { position: relative; }
, который даст .left1
"уровень суммирования" 6 - который переопределит .right1
уровень стека 4.