Наше путешествие в мир теней CSS3 продолжается. Сегодня мы сосредоточимся на еще одной интересной функции — как использовать несколько фонов с помощью CSS3.
Фоновая композиция
Есть много причин, по которым вам может понадобиться создать композицию из нескольких изображений для создания фона. Я думаю, что наиболее важными являются следующие:
- уменьшить использование полосы пропускания, когда сумма размеров файлов отдельных изображений меньше, чем размер изображения с объединенными слоями (особенно если ваше изображение содержит повторяющиеся узоры), и
- обеспечить способ независимого манипулирования различными слоями (например, если вы собираетесь реализовать эффект параллакса).
Я считаю, что у вас могут быть другие разумные аргументы 🙂
Классический подход
Поэтому нам нужно создать многослойный фон, поместив некоторые изображения поверх других. Как обычно решается эта проблема? Это действительно просто: просто создайте контейнер (например, элемент div) для каждого имеющегося изображения и добавьте для него фон, используя правило CSS. Затем вы вставляете один контейнер в другой или помещаете их в ряд и применяете соответствующие правила позиционирования CSS. У меня есть простой пример:
<div class = "sample1"> <div class = "sea"> <div class = "mermaid"> <div class = "fishing"> </ div> </ div> <div class = "fish"> </ div> </ DIV> </ DIV>
Класс рыбалки внутри класса русалки только для демонстрационных целей.
И здесь у нас есть несколько стилей CSS:
.sample1 .sea, .sample1 .mermaid, .sample1 .fishing { высота: 300 пикселей; ширина: 480 пикселей; положение: относительное; } .sample1 .sea { background: url (media / sea.png) repeat-x вверху слева; } .sample1 .mermaid { фон: url (media / mermaid.svg) repeat-x внизу слева; } .sample1 .fish { фон: url (media / fish.svg) без повтора; высота: 70 пикселей; ширина: 100 пикселей; слева: 30 пикселей; верх: 90 пикселей; положение: абсолютное; } .sample1 .fishing { фон: url (media / fishing.svg) без повтора вверху справа 10px; }
Результат:
В этом примере у меня есть три вложенных div
с фоновыми изображениями и еще один соседний div
, fish. Вы можете представить, что рыбу можно анимировать с помощью JavaScript или CSS3-переходов или анимации.
Обратите внимание, что для класса рыбалки я использую новый синтаксис фонового позиционирования , определенный в CSS3. Но пока он поддерживается только IE9 + и Opera 11+; он еще не работает в Firefox 10 или Chrome 16. Таким образом, пользователи последних двух не могут поймать рыбу. 🙁
Давай продолжим. Можно ли упростить эту композицию?
Несколько фонов
Это когда несколько фонов приходят на сцену. Эта функция позволяет добавлять более одного фона одновременно к одному элементу. Вот как это выглядит:
<div class = "sample2"> <div class = "sea"> <div class = "fish"> </ div> </ DIV> </ DIV>
И стили:
.sample2 .sea { высота: 300 пикселей; ширина: 480 пикселей; положение: относительное; background-image: url ("media / fishing.svg"), url ("media / mermaid.svg"), url ("media / sea.png"); background-position: вверху справа 10px, внизу слева, вверху слева; повторение фона: без повторения, повтор-х, повтор-х; } .sample2 .fish { background: url ("media / fish.svg") без повторов; высота: 70 пикселей; ширина: 100 пикселей; слева: 30 пикселей; верх: 90 пикселей; положение: абсолютное; }
Чтобы определить несколько фонов, вы должны использовать правило background-image
, перечисляя ваши изображения (через запятую). Вы также можете использовать другие правила для установки положения, режима повторения и других атрибутов для каждого изображения — просто запишите их также, используя разделенный запятыми список для соответствующего правила. Обратите внимание на порядок изображений: они перечислены слева направо, начиная с самого верхнего и заканчивая самым нижним.
Результат на 100% идентичен:
В одном правиле
Если вам не нужна ваша рыба, чтобы плавать в независимом блоке, весь фон может быть записан в одном простом правиле:
<div class = "sample3"> <div class = "sea"> </ div> </ DIV>
Стили:
.sample3 .sea { высота: 300 пикселей; ширина: 480 пикселей; положение: относительное; background-image: url ("media / fishing.svg"), url ("media / mermaid.svg"), url ("media / fish.svg"), url ("media / sea.png"); background-position: верхний правый 10px, нижний левый, 30px 90px, верхний левый; повторение фона: без повторения, повторение х; }
Я не показываю ту же картинку еще раз, но поверьте мне — она равна двум изображениям выше. Посмотрите на стили еще раз, особенно на правило background-repeat
. Согласно спецификации, если часть списка не указана, UA (браузер) должен повторить текущий список, чтобы заполнить остальные.
В нашем случае оно равно следующему определению:
повторение фона: без повтора, повтор-х, без повтора, повтор-х;
Более короткая версия
Если вы помните, в CSS2.1 можно описать фоновое изображение в одном коротком background
правиле. Как насчет нескольких фонов? На самом деле, вы также можете использовать правило background
для нескольких фонов:
.sample4 .sea { высота: 300 пикселей; ширина: 480 пикселей; положение: относительное; background: url ("media / fishing.svg") вверху справа 10px без повтора, url ("media / mermaid.svg") слева внизу repeat-x, url ("media / fish.svg") 30px 90px без повтора, url ("media / sea.png") repeat-x; }
Но обратите внимание, что вы не можете легко опустить аргументы, если значения не равны значениям по умолчанию. Также, если вы хотите определить цвет фона, вы должны сделать это в последнем слое.
Динамические изображения
Вот что мы уже знаем: если ваш фон в основном статичен — это может зависеть от размера контейнера (т. Е. Если вы используете% length, чтобы некоторые слои сместились при изменении размера окна), — тогда магия нескольких фонов полезна, так как действительно упрощает структуру страницы. Но что, если вам нужно анимировать некоторые слои с помощью JavaScript (перемещение, вращение и т. Д.)?
У меня есть пример из реальной жизни — тема одуванчиков на сайте Яндекса (российский поисковый провайдер, YNDX ):
Если вы посмотрите на исходный код (нажмите F12 в IE, чтобы открыть devtools ), вы найдете код, подобный следующему:
<div class = b-skin-bg sizcache = "272" sizset = "0"> <Div class = b-fluff-bg sizcache = "272" sizset = "0"> <Div class = b-fluff__sky sizcache = "272" sizset = "0"> <Div style = "background-position: 3244px 0px" class = b-fluff__cloud> </ div> <Div style = "width: 1200px" class = b-max-width sizcache = "214" sizset = "0"> <div class = b-fluff__placeholder sizcache = "302" sizset = "0"> <div style = "bottom: 105px; отображение: нет; слева: 940px" class = "b-fluff__item b-fluff_item_3" jQuery1328289994769 = "30"> </ div> <Div style = "bottom: 50px; отображение: нет; слева: 879px" class = "b-fluff__item b-fluff_item_3" jQuery1328289994769 = "31"> </ div> <Div style = "bottom: 105px; отображение: нет; слева: 940px" class = "b-fluff__item b-fluff_item_3" jQuery1328289994769 = "32"> </ div> ... </ DIV> </ DIV> </ DIV> </ DIV> </ DIV>
К div
с классами b-fluff-bg, b-fluff__cloud & b-fluff__item применяются правила CSS, добавляющие наложенные фоновые изображения. Фон с облачной прокруткой слева направо, а фон с семенами одуванчика летит по экрану.
Можно ли переписать такую композицию, используя CSS3 несколько фонов? На самом деле, да, но только если 1) он поддерживается во всех целевых браузерах и 2) продолжить чтение;)
Как мы можем сделать наши многочисленные фоны более динамичными? Внутри браузер разбирает каждое background
правило на отдельные правила background-*
для каждого из атрибутов. Это очень полезно, если вам нужно изменить только один из атрибутов. Например, вы можете использовать правило background-position
для смещения ваших изображений. Но есть некоторые штрафы за работу с несколькими фонами: если вы собираетесь переместить только один слой, вам все равно нужно переписать это правило для всех слоев.
Для анимации нашего морского фона мы можем использовать следующий код JavaScript:
$ (документ) .ready (function () { var sea = $ (". sample5 .sea") [0]; 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 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 () { возвращение window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.webkitRequestAnimationFrame || (function (callback) {window.setTimeout (callback, 1000/60);}); }) ();
Результат ( видео ):
Вы также можете использовать CSS3 Transitions или Animations, но это хорошая тема для отдельного обсуждения.
Параллакс и Интерактивность
Наконец, используя аналогичные методы, вы можете легко добавить некоторые эффекты параллакса или другие интерактивные эффекты на свой фон:
Многократные фоны полезны в таких сценариях, и хотя мы говорим только о фонах (не о контенте), их использование, безусловно, является хорошим способом избежать загрязнения HTML-кода сложными ненужными элементами. Но, как я уже сказал, есть некоторые штрафы, если вам нужно создать сложный и динамический фон: вы не можете получить доступ к отдельному слою по ID, классу или любому другому параметру. Вы должны помнить порядок слоев в вашем коде, и чтобы изменить атрибут только для одного слоя, вам нужно будет создать строку, описывающую этот атрибут для всех ваших слоев. Чтобы обновить один слой, вам нужно обновить всю композицию:
sea.style.backgroundPosition = "top" + fishY + "px right" + fishX + "px," + mermaidX + "px bottom", + fishesX + "px" + fishesY + "px, top left";
Я уверен, что можно создать хорошую и полезную библиотеку JavaScript, которая виртуализирует все эти слои и обеспечит простой способ изменения атрибутов для отдельного слоя, сохраняя чистоту вашего HTML-кода и DOM.
Совместимость
Все современные браузеры, включая IE10 и 9, поддерживают несколько фонов. Вы также можете использовать некоторые инструменты, такие как Modernizr, чтобы обеспечить некоторый уровень совместимости для старых браузеров, например, предоставляя альтернативный фон. Как написал Крис Койер в своей статье о порядке наложения нескольких фонов , вы можете использовать следующий подход:
.multiplebgs body { / * Потрясающие множественные декларации BG, которые выходят за рамки реальности и производят впечатление на цыпочек * / } .no-multipbgs body { / * laaaaaame резервный * / }
Если вас не устраивает использование JavaScript для обеспечения обратной совместимости для новых правил CSS3, вы можете просто определить свойство background
дважды (но этот подход может привести к ненужным загрузкам для современных браузеров, в зависимости от того, как они обрабатывают такие правила):
/ * многократный откат BG * / фон: # 000 url (...) ...; / * Потрясающие множественные декларации BG, которые выходят за рамки реальности и производят впечатление на цыпочек * / фон: url (...), url (...), url (...), # 000 url (...);
И, наконец, если вы хотите это знать: да, вы можете использовать несколько фонов в своих приложениях в стиле Metro для Windows 8, созданных с использованием HTML и JavaScript.
PS Посмотрите эту феноменальную статью Алекса Уокера о принципе цикады.
Заметка
Свойства CSS, обсуждаемые в этой статье, определяются в модуле « Фоны и границы CSS3 », который в настоящее время находится в состоянии «Рабочий чертёж». Между тем, он кажется достаточно стабильным, но все еще может измениться в деталях.