Подробно о CSS свойстве z-index c position в div с w3

Перевод статьи с: https://iamvdo.me/blog/comprendre-z-index-et-les-contextes-dempilement

Проблема с z-index заключается в том, что очень немногие люди понимают, как это работает. Это не сложно, но если вы никогда не нашли время, чтобы прочитать его спецификацию, есть почти наверняка важные аспекты, о которых вы совершенно не подозреваете.

Не верьте мне? Посмотрите, сможете ли вы решить эту проблему:

Проблема

В следующем HTML вы имеете три <div>элемента, каждый из которых <div>содержит один <span>элемент. Каждому <span>задан цвет фона – красный, зеленый и синий соответственно. Каждый из <span>них также расположен почти в левом верхнем углу документа, слегка перекрывая другие <span>элементы, чтобы вы могли видеть, какие из них уложены впереди. Первое <span>имеет значение z-индекса 1, в то время как другие два не имеют никакого набора z-индексов.

Вот как выглядит HTML и базовый CSS. Я также включил визуальную демонстрацию (через Codepen ) с полным CSS ниже:

<div>
  <span class="red">Red</span>
</div>
<div>
  <span class="green">Green</span>
</div>
<div>
  <span class="blue">Blue</span>
</div>
.red, .green, .blue {
  position: absolute;
}
.red {
  background: red;
  z-index: 1;
}
.green {
  background: green;
}
.blue {
  background: blue;
}

Вот вызов: попробуйте увидеть, можно ли сделать <span>стек красных элементов за синим и зеленым <span>элементами, не нарушая ни одно из следующих правил:

  • Не изменяйте разметку HTML каким-либо образом.
  • Не добавляйте / не изменяйте свойство z-index для любого элемента.
  • Не добавляйте / не изменяйте свойство позиции любого элемента.

Чтобы узнать, можете ли вы это понять, нажмите ссылку на ссылку Codepen выше и немного поиграйте с ней. Если вы преуспели, это должно выглядеть следующим образом.

Предупреждение. Не нажимайте на вкладку CSS в примере ниже или ответьте.

Решение

Решение состоит в том, чтобы добавить значение непрозрачности меньше, чем 1к первому <div>(родительский элемент красного <span>). Вот CSS, который был добавлен в Codepen выше:

div:first-child {
  opacity: .99;
}

Если вы почесываете голову прямо сейчас в шоке и недоверии, что непрозрачность будет иметь какое-то влияние на элементы, уложенные впереди, добро пожаловать в клуб. Я был так же потрясен, когда впервые наткнулся на этот вопрос.

Надеемся, что остальная часть этой статьи сделает вещи более ясными.

Заказ штабеля

Z-индекс кажется таким простым: элементы с более высоким z-индексом укладываются перед элементами с более низким z-индексом, правильно? Ну, на самом деле, нет. Это часть проблемы с z-индексом. Это выглядит так просто, поэтому большинство разработчиков не тратят время на чтение правил.

Каждый элемент документа HTML может быть либо перед, либо за каждым другим элементом документа. Это называется порядком укладки. Правила определения этого порядка довольно четко определены в спецификации, но, как я уже сказал, они не совсем понятны большинству разработчиков.

Когда свойства z-index и position не задействованы, правила довольно просты: в основном порядок укладки совпадает с порядком появления в HTML. (ОК, на самом деле это немного сложнее , но если вы не используете отрицательные поля для перекрытия встроенных элементов, вы, вероятно, не столкнетесь с крайними случаями.)

Когда вы вводите свойство позиции в микс, любые позиционированные элементы (и их дети) отображаются перед любыми не расположенными элементами. ( Для того, чтобы сказать , если элемент «позиционируется» означает , что он имеет значение положение , отличное от static, например, relative, absoluteи т.д.)

Наконец, когда задействуется z-индекс, все становится немного сложнее. Вначале естественно предположить, что элементы с более высокими значениями z-индекса перед элементами с более низкими значениями z-индекса, а любой элемент с z-индексом находится перед любым элементом без z-индекса, но это не так просто , Прежде всего, z-индекс работает только с позиционируемыми элементами. Если вы попытаетесь установить z-индекс для элемента без указанной позиции, он ничего не сделает. Во-вторых, значения z-index могут создавать контексты стекирования, и теперь внезапно казалось, что просто просто стало намного сложнее.

Контексты стеков

Группы элементов с общим родителем, которые перемещаются вперед или назад вместе в порядке укладки, составляют так называемый контекст стекирования. Полное понимание контекстов стекирования – это ключ к тому, чтобы понять, как работают z-index и порядок укладки.

Каждый контекст стекирования имеет один элемент HTML в качестве его корневого элемента. Когда новый элемент стекирования формируется на элементе, этот контекст стекирования ограничивает все его дочерние элементы определенным местом в порядке укладки. Это означает, что если элемент содержится в контексте стекирования в нижней части порядка укладки, нет способа заставить его появиться перед другим элементом в другом контексте стекирования, который выше в порядке укладки, даже с z-индекс миллиарда!

Новые контексты стекирования могут быть сформированы на элементе одним из трех способов:

  • Когда элемент является корневым элементом документа ( <html>элемента)
  • Когда элемент имеет значение позиции, отличное от значения staticz-index, отличное отauto
  • Когда элемент имеет значение непрозрачности меньше, чем 1

Первый и второй способы формирования контекста укладки имеют большой смысл и, как правило, понимаются веб-разработчиками (даже если они не знают, что они называются).

Третий способ (непрозрачность) почти никогда не упоминается вне документов спецификации w3c.

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

Определение позиции элемента в порядке укладки

Фактически определение глобального порядка упорядочивания для всех элементов на странице (включая границы, фоны, текстовые узлы и т. Д.) Чрезвычайно сложно и далеко выходит за рамки этой статьи (опять же, я отсылаю вас к спецификации ).

Но для большинства целей и целей базовое понимание заказа может пройти долгий путь и помочь сохранить CSS-прогноз предсказуемым. Итак, давайте начнем с разбивки порядка на отдельные контексты стекирования.

Порядок укладки в рамках одного стекового контекста

Вот основные правила для определения порядка укладки в одном контексте стекирования (от начала до конца):

  1. Корневой элемент контекста контекста
  2. Позиционированные элементы (и их дочерние элементы) с отрицательными значениями z-индекса (более высокие значения складываются перед более низкими значениями, элементы с одинаковым значением складываются в соответствии с внешним видом в HTML)
  3. Нерасположенные элементы (упорядоченные по внешнему виду в HTML)
  4. Позиционированные элементы (и их дочерние элементы) с индексом z-индекса auto(упорядоченным по внешнему виду в HTML)
  5. Позиционированные элементы (и их дочерние элементы) с положительными значениями z-индекса (более высокие значения складываются перед более низкими значениями, элементы с одинаковым значением складываются в соответствии с внешним видом в HTML)

Примечание: позиционированные элементы с отрицательными z-индексами сначала упорядочиваются в контексте стекирования, что означает, что они появляются за всеми остальными элементами. Из-за этого становится возможным появление элемента за его собственным родителем, что обычно невозможно. Это будет работать, только если родитель элемента находится в одном и том же контексте стекирования и не является корневым элементом этого стекового контекста. Отличным примером этого являются CSS-тени Николаса Галлахера без изображений .

Глобальный порядок штабелирования

С четким пониманием того, как / когда формируются новые контексты стекирования, а также понимание порядка укладки в контексте стекирования, выяснение того, где определенный элемент будет отображаться в глобальном порядке укладки, не так уж плох.

Ключ, чтобы избежать споткнуться, может определить, когда формируются новые контексты стекирования. Если вы устанавливаете z-индекс миллиарда на элемент и не продвигаетесь вперед в порядке укладки, найдите его дерево предков и посмотрите, не образуют ли какие-либо из его родителей контексты стекирования. Если они это сделают, ваш z-индекс миллиарда не принесет вам никакой пользы.

Завершение

Возвращаясь к исходной проблеме, я воссоздал структуру HTML, добавляя комментарии в каждый тег, указывающий свое место в порядке укладки. Этот порядок предполагает исходный CSS.

<div><!-- 1 -->
  <span class="red"><!-- 6 --></span>
</div>
<div><!-- 2 -->
  <span class="green"><!-- 4 --><span>
</div>
<div><!-- 3 -->
  <span class="blue"><!-- 5 --></span>
</div>

Когда мы добавляем правило непрозрачности к первому <div>, порядок укладки изменяется следующим образом:

<div><!-- 1 -->
  <span class="red"><!-- 1.1 --></span>
</div>
<div><!-- 2 -->
  <span class="green"><!-- 4 --><span>
</div>
<div><!-- 3 -->
  <span class="blue"><!-- 5 --></span>
</div>

span.redраньше, 6но он был изменен 1.1. Я использовал точечную нотацию, чтобы показать, что был создан новый контекст стекирования и span.redтеперь является первым элементом в этом новом контексте.

Надеюсь, теперь стало еще более понятно, почему красный ящик двигался за другими коробками. Исходный пример содержал только два контекста стекирования: корневой и один сформированный span.red. Когда мы добавили непрозрачность к родительскому элементу, span.redмы сформировали третий контекст стекирования и, как результат, значение z-index span.redприменимо только в этом новом контексте. Поскольку первый <div>(тот, на который мы применили непрозрачность), и его дочерние элементы не имеют установленных позиций или значений z-индекса, их порядок стекирования определяется их порядком исходного кода в HTML, что означает первый <div>и все элементы, содержащиеся в его контекст стекирования отображаются за вторым и третьим <div>элементами.

Leave a Reply

Close Menu