Множественный фон в css3. Как сделать несколько фоновых изображений CSS. Прогрессивные усовершенствованиям и устаревшие браузеры
Рассказывая о свойстве 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; /* середина рамки */
Такой вариант выглядит менее громоздко и легче воспринимается.
). Сегодня мы немного поговорим о еще одной интересной возможности — использовании нескольких изображений в фоне.
Композиция фонов
Существует множество причин, по которым, вам вообще может потребоваться композиция нескольких изображений в фоне, среди них наиболее важные — это:
- экономия трафика на размере изображений, если отдельные изображения в сумме весят меньше, чем изображение со сведенными слоями, и
- необходимость независимого поведения отдельных слоев, например, при реализации эффектов паралакса.
Классический подход
Итак, нам нужно разместить несколько фоновых изображений одно над другим. Как обычно решается эта задача? Очень просто: на каждое фоновое изображение создается блок, которому прописывается соответствующее фоновое изображение. Блоки либо вкладываются друг в друга, либо размещаются подряд с соответствующими правилами позиционирования. Вот простой пример:
Блок с классом «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. В тему: не могу не вспомнить феноменальную статью про .
Сегодня, практически в каждом дизайне сайта присутствует красивая background картинка.
Каждый верстальщик знает, что самый простой способ создания дизайна - лучшее, что может быть. Одним из простых и удобных техник является , с помощью нескольких строк css кода.
Казалось бы, мелочь, но все же, порой нужно сотворить что-то сложное простым способом. Например, реализовать несколько background с индивидуальными параметрами, без использования вспомогательных div блоков. То есть, сохраняя .
В этой статье мы рассмотрим синтаксис кода, который поддерживает несколько background (multiple backgrounds) в одном элементе. Вот, как это смотрится в реалии:
CSS код для multiple backgrounds
Несколько background картинок реализуются с помощью нескольких значений css параметра background, которые разделены комой:
#multipleBGs { background: url(photo1.png), url(photo2.png), url(photo3.png) ; background-repeat: no-repeat, no-repeat, repeat-y; background-position: 0 0, 30px 70px, right top; width: 400px; height: 400px; border: 1px solid #ccc; }
Я пытался сделать так же, с помощью краткого кода. К сожалению, не работает.
Плюс к этому, можно использовать другие свойства background (background-attachment, background-clip, background-image, background-origin, background-position, background-repeat, background-size). Так же, как и в CSS градиентах.
Вот и все! Надеюсь вам понравилась эта техника создания нескольких background, без использования каких либо вспомогательных элементов. Чистый семантический код.
Если у вас остались вопросы, замечания или предложения по поводу данной техники создания multiple backgrounds - пишите в комментарии. Также, хотелось бы провести тест на
Сегодня мы займемся работай над фоновыми рисунками, которые устанавливаются с помощью свойства 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; .
Вместо другого элемента, хотя формально, он идет как отдельная область, используем псевдоэлемент. Ему задаем абсолютную позицию и позиционируем в необходимое нам место.
В CSS 2 добавить одновременно два фона к одному элементу нереально, поэтому приходится вкладывать один элемент внутрь другого и для каждого задавать свой собственный фоновый рисунок. Для сложных макетов таких вложений иной раз можно насчитать около десятка. Понятно, что ни к чему хорошему такое нагромождение не приводит, но что делать? Оказывается, есть что! В CSS 3 можно одновременно добавлять несколько фоновых рисунков для любого элемента. Так что берем рисунок блока (рис. 1), режем его на части и начинаем тестировать в браузерах.
Рис. 1. Блок для сайта
Для простоты, ширину блока возьму фиксированного размера, а высота будет тянуться в зависимости от контента. По рисунку хорошо видно верхнюю и нижнюю часть, вырезаю в редакторе и складываю пластами в отдельном файле. Среднюю часть надо выбрать так, чтобы она повторялась без швов по вертикали. Рисунок имеет хорошо выраженный повторяющийся орнамент, так что трудностей с выделением быть не должно. Копирую и вставляю к предыдущим фрагментам. В итоге получится такая картинка (рис. 2).
Рис. 2. Подготовленные изображения
В принципе, можно сохранить каждый фрагмент в виде отдельного файла, но у CSS-спрайтов (так называется технология склейки нескольких изображений в одно) есть ряд преимуществ. Во-первых, сокращается количество запросов к серверу из-за сокращения количества файлов и, во-вторых, рисунки в сумме загружаются и отображаются быстрее.
Сам фон выводится свойством background , оно же задает и координаты нужного фрагмента. Параметры каждого фона перечисляются через запятую, и в данном случае имеет значение их порядок. Мне требуется, чтобы верхняя и нижняя часть блока не перекрывались, поэтому ставлю их первыми (пример 1).
Пример 1. Несколько фоновых картинок
HTML5 CSS2.1 CSS3 IE 8 IE 9 Cr Op Sa Fx
Уицилопочтли - «колдун колибри», бог войны и солнца.
Тескатлипока - «дымящееся зеркало», главный бог ацтеков.
Обоим богам приносили человеческие жертвы.
Первый фон выводит верхнюю границу блока, второй фон - нижнюю, а третий вертикальные границы.
Проверяем в браузерах. Internet Explorer 8 вообще не вывел никаких рисунков, остальные браузеры (IE 9, Opera 10.60, Firefox 3.6, Chrome 5, Safari 5) отобразили рамку корректно (рис. 3).
Рис. 3. Вид рамки в браузере Safari
С использованием множественных фонов ситуация для разработчиков существенно облегчается, особенно при верстке блоков. Остается только одна мелочь. Надо чтобы браузер IE 6–8 прекратил свое существование.