CSS: что вы могли не знать о свойстве opacity и z-index
Всё, написанное в этой статье, является частью стандарта и есть в спецификации W3C. Но кто ее читает? Да почти никто! Ведь намного проще понять большинство нюансов CSS прямо на практике.
Итак, не ходя долго вокруг да около, перейдём к делу.
Исходное положение:
Имеем разметку с тремя элементами, каждый из которых содержит внутри себя еще по одному элементу. Для наглядности каждому элементу зададим свой уникальный цвет фона. Каждый элемент имеет абсолютное позиционирование от левого верхнего края таким образом, чтобы немного накладываться на идущий за ним элемент.
Первому элементу задано свойство z-index: 1
, а остальные элементы не имеют свойства z-index
.
В коде это выглядит так:
<div>
<span class="red">Red</span>
</div>
<div>
<span class="green">Green</span>
</div>
<div>
<span class="blue">Blue</span>
</div>
.blue, .green, .red {
position: absolute;
}
.blue {
background: blue;
}
.green {
background: green;
}
.red {
background: red;
z-index: 1;
}
Задача:
Сделать так, чтобы красный блок перекрылся синим и зелёным, но при этом выдержав следующие условия:
- Запрещается менять HTML разметку
- Запрещаются манипуляции с z-index элементов
- Свойство
position
элементов менять нельзя
Решение задачи:
Нужно задать свойство opacity
меньше единицы первому элементу (родительскому для красного элемента).
В коде решение выглядит, например, так:
div:first-child {
opacity: 0.99
}
Как это работает
Свойство z-index
выглядит весьма прозрачным - чем больше значение, тем выше элемент. К примеру, элемент со свойством z-index: 10
перекроет элемент с z-index: 5
. Если вы со мной согласны, то здесь и кроется ошибка. На самом деле - всё не так. Вернее - не совсем так. А вот и варианты:
- Если свойства
z-index
иposition
заданы явно, то порядок наложения будет такой же, как порядок следования элементов в разметке. - Если явно ( к примеру
position: relative
илиposition: absolute
) указать позиционирование элементам (и их внутренним элементам), то такие элементы будут выше элементов без явно заданного свойстваposition
. - Последний случай, когда
z-index
задан. Логично предположить, что элемент с большим значениемz-index
будет выше элементов с меньшим значением, а любой элемент, которому заданz-index
будет выше любого элемента, которомуz-index
не задан. Но это не так.z-index
применяется только для элементов, которые спозиционированы явно (например,position: relative
илиposition: absolute
). А помимо этого - свойствоz-index
создаёт контексты наложения и об этом я напишу ниже
Контекст наложения
Элементы, имеющие общего родителя, перемещающиеся на передний или задний план вместе, называются контекст наложения. Понимание контекста наложения и является ключом к пониманию z-index
и порядка наложения элементов.
Каждый контекст наложения имеет свой корневой элемент в HTML структуре. Когда формируется новый контекст на элементе, все дочерние элементы так же попадают в этот контекст и располагаются в порядке наложения. В том случае, когда элемент находится в самом низу одного контекста наложения, он никак не сможет отобразиться над другим элементом в соседнем контексте наложения, располагающимся выше по иерархии, даже если задано большее значение z-index
.
Новый контекст формируется в следующих случаях:
- Если элемент – корневой элемент документа
- Если элемент имеет
position
отличное отstatic
и его значениеz-index
не равноauto
- Если элемент имеет
opacity
меньше 1