SVG

SVG — это формат векторных изображений, основанный на XML.

Спецификация: w3.org/TR/SVG

SVG имеет массу преимуществ перед растровыми изображениями:

  • векторные изображения масштабируются без потери качества и лучше отображаются на устройствах с ретиной;
  • SVG, как правило, весит несколько меньше, чем PNG-версия того же изображения;
  • содержимое рисунка описывается на XML, SVG-файл можно открыть в текстовом редакторе и увидеть человекопонятный код;
  • поэтому SVG-изображение можно не только нарисовать в векторном редакторе, но и написать руками;
  • SVG-файл — это всегда исходник. В отличие от растровой графики, для его редактирования не требуется исходный PSD-файл, содержимое файла не склеивается в один слой, поэтому его всегда можно просто открыть и отредактировать. Правда, если в файле также есть стили и скрипты, лучше так не делать, потому что содержимое перезапишется;
  • внутри SVG-файла можно описывать тени и градиенты, причем использовать их можно не только внутри этого файла, но также можно применять и к внешним элементам (пока работает не везде);
  • внутри файла могут находиться CSS и JavaScript.

Пример SVG:

See the Pen SVG Car by yoksel (@yoksel) on CodePen.

SVG хорошо поддерживается всеми современными браузерами и его уже вполне можно использовать, предусмотрев PNG-версии для старых браузеров.

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

Хорошо видно, что SVG (внизу) в этих условиях выглядит гораздо лучше, чем PNG (наверху). Так что если поставить себе задачу сделать сайт, который хорошо выглядит на любых устройствах, SVG очень пригодится.

Уже сейчас можно найти довольно много сайтов с готовой SVG-графикой, например:

iconmelon.com icomoon.io flaticon.com iconmonstr.com

В основном, это наборы иконок.

Можно использовать картинки как есть, а можно перекрасить, объединить в стек, спрайт или сделать шрифт.

SVG на страницу можно вставить несколькими способами. Они по-разному поддерживаются браузерами и предоставляют разные возможности.

Embed/object/iframe

Содержимое доступно для внешнего JavaScript. Хорошая поддержка браузерами (все, кроме IE8 и ниже).

Embed: Object: Iframe:
Embed:
<embed src="your.svg"
        width="199" height="200">
Object:
<object data="your.svg"
        type="image/svg+xml" width="199" height="200"></object>
Iframe:
<iframe src="your.svg"
        width="199px" height="200px"></iframe>

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

IE Opera Opera Mini Opera Mobile Chrome Firefox Safari
9+ 9+ 5+ 10+ 4+ 3+ 3.2+

IMG

Содержимое недоступно для JS.

<img src="your.svg">

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

IE Opera Opera Mini Opera Mobile Chrome Firefox Safari
9+ 9+ 5+ 10+ 4+ 4+ 4+

Css backgrounds

Содержимое недоступно для JS. Могут быть проблемы в старых Операх. Не работает в Opera Mini В Opera Mini работает только без viewBox в SVG.

background-image: url(your.svg);

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

IE Opera Opera Mini Opera Mobile Chrome Firefox Safari
9+ 12+ 5+ 16+ 5+ 24+ 5+

Inline SVG

Не работает в Opera Mini.

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

IE Opera Opera Mini Opera Mobile Chrome Firefox Safari
9+ 11.6+ 12+ 7+ 4+ 5.1+

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

Способы отображение в старых браузерах:

1. Хак для элемента с фоном:
DIV {
    background-image: url(your.png); /* PNG для IE6-8 */
    background-image: url(your.svg), none;
    }

Вторая строка сработает в браузерах с поддержкой CSS3, старые её проигнорируют и покажут PNG из первой строки.

2. Способ с image

Современные браузеры выберут атрибут xlink:href и покажут SVG, старые выберут src и покажут растровую версию:

<svg width="200px" height="200px">
    <image xlink:href="your.svg"
           src="your.png"
           width="200px" height="200px"/>
</svg>

Способ найден здесь: lynn.ru/examples/svg/. Про этот способ есть статья у Криса Коера Svg fallbacks, в которой он анализирует этот вариант вставки и предлагает другие.

Способ хорошо работает в IE8 и Opera Mini. Минус способа — загрузка обоих файлов в IE9-11, хотя отобразится только SVG. Также есть проблемы с отображением в 12-й Опере: вместо картинки иногда загружается вот такое:

SVG in Opera 12

3. Modernizr

Элементы, содержащие SVG-графику, заворачиваются в div.svg (например). Затем определяем поддержку SVG с помощью Modernizr, браузеры без SVG определяем по классу .no-svg, дальше немного CSS:

/* Задаем обертке размеры и фон в PNG: */
.no-svg .svg {
  width: 200px;
  height: 200px;
  background: url(your.png); /* PNG-заглушка */
  }
/* Скрываем содержимое обертки (иначе будут отображаться
иконки незагрузившихся картинок) */
.no-svg .svg IFRAME,
.no-svg .svg OBJECT,
.no-svg .svg EMBED,
.no-svg .svg IMG {
  display: none;
} 

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

Хорошее решение для IE8 и старше. Проблема может возникнуть с Opera Mini. Она имеет частичную поддержку SVG, поэтому не будет селектора .no-svg, и при этом она не поддерживает SVG в CSS-фонах и Inline Svg, так что они не отобразятся.

Для IE также можно использовать вот такое определение версии браузера.

4. :root

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

/* По умолчанию показываем PNG: */
.svg {
  width: 200px;
  height: 200px;
  background: url(your.png);
}

/* Контейнеры с SVG скрыты. */
.svg IFRAME,
.svg OBJECT,
.svg EMBED,
.svg IMG {
  display: none;
}

/* Включаем содержимое для браузеров с поддержкой CSS3 */
:root IFRAME,
:root OBJECT,
:root EMBED,
:root IMG {
  display: inline-block;
}

Как и предыдущее решение, подойдет для IE8 и старше, но не поможет в Opera Mini, потому что она поддерживаeт CSS3, поэтому не будет заглушек для элементов с SVG-фоном и инлайновым SVG.

5. Решение для Opera на Presto (например, 12 и Mini)

В Opera 12 SVG-фоны могут вести себя странно, местами до сильного. Совершенно невинный CSS может привести к проблемам отрисовки векторых фонов при прокрутке страницы. Мне удавалось получить такое:

Действующий пример можно увидеть тут: http://jsbin.com/winag/1/edit. Откройте ссылку в Opera 12 и прокрутите страницу вверх-вниз.

В Opera Mini большие проблемы c фоновым SVG, а инлайновый не поддерживается совсем.

Opera Mini и фоновый SVG:

На этот случай можно использовать хак, который сработает только в Опере:

doesnotexist:-o-prefocus, .selector {
  background-image: url(your.png);
}

Способ использует специфичный для оперы селектор, подробнее про такие селекторы можно почитать тут: opera.com/docs/specs/presto2.12/css/o-vendor

6. Селектор только для Opera Mini
@media all and (-webkit-min-device-pixel-ratio:10000), not all and (-webkit-min-device-pixel-ratio:0) {
  .selector {
    background-image: url(your.png);
  }
}

Рассмотренная тема — только верхушка айсберга, в спецификации есть ещё много всего интересного. Продолжение следует : )

Ссылки по теме:
Browsers support for SVG
SVG Fallbacks
Modernizr
A Primer to Front-end SVG Hacking
Трюки с SVG и тегом image
SVG fallback pure CSS
Если вы нашли ошибку или неточность, вы можете отредактировать статью с помощью prose.io, а также можно написать мне в комментариях или в Twitter.
Система комментирования от Disqus