Анимация фона

Влад Мержевич

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

Почему именно фон? У него куча плюсов. Главное, фон лежит себе на заднем плане и не мешает выводить поверх него остальные элементы. К тому же у background есть множество параметров, включая функции для градиентов, всё это позволяет разнообразить создание фона.

Для начала сделаем пока просто вывод фона для всей страницы без анимации. Стиль получится такой:

body {
  background: url(images/city.png) repeat-x 0 100% fixed,
  linear-gradient(to top, #5080b1, #004e8c) fixed;
}

Фоновая картинка city.png имеет ширину 1000 пикселей и повторяется без стыков по горизонтали. На рис. 1 она показана в уменьшенном виде. Для красоты добавим на заднем плане градиент, он будет создавать эффект тёмного неба.

Картинка для фона

Рис. 1. Картинка для фона

Высота <body> не совпадает с высотой окна браузера, а равна высоте контента. Поэтому просто так фон поместить в самый низ окна не получится. Для этого применяют всякие хитрости, вроде установки высоты 100% для селекторов html и body. Мы пойдём другим путём и добавим параметр fixed к каждому фону. Он фиксирует фон на одном месте и не прокручивает его, как обычно, вместе с содержимым. Заодно привязывает фон к окну браузера. Вот как выглядит страница с фоном (рис. 2).

Фон

Рис. 2. Фон

Теперь добавляем бесконечную анимацию. Пусть город плавно движется слева направо. Поскольку фон у нас повторяется без стыков, получится зацикленное движение без рывков. В свойстве animation пишем имя нашей анимации city, добавляем линейное движение через linear и ставим infinite для бесконечного повтора. Время анимации определяется методом Подборского, в общем, ставим что больше нравится. У меня 30 секунд.

animation: city 30s linear infinite;

Теперь переходим к ключевым кадрам. Нам надо только менять позицию фона. Мы знаем, что ширина фона равна 1000px, на это значение и сдвигаем фон.

@keyframes city {
  from { background-position: -1000px 100%, 0 0;}
  to { background-position: 0 100%; }
}

Можно менять от -1000 до 0 или 0 до 1000, это не имеет значения. Градиент под картинкой не трогаем. Хотя теоретически его движение по горизонтали не должно быть заметно, Хром под Windows добавляет небольшой шум к фону. Без анимации градиент выглядит лучше, к тому же она нам совсем ни к чему, двигаться должна только картинка города.

Добавляем префикс -webkit где это требуется и анимированный фон готов. Для наглядности поверх выводится полупрозрачный блок (пример 1).

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

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Фон</title>
  <style>
   body {
    background: url(images/city.png) repeat-x 0 100% fixed,
                linear-gradient(to top, #5080b1, #004e8c) fixed;
    animation: city 30s linear infinite;
    -webkit-animation: city 30s linear infinite;
   }
   @keyframes city {
    from { background-position: -1000px 100%, 0 0;}
    to { background-position: 0 100%, 0 0; }
   }
   @-webkit-keyframes city {
    from { background-position: -1000px 100%, 0 0;}
    to { background-position: 0 100%, 0 0; }
   }
   main {
    width: 80%;
    min-height: 800px;
    display: block;
    margin: auto;
    background: rgba(255,255,255,0.6);
    padding: 20px;
   }
  </style>
 </head>
 <body>
  <main>Бла-бла</main>
 </body>
</html>

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

body {
  background: 
   url(images/city.png) repeat-x 0 100% fixed,
   url(images/cloud.png) no-repeat fixed,
   url(images/cloud.png) no-repeat fixed,
   linear-gradient(to top, #5080b1, #004e8c) fixed;
}
В итоге у нас получилось аж четыре фона и для background-position их надо все указывать. Чем фоновая картинка хороша, её можно легко позиционировать за пределами окна, задавая отрицательное значение координат. При этом никаких полос прокрутки не появится, это же фон, а не обычный элемент. Так что размещаем облака справа, а двигаться они будут далеко влево. Отдельно задать скорость движения каждого рисунка нельзя, потому что background у нас один, так что регулируем скорость, увеличивая или уменьшая дистанцию движения через background-position (пример 2).

Пример 2. Анимация нескольких фоновых картинок

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Фон</title>
  <style>
   body {
    background: url(images/city.png) repeat-x 0 100% fixed,
                url(images/cloud.png) no-repeat fixed,
                url(images/cloud.png) no-repeat fixed,
                linear-gradient(to top, #5080b1, #004e8c) fixed;
    animation: city 30s linear infinite;
    -webkit-animation: city 30s linear infinite;
   }
   @keyframes city {
    from { background-position: -1000px 100%, 120% 30%, 120% 15%, 0 0;}
    to { background-position: 0 100%, -200% 10%, -50% 15%, 0 0; }
   }
   @-webkit-keyframes city {
    from { background-position: -1000px 100%, 120% 30%, 120% 15%, 0 0;}
    to { background-position: 0 100%, -200% 10%, -50% 15%, 0 0; }
   }
  </style>
 </head>
 <body>
 </body>
</html>

CSS по теме

Не выкладывайте свой код напрямую в комментариях, он отображается некорректно. Воспользуйтесь сервисом cssdeck.com или jsfiddle.net, сохраните код и в комментариях дайте на него ссылку. Так и результат сразу увидят.