Как сделать прозрачный фон на css
Изменение прозрачности фона кажется простой задачей. В CSS есть свойство opacity, которое управляет прозрачностью. Но этот подход работает не всегда. Если нужно разместить, например, текст поверх картинки, то использовать opacity — не лучшее решение.
Давайте разбираться, в чем проблема с вроде бы подходящим свойством CSS и как изменить прозрачность фона картинки, чтобы не испортить внешний вид других частей интерфейса.
Наивный подход — использовать opacity
К вам приходит проджект-менеджер и показывает новый дизайн страницы облачные серверы. В нем есть такие облака. Задача — сделать их полупрозрачными, а сверху добавить текст.
Источник: Shareicon
Первая мысль — сделать прозрачный фон CSS с помощью opacity. Выглядит так, будто это оптимальное решение для поставленной задачи. Набросаем простую разметку и посмотрим, что из этого получится.
HTML:
<div class="cloud">
<h1 class="title">Timeweb Cloud</h1>
</div>
CSS:
.cloud {
background-image: url(../images/cloud.png');
opacity: 1;
}
Свойство opacity принимает значение от 0 до 1, где 0 — полная прозрачность, а 1 — полная непрозрачность. Можно регулировать отображение с очень высокой точностью. Правда, на глаз разница заметна только при значительном изменении.
Сейчас результат выглядит так:
Выставили непрозрачность, выглядит нормально. Но в дизайне явно указано, что картинка должна быть полупрозрачной. Попробуем изменить значение opacity — например, 0.5 вместо 1. Облака должны стать немного светлее, насыщенность цветов ведь тоже изменится.
Вылезла проблема — вместе с фоновой картинкой начал исчезать текст с названием сервиса cloud.timeweb.com. В дизайне страницы такого нет. Более того, если сделать opacity: 0, то текст вообще исчезнет, как и облака под ним. Значит, это решение не подходит. Осталось разобраться, в чём причина такого поведения.
Объяснение простое. Проблема в том, что непрозрачность автоматически наследуется дочерними элементами. Нет свойства CSS, которое можно использовать для изменения непрозрачности только фонового изображения родителя. Возможно, оно появится когда-нибудь в будущем. Пока же нужны небольшие «костыли».
Мы поняли, что такое применение opacity для решения задачи не подходит. Для изменения прозрачности фонового изображения потребуется другой подход.
Гибкий подход — использовать псевдоэлемент
Чтобы решить задачу, нужно поместить фоновое изображение в дочерний элемент родителя. Это гарантирует, что облака и текст будут каждый на своем слое. А непрозрачность каждого слоя можно контролировать по отдельности. В теории это выглядит как то, что нам нужно для достижения эффекта, который отрисовал дизайнер.
Разметка останется такой же, а стили перепишем:
.cloud {
position: relative;
height: 100vh;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.cloud::before {
content: "";
background-image: url('../images/cloud.png');
background-size: cover;
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
opacity: 0.3;
}
.title {
position: relative;
top: 80px;
right: 50px;
}
Элемент .cloud получил свойство position: relative. Это нужно для того, чтобы относительно родителя позиционировать потомков — .cloud::before и .title. Потомки выстраиваются внутри родители с помощью флекса.
Чтобы сделать псевдоэлемент того же размера, что и родитель, необходимо задать ему абсолютное позиционирование. Верхнее, правое, нижнее и левое значения должны быть равны нулю, чтобы :before не схлопывался. У него также должно быть установлено свойство content, иначе он не будет отображаться на странице.
Тексту нужно установить position: relative, чтобы он был поверх наложения и картинки. Если вы не установите position явно, надпись будет скрыта под абсолютно позиционированным псевдоэлементом. Это позволяет добиваться разных интересных эффектов в интерфейсе. Но мы сейчас решаем другую задачу.
Посмотрим на результат. Теперь облака полупрозрачные, а текст — непрозрачный, как того и требует дизайн страницы.
Вместо .cloud::before можно добавить обычный HTML-элемент для фонового изображения CSS — например, ещё один div. Принципиально это ничего не изменит. Но использование псевдоэлементов помогает упростить структуру HTML и не плодить в разметке лишние сущности.
А в чём же гибкость этого подхода?
Мало того, что вы можете сделать из непрозрачного фона прозрачный без влияния на другие части дизайна, так ещё и получаете возможность дополнительно управлять цветом наложения. Для этого достаточно немного изменить стили.
Свойства background-image и background-size перенесём в стили .cloud. В стили .cloud::before добавим background-color: rgba(0,0,0,0.25). Должно получиться так:
.cloud {
position: relative;
height: 100vh;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
background-image: url('../images/cloud.png');
background-size: cover;
}
.cloud::before {
content: "";
position: absolute;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
background-color: rgba(256,256,256,0.75)
}
RGBA — это три основных цвета (Red, Green, Blue) плюс альфа-канал, который помогает управлять прозрачностью. Значение rgba(256,256,256,0.75) говорит о том, что мы наложили белую плашку с непрозрачностью 25%. Вместо белого можно применить любой другой цвет и получить интересный эффект наложения:
Какой способ выбрать — решайте сами. Если с цветами играть не придётся, то можно обойтись первым вариантом. Хотя кто знает, что в следующий раз придёт от дизайнера.
Заключение
Как мы увидели, свойство opacity всё-таки пригодилось. Правда, использовать его «в лоб» для изменения прозрачности не получится. Выход простой — добавить псевдоэлемент, который решит проблему с наследованием.