Как сделать несколько фоновых изображений CSS. Новый способ: множественные фоны на CSS3

Сегодня мы займемся работай над фоновыми рисунками, которые устанавливаются с помощью свойства background и его дополнительными значениями. Рассмотрим пару практических примеров в реализации установки нескольких фонов к одному и тому же элементу.

Это может пригодиться во многих случаях и моментах. Особенно, использование псевдоэлементов в этом деле, так как они являются очень гибкими в параметрах.

Множество фоновых изображений

Чтобы не создавать блок внутри блока, проще всего дописать одну строчку правил к главному элементу и, таким образом, получим нужный результат. Можно считать это лаконичным вариантам, тем более, избавить от необходимости лишний раз лезть в исходный код. Все будет сделано одними только средствами CSS.

Blockimg{ background: url("img/img2.png"),/*самых верхний фон и дальше последовательно*/ url("img/img3.png"), url("img/img1.jpg"); background-position:370px center, 120px 150px, center center;/*позиция изображений*/ background-repeat: no-repeat;/*повторение рисунка*/ background-color: #444;/*если нужен цвет фона*/ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); margin: 100px auto 15px; box-sizing: border-box; padding: 25px; width:700px; min-height: 300px; } /*сокращенный вариант*/ .blockimg{ background: url("img/img2.png") no-repeat 370px center, url("img/img3.png") no-repeat 120px 150px, url("img/img1.jpg") no-repeat center center; margin: 100px auto 15px; box-sizing: border-box; padding: 25px; width:700px; min-height: 300px; }

Пояснение. Задаем элементу фоновой рисунок, указывая путь к его местоположению. Через запятую нам дается возможность прописать еще множество бэкграундов, как это видно в коде выше. Порядок расположения их численности определяет какое изображение будет находиться поверх других. То есть, первый фон – выше всех остальных, а дальше идет последовательность по принципу обычного графического редактора.

Следом указывается дополнительные параметры через отдельные свойства: позиция, повторение, размер, если нужно, то еще цвет. Также обращаем внимания, что все параметры прописываются через запятую, в том же порядке, в каком числе находится картинка.

И последняя деталь. Весь код можно сократить, использовав лишь одно универсальное свойство background . В примере кода есть второй вариант где показано, как это делается.

Фоновой рисунок через псевдоэлемент

Также не стоит забывать про альтернативные варианты, как таковыми, являются псевдоэлементы before и after . В их применении есть положительный плюс – изображение можно заносить за край элемента, так чтоб оно не исчезало на границе, а было поверх нее. Такой прием пригодится, если нужно будет сделать что-то вроде 3Д эффекта.

Blockimg{ background: url("img/img1.jpg") no-repeat;/*фон элемента*/ position:relative;/*область позиционирования*/ margin: 200px auto 15px; box-sizing: border-box; padding: 25px; width:700px; min-height: 300px; } .blockimg::before{ background: url("img/img1.png") no-repeat center center; bottom: 0; content: ""; height: 295px; left: 0; position: absolute;/*абсолютное позиционирование*/ right: 0; top: -150px; }

Пояснение. По сути, все очень просто. Главному элементу обычным путем задаем фон. Дальше идет ключевое свойство position: relative; , которое определяет область для перемещения другого элемента, находящегося в главном элементе и имеющем свойство position:absolute; .

Вместо другого элемента, хотя формально, он идет как отдельная область, используем псевдоэлемент. Ему задаем абсолютную позицию и позиционируем в необходимое нам место.

Рассказывая о свойстве background-image в начале раздела, мы не упомянули об одной особенности: в CSS3 вы можете добавлять несколько фонов для одного элемента, просто перечисляя их через запятую. Особенно это бывает нужно, когда элемент с фоном имеет непостоянную ширину или высоту, и фон должен подстраиваться под его размер.

Как задать несколько фонов в CSS

Мы продемонстрируем вам пример, который вполне может пригодиться на практике. Представим, что нам необходимо поместить блок с текстом в рамку. Рамка представляет собой графический файл в формате PNG:


В данной задаче высота текста нам неизвестна - мы не знаем, поместится ли текст полностью в рамку или же выйдет за ее пределы. Из-за этой неизвестной величины мы не можем рисковать, используя исходный рисунок рамки в качестве фона. Но с помощью CSS мы можем заставить эту рамку удлиняться при необходимости. Для этого придется разделить исходный рисунок в графическом редакторе на три части - верх, низ и середину - и сохранить каждый файл отдельно. Вот так:

Верхняя часть рамки


Нижняя часть рамки


Середина рамки


Фон с изображением середины рамки мы сделаем повторяющимся по оси Y , тогда как верх и низ рамы не будут дублироваться. Добавим все три фона к элементу, а также запишем другие необходимые стили:

Frame { background-image: url(https://goo.gl/tKyzHt), /* верхняя часть рамки */ url(https://goo.gl/SUKymM), /* нижняя часть рамки */ url(https://goo.gl/Km7HVV); /* середина рамки */ background-position: center top, /* позиция верха рамки */ center bottom, /* позиция низа рамки */ center top; /* позиция середины рамки */ background-repeat: no-repeat, /* верх рамки не повторяется */ no-repeat, /* низ рамки не повторяется */ repeat-y; /* середина рамки повторяется по вертикали */ background-size: contain; /* здесь для всех фонов одинаковое значение */ height: auto; /* высота блока зависит от количества содержимого */ width: 400px; /* ширина блока фиксированная */ padding: 30px; /* внутренние отступы блока */ }

Каждый фон необходимо отделять запятой, и только после последнего ставится точка с запятой, означающая конец объявления. Для удобства и лучшей читабельности кода рекомендуем указывать каждый URL в новой строке.

Фоновые рисунки размещаются по принципу слоев - один под другим. Фон, указанный первым, будет находиться в верхнем слое, второй фон - под первым, третий - под первыми двумя. Именно поэтому мы поместили рисунок с серединой рамки в самый конец - чтобы он не накладывался на верхнюю и нижнюю части.

Далее в коде заданы свойства background-position и background-repeat для каждого фона (соблюдается тот же порядок, в котором расположены фоновые рисунки). Да, вы правильно догадались: если это требуется, то через запятую можно указывать значения и других фоновых свойств. А если вам нужно применить одно значение для всех фонов, вы записываете его, как обычно (в нашем случае это свойство background-size: contain).

Что ж, давайте взглянем на результат:


Как видим, рамка расположилась правильно, и теперь она красиво обрамляет содержимое блока. Что же будет, если мы увеличим количество текста в блоке? Смотрим:


Средняя часть нашей рамки продублировалась по вертикали необходимое количество раз, словно вытягиваясь в длину и подстраиваясь под текст. Это и есть тот эффект, который не удалось бы реализовать, если бы мы использовали цельное изображение рамки. Добавим еще больше текста для наглядности:


Безусловно, несколько фонов можно использовать и для решения других задач. Мы показали лишь один пример из множества. Попробуйте придумать свою ситуацию и попрактиковаться в использовании группы фоновых рисунков.

Использование сокращенной записи

Свойство background также принимает множественные значения. В случае использования нескольких фонов сокращенная запись может оказаться намного более удобной, ведь в ней сложнее запутаться. Давайте переделаем наш код для рамки:

Background: url(https://goo.gl/tKyzHt) center top / contain no-repeat, /* верх рамки */ url(https://goo.gl/SUKymM) center bottom / contain no-repeat, /* низ рамки */ url(https://goo.gl/Km7HVV) center top / contain repeat-y; /* середина рамки */

Такой вариант выглядит менее громоздко и легче воспринимается.

К одному элементу можно добавить сразу несколько фоновых изображений через единственное свойство background . Это позволяет обойтись одним элементом для создания сложного фона или одной картинкой, выводя её несколько раз с различными настройками. Все изображения со своими параметрами перечисляются через запятую, при этом вначале указывается картинка которая выводится поверх остальных изображений, а последней, соответственно, самая нижняя картинка. В примере 1 показано создание фона с тремя изображениями.

Пример 1. Три фона

Фон

Если требуется отдельно задать какое-то стилевое свойство для фона, вроде background-size как в примере выше, то параметры для каждого фона перечисляются через запятую. Результат данного примера показан на рис. 1.

Рис. 1. Фон с тремя изображениями

Отдельные изображения для фона позволяют менять их положение, а также анимировать, как показано в примере 2.

Пример 2. Анимированный фон

Фон

Рассмотрим теперь как применять одну картинку для создания блока с рамкой (рис. 2). Ширина блока фиксированная, а высота тянется в зависимости от объёма содержимого блока.

Рис. 2. Рисованная рамка

На рисунке хорошо заметна верхняя и нижняя часть, которую требуется вырезать в графическом редакторе и расположить по горизонтали. Средняя часть выбирается таким образом, чтобы она повторялась без швов по вертикали. Картинка имеет выраженный повторяющийся орнамент, так что трудностей с выделением быть не должно. В итоге получится такое подготовленное изображение (рис. 3). Клетчатое поле обозначает прозрачность, оно позволяет задавать наряду с изображениями цветной фон и легко менять его через стили.

Рис. 3. Подготовленное для фона изображение

Сам фон выводится свойством background , оно же задаёт и координаты нужного фрагмента. Параметры каждого фона перечисляются через запятую и в данном случае имеет значение их порядок. Нам требуется, чтобы верхняя и нижняя часть блока не перекрывались, поэтому ставим их первыми (пример 3). Цвет фона указывается последним.

Пример 3. Несколько фоновых картинок

Фон

Уицилопочтли - «колдун колибри», бог войны и солнца.

Тескатлипока - «дымящееся зеркало», главный бог ацтеков.

Обоим богам приносили человеческие жертвы.

Первый фон выводит верхнюю границу блока, второй фон - нижнюю, а третий вертикальные границы. Последним идёт цвет, который виден в прозрачной центральной части блока (рис. 4).

Новый способ: множественные фоны на CSS3

Я использую четыре полупрозрачных PNG-изображения, чтобы создать космический фон, используемый на сайте с Луной. Все они накладываются на элементbody , одно поверх другого, чтобы создавать ощущение пространства, когда пользователь меняет размеры окна браузера.

На рис. 5.03 показаны все используемые изображения:

1) облака пыли (clouds.png);

2) сине-розовый градиент (space-bg.png);

3) звездный слой (stars-1.png);

4) еще один слой случайно разбросанных звезд (stars-2.png).

Рис. 5.03. Четыре полупрозрачных фоновых PNG-изображения, которые расположены на фоне сайта с Луной

Синтаксис множественного фона

Поставить эти четыре изображения в качестве фона элемента body очень просто с использованием нового синтаксиса CSS3:

body { background:

Д. Сидерхолм. «CSS3 для веб-дизайнеров»

Четыре изображения наслаиваются – облака в самый низ, звезды на самый верх – в виде списка, разделенного запятыми (обратите внимание, что перечисление начинается с того изображения, которое «ближе» к пользователю). Каждое изображение дублируется по горизонтали, и им выставлены различные положения по горизонтали (используя положительные и отрицательные значения), чтобы каждый слой двигался со своей скоростью, когда меняется размер окна браузера. Наконец, их положение на странице зафиксировано с помощью значения fixed .

Почти черный цвет #1a1a1a добавлен отдельным правилом background-color в самом конце.

Это все (рис. 5.04 ). Замечательно, что удалось обойтись без лишней разметки. Все эти изображения выставляются на элементbody , так что они будут находиться позади содержимого страницы, но нам не потребовалось обертывать их в лишние вспомогательные слои.

Рис. 5.04. Четыре PNG-изображения наслоены одно поверх другого, равно как и темно– серый цвет фона

Поддержка в браузерах

Как упоминалось в первой главе, множественные фоны поддерживаются в Safari 1.3+, Chrome 2+, Firefox 3.6+, Opera 10.5+ и IE9 Beta. Так что они находятся наравне с многими другими CSS-свойствами, которыми мы пользовались в этой книге.

Мы выбрали использовать эту замечательную возможность CSS3 в некритичной части дизайна из-за несовершенной поддержки: чтобы улучшить фон страницы, чтобы создать новое взаимодействие при изменении размеров окна – эффект параллакса для тех, кто может испытать его.

Запасной вариант для всех браузеров

Браузеры, которые пока что не поддерживают множественные фоны, проигнорируют свойство background целиком. Вот почему мы определили свойствоbackgroundcolor отдельно.

Д. Сидерхолм. «CSS3 для веб-дизайнеров»

На рис. 5.05 показано, как сайт выглядит в IE7: множественные фоны игнорируются, и отображается только темно-серый фон, заданный свойством background-color .

Рис. 5.05. IE7 игнорирует свойство, в котором определены множественные фоны, и показывает только темно-серый фон, заданный свойством background-color

Конечно, все работает должным образом, но то, что объемный фон потерялся, нехорошо. Решение заключается в том, чтобы сначала задать единый запасной фон – для браузеров (таких, как IE7 и 8), которые не поддерживают множественные фоны. Затем можно снова объявить это свойство – на этот раз с множественными фонами (IE проигнорирует его).

background: url(../img/space-bg.png) repeat-x fixed -80% 0;background:

url(../img/stars-1.png) repeat-x fixed -130% 0, url(../img/stars-2.png) repeat-x fixed 40% 0, url(../img/space-bg.png) repeat-x fixed -80% 0, url(../img/clouds.png) repeat-x fixed 100% 0; background-color: #1a1a1a;

Для запасного варианта с одной картинкой можно выбрать одно из изображений, которые используются во множественном объявлении, а можно пойти дальше и создать одну картинку, в которой объединялись бы все четыре изображения.

Для сайта с Луной я решил использовать space-bg.png – цветной градиент (рис. 5.06 ), таким образом показывая вариант фона без звезд и облаков в тех браузерах, которые пока что не поддерживают множественные фоны. Очень уместно.

Д. Сидерхолм. «CSS3 для веб-дизайнеров»

Рис. 5.06. Благодаря запасному варианту картинки на фоне в IE7 частично восстановлено ощущение пространства

  • Tutorial

Мы уже ранее затрагивали возможности модуля CSS3 Backgrounds and Borders , рассматривая работу с тенями (box-shadow). Сегодня мы немного поговорим о еще одной интересной возможности — использовании нескольких изображений в фоне.

Композиция фонов

Существует множество причин, по которым, вам вообще может потребоваться композиция нескольких изображений в фоне, среди них наиболее важные — это:

  • экономия трафика на размере изображений, если отдельные изображения в сумме весят меньше, чем изображение со сведенными слоями, и
  • необходимость независимого поведения отдельных слоев, например, при реализации эффектов паралакса.
Могут быть и другие разумные причины:)

Классический подход

Итак, нам нужно разместить несколько фоновых изображений одно над другим. Как обычно решается эта задача? Очень просто: на каждое фоновое изображение создается блок, которому прописывается соответствующее фоновое изображение. Блоки либо вкладываются друг в друга, либо размещаются подряд с соответствующими правилами позиционирования. Вот простой пример:

Блок с классом «fishing» внутри «mermaid» исключительно для демонстрационных целей.

Теперь немного стилей:
.sample1 .sea, .sample1 .mermaid, .sample1 .fishing { height:300px; width:480px; position: relative; } .sample1 .sea { background: url(media/sea.png) repeat-x top left; } .sample1 .mermaid { background: url(media/mermaid.svg) repeat-x bottom left; } .sample1 .fish { background: url(media/fish.svg) no-repeat; height:70px; width:100px; left: 30px; top: 90px; position: absolute; } .sample1 .fishing { background: url(media/fishing.svg) no-repeat top right 10px; }

Результат:

В данном примере три вложенных фона и один блок с рыбками, расположенный рядом с «фоновыми» блоками. В теории, рыбок можно перемещать, например, с помощью JavaScript или CSS3 Transitions/Animations.

Кстати, в этом примере для ".fishing" используется новый синтаксис для позиционирования фона , также определенный в CSS3:
background: url(media/fishing.svg) no-repeat top right 10px;
На текущий момент он поддерживается в IE9+ и Opera 11+, но не поддерживается в Firefox 10 и Chrome 16. Так что пользователи последних двух браузов поймать рыбку пока не смогут.

Множественные фоны

На помощь приходит новая опция, добавленная в CSS3, — возможность определять сразу несколько фоновых изображений для одного элемента. Выглядит это следующим образом:

И соответствующие стили:
.sample2 .sea { height:300px; width:480px; position: relative; background-image: url("media/fishing.svg"), url("media/mermaid.svg"), url("media/sea.png"); background-position: top right 10px, bottom left, top left; background-repeat: no-repeat, repeat-x, repeat-x ; } .sample2 .fish { background: url("media/fish.svg") no-repeat; height:70px; width:100px; left: 30px; top: 90px; position: absolute; }
Для определения множественных изображений необходимо использовать правило background-image, перечисляя отдельные изображения через запятую. Дополнительными правилами, также списком, можно задать позиционирование, повторы и другие параметры для каждого из изображений. Обратите внимание на порядок перечисления изображений: слои перечисляются слева направо от самого верхнего к самом нижнему.

Результат полностью совпадает:

Одним правилом

Если рыбок не нужно выделять в отдельный блок для последующих манипуляций, всю картинку можно переписать одним простым правилом:

Стили:
.sample3 .sea { height:300px; width:480px; position: relative; background-image: url("media/fishing.svg"), url("media/mermaid.svg"), url("media/fish.svg"), url("media/sea.png"); background-position: top right 10px, bottom left, 30px 90px, top left; background-repeat: no-repeat, repeat-x ; }

Картинку с результатом приводить не буду — поверьте, она совпадает с двумя картинками выше. А вот на стили обратите внимание еще раз, особенно на «background-repeat» — согласно спецификации, если часть списка в конце пропущена, то браузер должен повторить указанный список нужное число раз, чтобы соответствовать количеству изображений в списке.

В данном случае, это эквивалентно такому описанию:
background-repeat: no-repeat, repeat-x, no-repeat, repeat-x;

Еще короче

Если вы помните CSS 2.1, в нем определена возможность описывать фоновые изображения в краткой форме. Как на счет множественных изображений? Это также возможно:

Sample4 .sea { height:300px; width:480px; position: relative; background: url("media/fishing.svg") top right 10px no-repeat, url("media/mermaid.svg") bottom left repeat-x, url("media/fish.svg") 30px 90px no-repeat, url("media/sea.png") repeat-x; }

Но обратите внимание, что теперь пропускать просто так значения нельзя (если только они не совпадают со значением по умолчанию). Кстати, если вы хотите задать цвет фонового изображения, это надо делать в самом последнем слое.

Динамичные изображения

Если композиция статична или динамична не более, чем в зависимости от размеров контейнера, тогда множественные фоны очевидно упрощают конструкцию страницы. А что делать, если с отдельными элементами композиции нужно работать независимо из javascript (перемещать, прокручивать и т.п.)?
Кстати, вот пример из жизни — тема с одуванчиком в Яндексе:


Если вы залезете в код, вы увидите там примерно следующее:
...

Блоки с классами «b-fluff-bg», «b-fluff__cloud» и «b-fluff__item» содержат фоновые изображения, накладывающиеся друг на друга. Причем фон с облаками постоянно прокручивается, а одуванчики летают по экрану.

Можно ли это переписать с использованием множественных фонов? В принципе, да, но при условии 1) поддержки этой возможности в целевых браузерах и… 2) читайте дальше;)

Как добавить динамики множественным фонам? В такой ситуации оказывается удобным, что во внутреннем представлении браузер раскидывает отдельные параметры фоновых изображения по соответствующим правилам. Например, для позиционирования есть «background-position», и для сдвигов достаточно изменять только его. Однако имеется и плата за использование множественных изображений — в этом правиле (и любом аналогичном) необходимо перечислять позицию для всех фонов, заданных для вашего блока, и нельзя сделать это выборочно.

Чтобы добавить нашему фону с рыбками анимации, можно использовать такой код:
$(document).ready(function() { var sea = $(".sample5 .sea"); var fishesX = 30; var fishesY = 90; var fishX = 0; var fishY = 0; var mermaidX = 0; var t = 0; function animationLoop() { fishesY = 90 + Math.floor(30 * Math.sin(t++ / 180.0)); if(--fishesX < 0) fishesX = 480; mermaidX += 0.5; if(mermaidX > 480) mermaidX = 0; fishY = -10 + (10 * Math.cos(t * 0.091)); fishX = 10 + (5 * Math.sin(t * 0.07)); sea.style.backgroundPosition = "top " + fishY + "px right " + fishX + "px, " + mermaidX + "px bottom," + fishesX + "px " + fishesY + "px, top left"; window.requestAnimFrame(animationLoop); } animationLoop(); });
где
window.requestAnimFrame = (function() { return window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.webkitRequestAnimationFrame || (function(callback) { window.setTimeout(callback, 1000 / 60); }); })();

И, кстати, анимации также можно делать через CSS3 Transitions/Animations, но это тема для отдельного обсуждения.

Паралакс и интерактив

Наконец, схожими маневрами можно легко добавить эффекты паралакса или интерактивного взамодействия с фоном:

Множественные фоновые изображения удобны в подобных сценариях, так как пока мы говорим только про фон (а не контент), их использование позволяет избежать замусоривания html-кода и DOM. Но за все приходится платить: я не могу обращаться к отдельным элементам композиции по имени, id, классу или какому либо другому параметру. О порядке элементов в композиции я должен явно помнить в коде и на каждое изменение любого параметра любого элемента фактически я должен склеивать строку, описывающую значения этого параметра для всех элементов, и обновлять ее для всей композиции.

Sea.style.backgroundPosition = "top " + fishY + "px right " + fishX + "px, " + mermaidX + "px bottom," + fishesX + "px " + fishesY + "px, top left";

Уверен, что это можно обернуть в удобный код на javascript, который возьмет на себя виртуализацию взаимоотношений с отдельными слоями, оставляя при этом html-код страницы максимально чистым.

Что там с совместимостью?

Все современные версии популярных браузеров, включая IE9+, поддерживают множественные изображения (можно сверяться, например, с сaniuse).

Вы также можете использовать Modernizr , чтобы предоставлять браузерам, не поддерживающим множественные фоны, альтернативные решения. Как написал Chris Coyier в заметке о порядке слоев при использовании множественных фонов , делайте примерно так:

Multiplebgs body { /* Awesome multiple BG declarations that transcend reality and imsourcess chicks */ } .no-multiplebgs body { /* laaaaaame fallback */ }
Если вас смущает использование JS для предоставления обратной совместимости, вы можете просто дважды объявить background, правда, это тоже имеет свои минусы в виде возможной двойной загрузки ресурсов (это зависит от реализации обработки css в конкретном браузере):

/* multiple bg fallback */ background: #000 url(...) ...; /* Awesome multiple BG declarations that transcend reality and imsourcess chicks */ background url(...), url(...), url(...), #000 url(...);

Если вы уже начали думать о Windows 8 имейте в виду, что вы можете использовать множественные фоны при разработке metro style приложений, так как внутри используется тот же движок, что и в IE10.

P.s. В тему: не могу не вспомнить феноменальную статью про принцип цикады .

Теги: Добавить метки