Использование SVG
SVG - формат векторной графики. Буквально его название значит «масштабируемая векторная графика» (Scalable Vector Graphics). Попросту говоря, это то, с чем вы работаете в Adobe Illustrator. SVG можно легко использовать в вебе, но сперва нужно во многом разобраться.
Зачем вообще нужен SVG?
- Небольшие размеры файлов, отличное сжатие;
- Масштабирование до любого размера, без потери качества (разве что, при совсем маленьких размерах);
- Хорошо выглядит на ретине;
- Широкие возможности, которые предоставляют фильтры и интерактивность.
Создадим изображение SVG, с которым будем работать дальше
Создайте произвольный рисунок в Adobe Illustrator. Вот, например, птица киви на овале.
Обратите внимание, что изображение кадрируется чётко по краям изображения. Холст в SVG играет не меньшую роль, чем в PNG или JPG.
Adobe Illustrator умеет сохранять в SVG.
При сохранении появится ещё одно диалоговое окно с настройками. Честно говоря, я не очень в них разбираюсь. Существует целая инструкция по Профилям SVG. Меня вполне устраивает SVG 1.1.
Здесь стоит отметить, что у вас есть возможность нажать OK и сохранить файл или же нажать кнопку “SVG Code…”, которая откроет окно TextEdit (по крайней мере на Mac) с SVG-кодом.
Оба варианта могут пригодиться.
Добавляем SVG на страницу с помощью тега <img>
Если сохранить изображение SVG в файл, то его можно вставить с помощью тега <img>
.
<img src="kiwi.svg" alt="Киви на овале">
В Illustrator рабочая область была размером 612px ✕ 502px.
Именно такие размеры будут у изображения на странице, если их не указать
специально. Его размеры можно изменить, задав атрибуты width
или height
для
img
, так же как для PNG или JPG. Вот пример:
Посмотрите на этот пример!
Поддержка браузерами
SVG по-разному поддерживается браузерами. Он работает везде, кроме IE до 8 версии и браузерах на Android до версии 2.3.
Если вы хотели бы использовать SVG, но проект поддерживает браузеры, которые
не могут вставлять его через img
, есть разные варианты. Я описал некоторые
приемы в нескольких своих мастер-классах.
Один из вариантов: проверка поддержки через Modernizr и замена src
для
изображения:
if (!Modernizr.svg) {
$(".logo img").attr("src", "images/logo.png");
}
Дэвид Бушел (David Bushell) предложил очень простой альтернативный вариант, если вы не имеете ничего против JavaScript в разметке:
<img src="image.svg" onerror="this.onerror=null; this.src='image.png'">
Еще можно использовать SVGeezy. Далее мы рассмотрим другие способы деградации.
Добавляем SVG через background-image
Использовать SVG в качестве фона c помощью CSS-свойства background-image
так
же просто, как и вставка с помощью тега img
.
<a href="/" class="logo">
Kiwi Corp
</a>
.logo {
display: block;
text-indent: -9999px;
width: 100px;
height: 82px;
background: url(kiwi.svg);
background-size: 100px 82px;
}
Обратите внимание, что для селектора .logo
задан размер background-size
. Это
необходимо, иначе будет видна только верхняя левая часть изображения SVG, у
которого исходный размер намного больше. Эти размеры прописаны с учётом
соотношения сторон изображения в оригинале. Можно также использовать для
background-size
значение contain
, чтобы убедиться в том, что изображение
поместится в родительский контейнер, если вам не известно какого размера оно
должно быть.
Поддержка браузерами
Вставка SVG через свойство background-image
по-разному поддерживается
браузерами, но в общем дела обстоят так же, как и с img
. Проблемой являются
IE до 8 версии и браузеры на Android до версии 2.3.
В этом случае нам может помочь Modernizr, даже более эффективно, чем при
использовании img
. Если заменить background-image
на изображение,
формат которого поддерживается, на сервер будет отправлен один HTTP-запрос,
а не два. Modernizr добавляет класс “no-svg” для html-элемента,
если SVG не поддерживается:
.main-header {
background: url(logo.svg) no-repeat top left;
background-size: contain;
}
.no-svg .main-header {
background-image: url(logo.png);
}
Общая проблема при использовании <img>
и background-image
…
Проблема состоит в том, что вы не можете управлять внутренностями SVG с помощью CSS так, как сможете при использовании двух приёмов описанных ниже. Читайте дальше!
Добавляем SVG непосредственно в документ
Помните, как при необходимости можно получить SVG-код прямо при сохранении
изображения в Illustrator? Ещё можно просто открыть SVG-файл в текстовом
редакторе и скопировать его код. Этот код можно вставить прямо в HTML-документ,
и SVG-изображение будет отображаться точно так же, как если бы его вставили с
помощью тега img
.
<body>
<!-- вставьте код SVG, и появится изображение! -->
</body>
Этот приём может быть полезным, так как изображение встроено прямо в документ, и для его загрузки не происходит дополнительный HTTP-запрос. У этого метода те же преимущества, как и у использования Data URI. И недостатки у него те же, не обольщайтесь. Среди них: вероятность получения очень тяжелого документа, наличие блоков SVG-кода в нем и невозможность кэширования.
Если вы используете серверный язык, который позволяет получить содержимое файла и вставить его в документ, вы по крайней мере сможете очистить свой документ от блоков SVG кода. Вот так:
<?php include("kiwi.svg"); ?>
Сначала оптимизируем
Без сомнений, для вас не станет сюрпризом то, что SVG, полученные в Adobe Illustrator, не самые оптимальные. Они содержат DOCTYPE, примечания генератора и прочий мусор. У SVG, в общем, и так небольшой размер, но почему бы не уменьшить его еще больше, если есть возможность? Питер Коллингридж (Peter Collingridge) создал SVG Optimiser, инструмент для онлайн-оптимизации SVG. Загружаете старый файл, скачиваете новый. В своём видео Кайл Фостер заходит ещё дальше и удаляет даже переносы строки в процессе оптимизации.
Если вы еще более суровы, вот вам инструмент на Node JS, с помощью которого можно оптимизировать изображения самостоятельно.
Затем управляем с помощью CSS
Видите, насколько сильно теперь SVG похоже на HTML? Это потому, что они оба
не что иное, как XML (теги и всякая всячина внутри). В нашем проекте есть
два составляющих элемента, <ellipse>
и <path>
. Можно просто открыть код
и присвоить им классы, как любому другому элементу HTML.
<svg ...>
<ellipse class="ground" .../>
<path class="kiwi" .../>
</svg>
Теперь эти отдельные элементы можно контролировать с помощью специального CSS
для SVG. Необязательно добавлять CSS в сам SVG, его можно разместить где
угодно, даже в файле с глобальными стилями. Обратите внимание, что для элементов
SVG есть специальный набор свойств CSS. Например, нельзя использовать
background-color
, вместо него есть fill
. Однако кое-что стандартное тоже
можно использовать, например, :hover
.
.kiwi {
fill: #94d31b;
}
.kiwi:hover {
fill: #ace63c;
}
Более того, в SVG можно использовать фильтры, например размытие:
<svg ...>
...
<filter id="pictureFilter" >
<feGaussianBlur stdDeviation="5" />
</filter>
</svg>
И его можно применить из CSS:
.ground:hover {
filter: url(#pictureFilter);
}
Пример того, что может получиться:
Check out this Pen!
- Подробнее о применении фильтров для SVG
- Самый лучший список CSS-свойств для SVG, который мне удалось найти (разработанный для Opera)
- Песочница для тестирования эффектов от применения фильтров для SVG (от Microsoft)
Поддержка браузерами
Добавление SVG непосредственно в документ по-разному поддерживается браузерами, однако все сводится к отсутствию поддержки IE младше 8 и браузерам на Android до версии 2.3 1.
Для этого способа вставки SVG можно использовать следующие приемы деградации:
<svg> ... </svg>
<div class="fallback"></div>
И снова используем Modernizr:
.logo-fallback {
display: none;
/* Убедитесь, что размер соответствует размеру SVG */
}
.no-svg .logo-fallback {
background-image: url(logo.png);
}
Добавляем SVG на страницу с помощью тега <object>
Если по какой-либо причине вариант со вставкой SVG непосредственно в документ
вам не нравится (он все же имеет парочку недостатков, например, кэширование
практически невозможно), можно подключить SVG-файл используя <object>
и
сохранить возможность управлять его частями посредством CSS.
<object type="image/svg+xml" data="kiwi.svg" class="logo">
Kiwi Logo <!-- запасное изображение в CSS -->
</object>
На тот случай, если это не поддерживается, реализуем деградацию, используя класс, который добавляет Modernizr:
.no-svg .logo {
width: 200px;
height: 164px;
background-image: url(kiwi.png);
}
При таком подходе не возникают проблемы с кэшированием, и он
поддерживается браузерами лучше, чем другие. Но если использовать внешний файл
со стилями или <style>
встроенный в документ, CSS-навороты работать не будут,
нужно добавить элемент <style>
в сам SVG-файл.
<svg ...>
<style>
/* специальные CSS-фишки для SVG */
</style>
...
</svg>
Внешние файлы со стилями для SVG, вставленного с помощью <object>
Есть способ добавить в SVG-файл внешний файл со стилями, если это необходимо
работы для проекта, кэширования или еще чего-то. Я экспериментально выяснил,
что он работает только для SVG-файлов, встроенных в документ с помощью тега
<object>
. Вот что нужно добавить в SVG-файл перед открывающим тегом <svg>
:
<?xml-stylesheet type="text/css" href="svg.css" ?>
Если попробовать добавить этот код в HTML, вы получите ошибку, и браузер даже
не подумает его подгружать. Если подключить SVG-файл, в котором предложенный
код заменяет <img>
или background-image
, система ругаться не будет, но и
работать такой код не будет (SVG, однако, отобразится).
Использование Data URI для SVG
SVG-файл можно уменьшить еще сильнее, если конвертировать его в Data URI. На Mobilefish.com для этого есть онлайн-конвертер. Просто скопируйте содержимое SVG-файла и заполните форму, результат конвертирования можно будет скопировать с текстового поля. Не забудьте удалить переносы строки в полученном коде. Выглядеть он будет как полнейшая тарабарщина:
Его можно использовать в любом из приёмов, которые мы рассмотрели (кроме вставки
<svg>
непосредственно в документ, поскольку это попросту нелогично). Просто
скопируйте всю полученную тарабарщину вместо [data]
в следующих примерах.
Добавление на страницу с использованием тега <img>
<img src="data:image/svg+xml;base64,[data]">
Добавление на страницу в качестве фона с использованием CSS
.logo {
background: url(data:image/svg+xml;base64,[data]);
}
Добавление на страницу с использованием тега <object>
<object type="image/svg+xml" data="data:image/svg+xml;base64,[data]">
fallback
</object>
Кстати, если добавить <style>
в SVG до кодирования в base64, он будет
работать при добавлении на страницу с использованием тега <object>
!
А для по-настоящему суровых разработчиков компания Filament group предлагает
инструмент grunticon, который автоматизирует этот процесс.
Консольные штучки для перекодирования SVG в base64:
@chriscoyier @hkfoster maybe you could take a shortcut with >>> echo -n `cat logo.svg` | base64 | pbcopy
— Benny Schudel (@bennyschudel) March 2, 2013
Или же Матиас Биненс (Mathias Bynens) предлагает свои приёмы:
Используйте
openssl base64 < path/to/file.png | tr -d '\n' | pbcopy
илиcat path/to/file.png | openssl base64 | tr -d '\n' | pbcopy
чтобы пропустить запись в файл и просто скопировать выходные данные в кодировке base64 в буфер без переносов строки.
Материалы для дальнейшего чтения
- Дэвид Бушел: Букварь фронтендера по SVG-хакерству
- Дэвид Бушел: Независимость от разрешения с SVG
- MDN про SVG
- Поддержка браузеров для всяких всячин повязанных с SVG.
- Питер Гестон (Peter Gasston): Создание лучших SVG-спрайтов при помощи анкерных идентификаторов
- simuari: SVG стеки
- SVG.js - «Упрощённая библиотека для манипуляции и анимации SVG»
- В Emmet есть отличный способ генерировать data URI для SVG прямо в редакторе кода
- В Compass также есть вспомогательное средство для data URI
- Adobe: Стилизация SVG
- Эндрю Дж. Бейкер (Andrew J. Baker): Приручаем зверя SVG
- Альтернатива Illustrator: Inkscape, Sketch
- Кристер Кари (Krister Kari): Использование SVG-изображений для мобильных браузеров
Нельзя не упомянуть видео Кайла Фостера «Последовательность оптимизации SVG»:
… взгляните также на это видео + слайды.
Примечания
1. Говоря о браузере Android 2.3, вот. Но если вам никак не обойтись без поддержки родного браузера, вот.