CSS-градиенты

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

Использование градиентов, объявляемых в CSS, вместо файлов изображений, позитивно сказывается на управлении и производительности.

Как правило, градиенты - это переходы одного цвета в другой, но в CSS вы можете контролировать каждый аспект того, как это происходит, от направлений перехода цветов (так, как вы захотите) до того, где этот переход цветов осуществляется.

Давайте рассмотрим все по порядку.

Градиенты - это изображения фона

Объявляя применение в CSS сплошного цвета для параметра background-color, градиенты используют background-image. Это дает нам несколько преимуществ, которые можно использовать позже.

Значение параметра background указывает на то, что вы хотите сделать, когда объявляете то или другое действие:

.gradient {

  /* может рассматриваться, как запасной вариант */
  background-color: red;

  /* может использоваться, как изображение "по верху", если браузер поддерживаете его */
  background-image: linear-gradient(red, orange);

  /* это действие сбрасывает другие свойства, такие как background-position */
  background: red;
  background: linear-gradient(red, orange);

}

Линейный градиент

Возможно, одним из самых распространенных и полезных типов градиента является linear-gradient(). «Ось» перехода градиента может располагаться слева-направо, сверху-вниз или под любым другим углом на ваше усмотрение.

Если вы не объявляете отдельно угол, по умолчанию преобразования будут происходить сверху-вниз:

.gradient {
  background-image:
    linear-gradient(
      red, #f06d06
    );
}

Посмотреть пример на Codepen

Вместо разделенных запятыми цветов вы можете использовать те типы цветов, которые вы обычно используете: шестнадцатеричные числа, название цвета, rgba, hsla, и т.д.

Чтобы сделать переход слева-направо, вы задаете дополнительный параметр в начале функции linear-gradient(), начиная код параметра со слова «to», а затем указывая направление.

Например, «to right»:

.gradient {
  background-image:
    linear-gradient(
      to right, 
      red, #f06d06
    );
}

Посмотреть пример на Codepen

Данный синтаксис «to» применяется для углов переходов. Например, если вы хотите, чтобы ось градиента начиналась в левом нижнем углу и переходила к верхнему правому углу, можно указать «to top right»:

.gradient {
  background-image:
    linear-gradient(
      to top right, 
      red, #f06d06
    );
}

Посмотреть пример на Codepen

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

Если вы хотите задать градиент точно в 45 градусов, то вы можете объявить это:

.gradient {
  background-image:
    linear-gradient(
      45deg, 
      red, #f06d06
    );
}

Также вы можете не ограничиваться всего двумя цветами. На самом деле вы можете использовать столько цветов, сколько захотите.

Например, четыре:

.gradient {
  background-image:
    linear-gradient(
      to right, 
      red, 
      #f06d06, 
      rgb(255, 255, 0), 
      green
    );
}

Посмотреть пример на Codepen

Вы можете также объявить, откуда вы хотите, чтобы начинался какой-либо определенный цвет. Это называется «color-stop».

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

В таком случае вы можете разместить color-stop желтого цвета несколько раньше:

.gradient {
  height: 100px;
  background-color: red;
  background-image:
    linear-gradient(
      to right,
      red,
      yellow 10%
    );
}

Посмотреть пример на Codepen

Как правило, градиенты используются для плавного перехода цветов, однако если у вас есть два одинаковых color stops, вы можете сделать мгновенный переход от одного сплошного цвета к другому.

Это может быть полезно для объявления фона, который имитирует столбцы, на всю высоту страницы:

.columns-bg {
  background-image:
    linear-gradient(
      to right, 
      #fffdc2,
      #fffdc2 15%,
      #d7f0a2 15%,
      #d7f0a2 85%,
      #fffdc2 85%
    );
}

Посмотреть пример на Codepen

Поддержка браузерами / Префиксы

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

Например, поддержка браузерами. Здесь синтаксис и префиксы уже сложнее. Существует три разных набора правил синтаксиса, которые поддерживают браузеры.

Они не декларируют этого официально, но вот как вы можете себе их представить:

  • Старый: оригинальный, только с WebKit, в нем используется синтаксис наподобие from() и color-stop();
  • Tweener : старая система углов, например, «left»;
  • Новый: Новая система углов, например, «to right».

То же касается и префиксов.

Давайте попробуем их перечислить:

Chrome1-9: Старый, с префиксами.
10-25: Tweener, с префиксами.
26: Новый, без префиксов.
Safari3-: Не поддерживаются.
4-5.0: Старый, с префиксами.
5.1-6.0: Tweener, с префиксами.
6.1: Новый, без префиксов.
Firefox3.5-: Не поддерживаются.
3.6-15: Tweener, с префиксами.
16: Новый, без префиксов.
Opera11.0-: Не поддерживаются.
11.1-11.5: Tweener, с префиксами, только линейные.
11.6-12: Tweener, с префиксами, добавлены радиальные.
12.1: Tweener, без префиксов.
15: Новый, без префиксов.
IE8-: Не поддерживаются.
9: Только фильтры.
10+: Новый, без префиксов (также поддерживается префикс Tweener w/).
Android2.0-: Не поддерживаются.
2.1-3.0: Tweener, с префиксами.
4.0-4.3: Новый, с префиксами.
4.4+: Новый, без префиксов.
iOS3-: Не поддерживаются.
3.2-4.3: Tweener, с префиксами.
5.0-6.1: Новый, с префиксами.
7.0: Новый, без префиксов.

Тут существуют некоторые накладки. Например, если браузер поддерживает новый синтаксис, он, как правило, также поддерживает и старые синтаксисы, в том числе и префиксы.

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

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

.gradient {
  
  /* Резервный вариант (могут альтернативно использоваться.jpg/.png) */
  background-color: red;

  /* SVG резервный вариант для IE 9 (могут использоваться URI-данные или фильтры) */
  background-image: url(fallback-gradient.svg); 

  /* Safari 4, Chrome 1-9, iOS 3.2-4.3, Android 2.1-3.0 */
  background-image:
    -webkit-gradient(linear, left top, right top, from(red), to(#f06d06));
  
  /* Safari 5.1, iOS 5.0-6.1, Chrome 10-25, Android 4.0-4.3 */
  background-image:
    -webkit-linear-gradient(left, red, #f06d06);

  /* Firefox 3.6 - 15 */
  background-image:
    -moz-linear-gradient(left, red, #f06d06);

  /* Opera 11.1 - 12 */
  background-image:
    -o-linear-gradient(left, red, #f06d06);

  /* Opera 15+, Chrome 25+, IE 10+, Firefox 16+, Safari 6.1+, iOS 7+, Android 4.4+ */
  background-image:
    linear-gradient(to right, red, #f06d06);

}

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

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

Примеси Compass помогут перевести SVG-данные в URI под IE 9, если это для вас существенно.

Фильтры IE

Internet Explorer (IE) 6-9 не поддерживает синтаксис CSS градиентов, однако предлагает программный способ задать градиенты фона:

/* "Некорректный" способ, однако работает в версиях 6-8 */
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr=#1471da, endColorstr=#1C85FB);

/* Корректный, работает в версиях 8-9 */
-ms-filter: "progid:DXImageTransform.Microsoft.gradient (GradientType=0, startColorstr=#1471da, endColorstr=#1C85FB)";

Существует несколько критериев относительно того, применять вам фильтры или нет:

  1. Считается, что filter негативно влияют на производительность;
  2. background-image накладывается поверх фильтров, так что если вы хотите использовать его как запасной вариант, применение фильтров противопоказано. Однако если сплошной цвет является резервным вариантом (background-color), использование фильтров приемлемо.

Даже с учетом того, что фильтры работают только с шестнадцатеричными значениями, вы все равно можете получить альфа-прозрачность соотнеся шестнадцатеричное значение со значение прозрачности от 00 (0%) до FF (100%).

Например:

RGBA ( 92,47,90,1 ) == # FF5C2F5A
RGBA ( 92,47,90,0 ) == # 005C2F5A

Радиальные градиенты

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

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

По умолчанию первый цвет используется для начала перехода (в центре элемента), затем он переходит в конечный цвет по краям элемента.

Переход осуществляется равномерно независимо от направления:

.gradient {
  background-image:
    radial-gradient(
      yellow,
      #f06d06
    );
}

Посмотреть пример на Codepen

Вот как градиент задает эллиптическую форму, когда элемент не имеет квадратной формы.

Это по умолчанию (ellipse по умолчанию задается в качестве первого параметра), но если вы хотите чтобы градиент создавал круг, мы можем задать это отдельно:

.gradient {
  background-image:
    radial-gradient(
      circle,
      yellow,
      #f06d06
    );
}

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

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

Для этого в первом параметре мы через пробел задаем «closest-side»:

.gradient {
  background-image:
    radial-gradient(
      circle closest-side,
      yellow,
      #f06d06
    );
}

Посмотреть пример на Codepen

Также могут задаваться значения: closest-corner (ближайший угол), closest-side(ближайший край), farthest-corner (самый дальний угол), farthest-side (самый дальний край).

Вы можете представить себе это так: «Я хочу, чтобы радиальный градиент переходил из центральной точки в __________ , и везде цвет распределялся сообразно этому».

Радиальный градиент не обязательно должен начинаться в центре, вы можете задать центральную точку преобразований, указав ее с помощью "at ______" в первом параметре:

.gradient {
  background-image:
    radial-gradient(
      circle at top right,
      yellow,
      #f06d06
    );
}

Здесь я сделал это более наглядно, подготовив пример с квадратом и настроив точки color-stop:

Посмотреть пример на Codepen

Поддержка браузерами

Здесь в значительной степени все так же, как в случае с linear-gradient() , за исключением очень старых версий браузера Opera, которые поддерживают только линейные градиенты, но не радиальные.

Аналогично синтаксис radial-gradient() претерпел несколько изменений. Здесь также существует три набора: «Старый», «Tweener» и «Новый»:

/* Пример Старого синтаксиса */
background-image: 
  -webkit-gradient(radial, center center, 0, center center, 141, from(black), to(white), color-stop(25%, blue), color-stop(40%, green), color-stop(60%, red), color-stop(80%, purple));

/* Пример Tweener */
background-image: 
  -webkit-radial-gradient(45px 45px, farthest-corner, #F00 0%, #00F 100%) repeat scroll 0% 0% rgba(0, 0, 0, 0);

/* Пример Нового */
background-image: 
  radial-gradient(circle farthest-side at right, #00F, #FFF);

Их отличительными чертами являются:

  • Старый: с префиксами использует -webkit-, синтаксис типа from() и color-stop();
  • Tweener: Первый параметр в нем определяет центр градиента. Это полностью сломает структуру в новых браузерах, поддерживающих синтаксис без префикса, поэтому проверяйте, чтобы все префиксы синтаксиса Tweener были расставлены;
  • Новый: первый параметр имеет синтаксис типа "circle closest-corner at top right".

Опять же, я всегда обрабатываю код с помощью Autoprefixer. Вы пишете код в соответствии с новейшим синтаксисом, он делает резервные варианты.

Радиальные градиенты более гибкие, чем линейные, поэтому я рекомендую вам просто освоить новейший синтаксис и следовать ему (в крайнем случае, старый синтаксис можно не учитывать).

Повторяющиеся градиенты

Повторяющиеся градиенты имеют более слабую поддержку браузерами. Они представляют собой смесь линейных и радиальных градиентов.

В веб-дизайне существует такой трюк. Берется неповторяющийся градиент. С его помощью создается небольшой фрагмент, он стыкуется с таким же небольшим фрагментом, копией самого себя.

И в результате из таких прямоугольников выстраивается узор. По сути, вы создаете один небольшой прямоугольник и задаете background-size. С помощью подобного подхода легко создавать узоры полос, которые вы можете разворачивать в любую сторону.

С помощью repeating-linear-gradient(), вам не нужно прибегать к таким хитростям.

Размер градиента определяется окончательным color stop. Если размер color stop 20 пикселей, то размером градиента (который затем повторяется) будет квадрат 20 на 20 пикселей:

.repeat {
  background-image: 
    repeating-linear-gradient(
      45deg,
      yellow,
      yellow 10px,
      red 10px,
      red 20px /* determines size */
    );
}

Посмотреть пример на Codepen

То же самое касается радиальных градиентов:

.repeat {
  background: 
    repeating-radial-gradient(
      circle at 0 0, 
      #eee,
      #ccc 50px
    );
}

Посмотреть пример на Codepen

Некорректная резервная загрузка

Как мы уже упоминали, некоторые очень старые браузеры вовсе не поддерживают CSS-синтаксис градиентов. Если вам нужен запасной вариант, который бы работал, как замена градиентам, здесь можно применить изображение (.jpg/ .png).

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

Тогда они будут отсылать HTTP-запрос к изображению, даже если мог быть использован CSS-градиент.

Так происходит с Firefox 3.5.8 (скриншот), а также с Google Chrome ниже 5 версии и Safari 5.0.1:

Посмотреть пример на Codepen

Отказ загрузки Safari 5.0.1

Правда на сегодняшний день это уже не является серьезной проблемой. Единственные браузеры, в которых наблюдались такие трудности, это Google Chrome и Safari. В Chrome это исправлено в версии 6, в Safari - в версии 5,1, которые вышли три года назад.