background
— это одно из самых часто используемых свойств. Но сообщество веб-разработчиков пока не слишком хорошо осведомлено о возможностях, которые даёт использование множественного фона. Здесь я собираюсь серьёзно поговорить о том, что может дать применение множественного фона, и о том, как использовать стандартные механизмы CSS на полную мощность.В этом материале я подробно расскажу о свойстве
background-image
, приведу наглядные примеры совместного использования нескольких фоновых изображений элемента, рассмотрю сильные стороны такого подхода. Здесь будет много иллюстраций.![](https://habrastorage.org/webt/ok/dp/3u/okdp3us_uwh0hhfk0rn6oamvfwk.jpeg)
Если вы не знакомы с CSS-свойством
background
— хорошо будет, если вы, перед чтением материала, заглянете на эту страницу документации MDN, посвящённую данному свойству.Введение
CSS-свойство
background
— это сокращённое свойство, которое позволяет настраивать следующие обычные свойства элементов:- background-clip
- background-color
- background-image
- background-origin
- background-position
- background-repeat
- background-size
- background-attachment
Здесь основное внимание мы уделим свойствам
background-image
, background-position
и background-size
.Рассмотрим следующий пример:
.element {
background: url(cool.jpg) top left/50px 50px no-repeat;
}
Начальная позиция фонового изображения находится в верхнем левом углу элемента. Размер изображения составляет
50px * 50px
. При настройке свойства background
важно помнить о порядке следования свойств, задающих позицию и размер фонового изображения.![](https://habrastorage.org/getpro/habr/post_images/e1a/7dc/e7f/e1a7dce7f85a4a53b8f6962aba2506d9.png)
Путь к изображению, его позиция и его размер
На предыдущем рисунке за значениями, относящимися к настройке свойства
background-position
, идут значения свойства background-size
. Если разместить эти значения в другом порядке, мы получим неправильно оформленный CSS-код. Например — такой:.element {
/* Осторожно: неправильный CSS */
background: url(cool.jpg) 50px 50px/top left no-repeat;
}
Позиция фонового изображения
Для настройки области расположения фона, исходной позиции фонового изображения, используется свойство
background-origin
. Мне нравится та гибкость, которую даёт свойство background-position
. Оно позволяет позиционировать фон элементов разными способами:- Ключевые слова (
top
,right
,bottom
,left
,center
). - Процентные значения. Например:
50%
. - Значения, задающие некие расстояния. Например:
20px 2.5rem
. - Значения, представляющие собой отступы от краёв элемента. Например:
top 20px left 10px
.
![](https://habrastorage.org/getpro/habr/post_images/2ba/388/2ba/2ba3882ba6cc53cbea602a6c0b5c2218.png)
Система координат
Начало системы координат, используемой при позиционировании фоновых изображений, находится в левом верхнем углу элемента. Начальным значением свойства
background-position
является 0% 0%
.Стоит отметить то, что значение
top left
— это то же самое, что и значение left top
. Браузер достаточно интеллектуален для того чтобы определить то, какая часть этого значения относится к оси X, а какая — к оси Y.![](https://habrastorage.org/getpro/habr/post_images/6b1/72b/b83/6b172bb830cb609ce59e2d73f9b841ef.png)
Конструкции вида top left и left top равнозначны
.element {
background: url(cool.jpg) top left/50px 50px no-repeat;
/* Это - то же самое, что и следующее */
background: url(cool.jpg) left top/50px 50px no-repeat;
}
Размер фонового изображения
Имя свойства, задающего размер фонового изображения,
background-size
, однозначно указывает на роль этого свойства. Размер фонового изображения — это его ширина и высота. При настройке этого свойства нужно учитывать то, что первое значение представляет ширину, а второе — высоту.![](https://habrastorage.org/getpro/habr/post_images/e69/cf5/88f/e69cf588f7a31f971090072032f04a8a.png)
Сначала идёт ширина, а потом — высота
Если ширина и высота фонового изображения являются одинаковыми, это значит, что у нас нет необходимости указывать два значения для
background-size
. В такой ситуации достаточно указать одно значение.Тут, кстати, нелишним будет упомянуть о том, что в спецификации CSS по этому поводу сказано следующее: «Если указано лишь одно значение, то предполагается, что второе значение — это auto». Но этот механизм в браузерах не реализован, хотя в будущем ситуация может измениться. Благодарю Илью Стрельцына за то, что привлёк моё внимание к этой детали.
![](https://habrastorage.org/getpro/habr/post_images/371/8cd/e51/3718cde5164fddf81034f280e5829c47.png)
Одно значение задаёт и ширину, и высоту
Теперь, когда мы поговорили об основах использования свойства
background
, давайте поговорим о том, как работать с несколькими фонами.Множественный фон
В свойстве
background
может быть описан один слой фона, до сих пор мы видели именно такие описания, или — несколько слоёв, свойства которых разделены запятой. Если размеры нескольких фоновых изображений одинаковы, одно из них полностью перекроет другие..element {
background: url(cool.jpg) top left/50px 50px no-repeat,
url(cool.jpg) center/50px 50px no-repeat;
}
![](https://habrastorage.org/getpro/habr/post_images/215/484/68a/21548468a6a725c9f063ee1249b0a2de.png)
Использование нескольких фоновых изображений
На вышеприведённом рисунке у элемента есть два слоя фоновых изображений. Каждое из этих изображений позиционировано по-своему. Это — простейший пример использования множественного фона. А теперь давайте рассмотрим более продвинутый пример.
Порядок наложения фоновых изображений друг на друга
При оснащении элемента несколькими фоновыми изображения, в том случае, если одно из них занимает всю ширину и высоту родительского элемента, важное значение приобретает порядок наложения фонов друг на друга. Принять решение о том, в каком порядке фоны должны накладываться друг на друга, может быть не особенно просто. Рассмотрим следующий пример.
.hero {
min-height: 350px;
background: url('table.jpg') center/cover no-repeat,
url('konafa.svg') center/50px no-repeat;
}
Здесь у нас имеется изображение стола (
table.jpg
) и изображение тарелки (konafa.svg
). Как вы думаете, какое из этих фоновых изображений будет выведено первым? Изображение стола или изображение тарелки?![](https://habrastorage.org/getpro/habr/post_images/f49/4bb/22d/f494bb22dddc50f95e777fd4ed2fccb6.png)
Элемент с двумя фоновыми изображениями
Правильный ответ на этот вопрос заключается в том, что первым будет изображение стола. В CSS фон, описанный первым, накладывается на второй фон, второй фон накладывается на третий и так далее. Изменение порядка описания фонов влияет на их вывод в элементе.
.hero {
background: url('konafa.svg') center/50px no-repeat,
url('table.jpg') center/cover no-repeat;
}
![](https://habrastorage.org/getpro/habr/post_images/936/a5a/415/936a5a415082cd91432f9611ba19530f.png)
Первый фон накладывается на второй
Как видите, фон, заданный первым, находится выше фона, заданного вторым.
Сплошные цвета
Предположим, нам, используя CSS-инструменты настройки фона элемента, нужно сформировать одноцветный фон. Как это сделать? Это, благодаря CSS-градиентам, совсем несложная задача. Дело в том, что если воспользоваться функцией
linear-gradient
с одинаковыми стоп-цветами, это приведёт к появлению сплошного цвета..hero {
background: linear-gradient(#3c88Ec, #3c88Ec)
}
![](https://habrastorage.org/getpro/habr/post_images/d42/c02/354/d42c023547861293e88374d671f4f784.png)
Фон, созданный с помощью linear-gradient и одинаковых стоп-цветов
Тут мы привели простейший пример использования градиента при настройке фона, но градиенты, на самом деле, можно использовать для создания очень интересных и полезных эффектов.
Сценарии использования и практические примеры
?Затемнение фонового изображения
Часто, ради облегчения чтения текста верхнего раздела страницы, фоновое изображение этого раздела нужно затемнить. Это несложно сделать, воспользовавшись двумя фоновыми изображениями.
.hero {
background: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15)),
url("landscape.jpg") center/cover;
}
![](https://habrastorage.org/getpro/habr/post_images/0e4/bc5/435/0e4bc54358dca161002f37f45043e1ed.png)
Затемнённое фоновое изображение
Ещё интереснее то, что тот же метод можно использовать для тонирования фонового изображения элементов.
.hero {
background: linear-gradient(135deg, rgba(177, 234, 77, 0.25), rgba(69, 149, 34, 0.25),
url("landscape.jpg") center/cover;
}
![](https://habrastorage.org/getpro/habr/post_images/7f5/9ea/21e/7f59ea21e4719b2710e340022958de06.png)
Тонированный фон
?Рисование средствами CSS
Возможности использования CSS-градиентов для рисования поистине безграничны. В частности, речь идёт о градиентах, описываемых с помощью функций
linear-gradient
, radial-gradient
и других. В этом простом примере мы разберёмся с тем, как, используя градиенты, нарисовать ноутбук.![](https://habrastorage.org/getpro/habr/post_images/cbc/9ef/38a/cbc9ef38a6de0ac7db4bdcffdff187aa.png)
Изображение ноутбука
Давайте разберём это изображение и подумаем о том, какие градиенты нам понадобятся.
![](https://habrastorage.org/getpro/habr/post_images/290/b07/278/290b072785c3c830618777acc73249ef.png)
Пластиковая рамка дисплея, LCD-дисплей, отражение, скруглённые края корпуса, корпус
Обратите внимание на то, что когда ноутбук «разобран», гораздо легче разобраться в том, какие градиенты нужны для того чтобы его нарисовать с использованием техники применения нескольких фоновых изображений. Возможно, вы заметили то, что я использовал пару окружностей, играющих роль скруглённых углов корпуса ноутбука. Дело в том, что стандартного способа создания градиентов со скруглёнными углами не существует.
Теперь займёмся рисованием. Для начала определим каждый из градиентов в виде CSS-переменной и укажем размер соответствующих элементов. Мне нравится использовать CSS-переменные из-за того, что это может уменьшить сложность кода, делает код чище и облегчает его восприятие. После того, как градиенты описаны, можно переходить к их позиционированию.
:root {
--case: linear-gradient(#222, #222);
--case-size: 152px 103px;
--display: linear-gradient(#fff, #fff);
--display-size: 137px 87px;
--reflection: linear-gradient(205deg, #fff, rgba(255, 255, 255, 0));
--reflection-size: 78px 78px;
--body: linear-gradient(#888, #888);
--body-size: 182px 9px;
--circle: radial-gradient(9px 9px at 5px 5.5px, #888 50%, transparent 50%);
--circle-size: 10px 10px;
}
Итак, градиенты мы описали и задали их размеры. Теперь поразмышляем над их позиционированием. Решение этой задачи облегчит схематичное изображение ноутбука, приведённое ниже.
![](https://habrastorage.org/getpro/habr/post_images/a90/e33/4e4/a90e334e4f3394ded72022b8b7ec8831.png)
Схематичное изображение ноутбука
Реализация отражения света от рамки дисплея ноутбука
Как уже было сказано, слой фона, который должен располагаться над всеми остальными слоями, должен быть определён первым. В нашем случае первым градиентом будет тот, который имитирует отражение света от рамки дисплея ноутбука.
![](https://habrastorage.org/getpro/habr/post_images/dae/2c2/a72/dae2c2a72008066307a7980bb04e0cf7.png)
Отражение света от рамки дисплея ноутбука
LCD-дисплей
Дисплей ноутбука выровнен по центру оси X, а по оси Y он расположен со сдвигом в
6
пикселей от начала координат.![](https://habrastorage.org/getpro/habr/post_images/b6c/24b/7e0/b6c24b7e06eb338e74c6f84b294e0f33.png)
Дисплей ноутбука
Рамка дисплея
Рамка находится ниже дисплея, она центрирована по оси X, по оси Y она расположена со смещением в
0px
от начала координат.![](https://habrastorage.org/getpro/habr/post_images/bac/627/3b2/bac6273b297a16179885f304d6bceb74.png)
Рамка дисплея
Корпус ноутбука
А это — самый интересный элемент. Для начала, надо учесть то, что элемент, представляющий корпус ноутбука, является прямоугольником, и то, что корпус имеет скруглённые края. Это достигается благодаря использованию пары окружностей.
![](https://habrastorage.org/getpro/habr/post_images/af2/f1e/1ed/af2f1e1ed807ee118fe5d5b088323dbf.png)
Корпус ноутбука
Готовый рисунок
:root {
--case: linear-gradient(#222, #222);
--case-size: 152px 103px;
--case-pos: center 0;
--display: linear-gradient(#fff, #fff);
--display-size: 137px 87px;
--display-pos: center 6px;
--reflection: linear-gradient(205deg, #fff, rgba(255, 255, 255, 0));
--reflection-size: 78px 78px;
--reflection-pos: top right;
--body: linear-gradient(#888, #888);
--body-size: 182px 9px;
--body-pos: center bottom;
--circle: radial-gradient(9px 9px at 5px 5.5px, #888 50%, transparent 50%);
--circle-size: 10px 10px;
--circle-left-pos: left bottom;
--circle-right-pos: right bottom;
}
.cool {
width: 190px;
height: 112px;
background-image: var(--reflection), var(--display), var(--case), var(--circle), var(--circle), var(--body);
background-size: var(--reflection-size), var(--display-size), var(--case-size), var(--circle-size), var(--circle-size), var(--body-size);
background-position: var(--reflection-pos), var(--display-pos), var(--case-pos), var(--circle-left-pos), var(--circle-right-pos), var(--body-pos);
background-repeat: no-repeat;
/*outline: solid 1px;*/
}
Вот CodePen-проект, с которым вы можете поэкспериментировать.
?Смешивание нескольких фонов
Возможность использования различных режимов смешивания фонов, накладываемых друг на друга, открывает широкий простор для достижения различных эффектов. Простейший способ использования этого приёма заключается в обесцвечивании изображений. Представим, что в CSS имеется цветное фоновое изображение, которое нужно обесцветить, сделать чёрно-белым.
![](https://habrastorage.org/getpro/habr/post_images/b57/66a/d38/b5766ad38593d84f0bd3de6d2ebec0bc.png)
Цветное изображение и вспомогательный слой чёрного цвета
Обратите внимание на то, что в следующем фрагменте CSS-кода используется свойство
background-blend-mode: color
. Именно оно и позволяет достичь нужного эффекта.hero {
background: linear-gradient(#000, #000),
url("landscape.jpg") center/cover;
background-blend-mode: color;
}
![](https://habrastorage.org/getpro/habr/post_images/28f/4f9/1b7/28f4f91b7a1afa5fdd922a447621e5b0.png)
Обесцвеченное изображение
Пользуетесь ли вы множественными фонами в CSS?
![](https://habrastorage.org/webt/de/0y/l-/de0yl-6ppopvisr_a80b4yuhjj8.png)
sa10ry
Хорошо и подробно подано, спасибо!