Базовый арсенал Frontend-разработчика
December 12, 2023

3 способа наложить пересекающиеся элементы

Уровень: Junior

В этой короткой статье разберем одну из типовых задач 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
}

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

Слева непрозрачный блок. Контрастность текста 3.99. Справа блок с прозрачностью 70%. Контрастность текста - 2.34, что ниже нормы Accessibility

Способ 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