3 способа наложить пересекающиеся элементы
В этой короткой статье разберем одну из типовых задач Frontend-разработчика.
Дано: два пересекающихся элемента.
Задача: верхний элемент должен иметь прозрачность так, чтобы под ним был виден нижний элемент
<div class="block-1"> Block 1 </div> <div class="block-2 transparent"> Block 2 </div>
.block-1 { display: flex; align-items: center; justify-content: center; width: 200px; height: 200px; border: 1px solid #aaa; background: #0000ff; color: #fff; font-size: 32px; } .block-2 { display: flex; align-items: center; justify-content: center; position: absolute; top: 100px; left: 100px; width: 200px; height: 200px; border: 1px solid #aaa; background: #ff0000; color: #fff; font-size: 32px; } .transparent { // здесь будем добавлять прозрачность верхенму блоку }
Способ 1. opacity
Самый очевидный способ, использовать свойство opacity
.transparent { opacity: 0.7; }
Альтернативно, прозрачность можно добавить через фильтр
.transparent { filter: opacity(0.7); filter: alpha(opacity=70); // для InternetExplorer }
У данного подхода есть один существенный недостаток. Прозрачным становится весь блок, вместе со всем своим содержимым, что далеко не всегда уместно. В данном конкретном случае, текст тоже становится прозрачным, что снижает показатель его контрастности
Способ 2. background-color
Другой способ - сделать прозрачным только фон блока с помощью аlpha-канала.
RGBA
Для этого воспользуемся CSS-функцией rgba. Функция принимает 4 аргумента: red, green, blue и alpha. Соответственно, чтобы ей воспользоваться, нам нужно перевести наш HEX-цвет в RGB и добавить желаемый alpha. Для преобразования Hex в RGB потребуется произвести несложный арифметический расчет. Для удобства можно, так же использовать стандартный калькулятор, поддерживающий 16-ричную систему счисления или воспользоваться любым из огромного числа онлайн сервисов.
FF 00 00 = rgba(255, 0, 0) = rgba(255, 0, 0, 1)
rgba(255, 0, 0, 0.7) - где alpha = 0.7
.transparent { background-color: rgba(255, 0, 0, 0.7); }
Недостатки этого способа рассмотрим чуть ниже, а пока, представлю еще один похожий вариант.
HEXA
Аналогично, alpha-канал можно добавить не через RGBA, а сразу в HEX, точнее HEXA. В этом формате альфа канал можно задать 16-ричным числом, так же, как три основных цвета.
FF 00 00 (hex) = rgba(255, 0, 0, 1) = FF 00 00 FF (hexa)
rgba(255, 0, 0, 0.7) = FF 00 00 B2 (hexa)
.transparent { background-color: #ff0000b2; }
HSLA
Еще один метод добавить alpha-канал - HSLA. Работает функция так же, как и первые две, только вместо red / green / blue, она принимает Hue (оттенок) / Saturate (насыщенность) / Lightness (яркость).
FF 00 00 = hsl(0, 100%, 50%) = hsla(0, 100%, 50%, 1)
rgba(255, 0, 0, 0.7) = hsla(0, 100%, 50%, 0.7)
.transparent { background-color: hsla(0, 100%, 50%, 0.7); }
В большинстве случаев alpha-канала достаточно, чтобы решить задачу с прозрачностью, но и у этого способа есть одни недостаток. В случае со сложным background (например, изображение) он не сработает.
Способ 3. mix-blend-mode
Еще один альтернативный вариант. Вместо того, чтобы делать элемент прозрачным, воспользуемся механизмом наложения цветов браузером. В этом нам поможет свойство mix-blend-mode. У него есть много разных значений, подробнее о них можно узнать в документации. Для примера, попробуем значение multiply
.transparent { mix-blend-mode: multiply; }
Стоит сказать, что данный способ, все таки, не добавляет прозрачность элементу, он позволяет смешать/наложить цвета разных элементов тем или иным образом, однако, основную функцию нашей исходной задачи решает. Большим плюсом является тот факт, что в качестве фона может выступать не только цвет, но и произвольное изображение.
Заключение
В этой статье я представил 3 основных способа наложить два элемента друг на друга. У каждого есть свои плюсы и минусы. Как и во многих других случаях, на практике, одного универсального на 100% метода не существует. В разных ситуациях требуются разные подходы. Однако, этих трех достаточно, чтобы закрыть любой потенциальный кейс.
EN - https://t.me/frontend_almanac
RU - https://t.me/frontend_almanac_ru
English version: https://blog.frontend-almanac.com/bMWRMcKR81N