Непростая простая кнопка

Надеюсь, ни для кого уже не секрет, что оформительскую графику на сайтах давно пора переводить в формат SVG с растровым фолбеком (при необходимости). Кто понял это раньше, чем экраны с ретиной, готовые поспорить по качеству картинки с полиграфией, появились на 4-м айфоне, новом айпаде, а теперь и на новом макбуке — тот большой молодец. Но если кто-то до сих пор не в курсе, у меня специально для вас есть комикс SVG vs PNG.

В отличие от сложных методов, вроде -webkit-image-set, для которых нужно указывать несколько источников картинки в зависимости от разрешения, в случае с SVG нужна всего одна векторная картинка для всех случаев:

	E {
	    background:url(image.png) no-repeat;
	    background:rgba(0, 0, 0, 0) url(image.svg) no-repeat;
	    }

Удивлены, зачем перед второй декларацией стоит прозрачный чёрный цвет? Браузеры, которые не понимают SVG и о которых пока приходится заботиться, в нашем случае это всеми любимые IE6, IE7 и IE8, помимо прочего, не поддерживают цветовую модель rgba(…) в CSS, поэтому декларация для них окажется невалидной и будет отброшена. К сожалению, это не сработает в Firefox 3.6 и в старых браузерах на движке Webkit, которые стоят на системах вроде Android 2.2 (как на моём HTC Desire), поэтому для них будет уместнее использовать определение поддержики SVG с помощью Modernizr. Тогда вам придётся написать что-то вроде:

	E {
	    background:url(image.png) no-repeat;
	    }
	.inlinesvg E {
	    background:url(image.svg) no-repeat;
	    }

Поскольку в Firefox 3.6 есть базовая поддержка SVG (через элемент <object>), но нет поддержки SVG в для фоновых изображений в CSS, то определять поддержку нужно будет не через класс .svg, а через .inlinesvg, который появился в Firefox 4.0 вместе с поддержкой векторных фоновых картинок.

Дальше мы просто экспортируем SVG-картинку из любимого векторного редактора, чистим от мусора, расставляем недостающие параметры, вставляем в CSS фоном. Но дьявол, как известно, в мелочах, и даже простую кнопку с векторной иконкой можно сделать пятью разными способами. Поэтому давайте пройдём шаг за шагом процесс создания кнопки, решая разные проблемы, возникающие по дороге, и даже просто выдумывая себе новые.

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

Самая простая кнопка

Простая кнопка, увеличенная примерно в 10 раз для наглядности

Давайте начнём с самой простой кнопки «Play», которая согласно первоначальной дизайнерской идее представляет собой чёрный треугольник, который должен быть вписан в белый квадрат размером 25×25 пикселей. Любители CSS-графики тут же попытаются сделать её с помощью лошадиных размеров рамок, диагонали которых нормально сглаживаются только при углах, кратных 45°, а мы с вами пока продолжим.

Начинать всегда стоит с HTML, и мы возьмём для нашей кнопки элемент «кнопка», что может быть логичнее! Предусмотрим сразу абстрактную кнопку .button и её подвид .play.

	<button class="button play">Play</button>

И добавим простой CSS:

	.button {
	    display:inline-block;
	    padding:0;
	    width:25px;
	    height:25px;
	    border:none;
	    background:#000 no-repeat;
	    text-indent:-9999px;
	    }
	.button.play {
	    background-image:url(images/play-button.png);
	    background-image:rgba(0, 0, 0, 0) url(images/play-button.svg);
	    }

Если мы собираемся делать векторную графику, понятно, что без векторых исходников нам не обойтись. Первым делом хочется поступить с этим треугольником так же, как мы раньше поступали с растровой графикой: просто сохранить его как SVG и поставить фоном. Но в нашем случае фигура настолько простая, что вместо экспорта её будет проще написать руками. Заодно мы сможем понять, как работает SVG, и нам не придётся чистить экспорт от мусора. Возьмём шаблон минимального SVG-файла и вставим в него элемент <polygon> с тремя точками, соответствующими вершинам нашего треугольника. Координаты точек в Illustrator можно подсмотреть, наведя курсор на каждую из них. Пары координат через запятую разделяются пробелами: x1,y1 x2,y2.

	<svg xmlns="http://www.w3.org/2000/svg" width="8" height="9">
	    <polygon fill="#000" points="0,0 8,4.5 0,9"/>
	</svg>

Если мы зададим размеры SVG-элементу с помощью атрибутов width и height, иконка будет вести себя как растровая и всегда будет указанных размеров, куда бы мы её не вставили. Это вполне нормально и выполняет нашу задачу по отрисовке чёткой графики для дисплеев с высоким разрешением. Но указание явных размеров лишает нас одного из преимуществ формата — возможности подстаиваться под размеры объекта, фоном к которому он указан.

Поэтому давайте вместо размеров укажем нашей иконке атрибут viewBox (именно с прописной «B», иначе не сработает) со значением 0 0 8 9, где 8 и 9 — это ширина и высота нашей иконки в пикселях. Подробнее про viewBox и другие его параметры читайте в спецификации SVG.

	<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 9">
	    <polygon fill="#000" points="0,0 8,4.5 0,9"/>
	</svg>

А теперь откройте по очереди два файла play-fixed.svg и play-viewbox.svg в новых вкладках и сравните результат. При указанных размерах SVG сохраняет их, а с указанным viewBox пытается вписаться в размеры окна или элемента, сохраняя пропорции. Поэтому если мы захотим сделать ещё одну кнопку не 25×25, а 100×100 пикселей, то нам не придётся создавать новую иконку для неё.

Но в нашем случае нужно не просто вписать треугольник во все 25×25 пикселей кнопки, а сохранить пропорции отступов и расположения треугольника. Поэтому давайте сделаем нашу картинку сразу нужных размеров и спозиционируем иконку ровно так, как на макете с дополнительным смещением для координат. В итоге получится файл play-button.svg.

	<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25">
	    <polygon fill="#000" points="9,8 17,12.5 9,17"/>
	</svg>

Но это слишком просто. Сделаем что-нибудь поинтереснее.

Кнопка без тени — деньги на ветер

Непростая кнопка с синей заливкой и внутренней тенью

И тут к нам забегает дизайнер чёрного треугольника (и большой поклонник Малевича, по-видимому) и говорит, что совсем забыл про активное состояние кнопки. Во время воспроизведения она должна гореть голубым цветом и выглядеть вдавленной. Поменять цвет заливки нашей картинки теперь просто как никогда, ведь мы сами писали этот треугольник и знаем, как там всё устроено. А вот внутреннюю тень дизайнер нарисовал с помощью одного из сотни спецэффектов в Photoshop или Illustrator. И мы могли бы скомбинировать десяток SVG-фильтров и попытаться сделать настоящую тень, но это становится слишком сложной задачей, и с кроссбраузерностью у фильтров не всегда хорошо.

Градиенты для имитации внутренней тени

Поэтому мы попробуем имитировать эту тень с помощью двух градиентов. Один мы пустим по верхней грани нашего треугольника, другой по левой, немного повернём каждый из них и добьёмся размытием нужного эффекта. Для того чтобы градиенты правильно наложились в одну тень поверх фонового цвета, они должны начинаться в 100% прозрачности и выходить в нулевую. Градиенты в SVG появились намного раньше, чем в CSS, и имеют свой особенный синтаксис, немного отличающийся от того, к чему мы привыкли.

Сам градиент, как и другая метаинформация, задаётся в специальной секции <defs> и описывается элементом <linearGradient>, который можно повернуть с помощью атрибута gradientTransform. Каждый цвет, его смещение и прозрачность описываются во вложенном элементе <stop>.

	<linearGradient x1="0" y1="0" x2="0" y2="100%" id="shadow-left"
	        gradientTransform="rotate(-75 0.5,0.5)">
	    <stop stop-color="#0020FF" offset="0"/>
	    <stop stop-color="#1ABEF1" stop-opacity="0" offset="40%"/>
	</linearGradient>

Мы с вами оказались чертовски предусмотрительны и задали каждому из двух градиентов ID shadow-left и shadow-top, и теперь сможем вызвать их с помощью атрибута fill="url(#shadow-left)" и значением ID в качестве параметра. Но для того, чтобы этот трюк сработал, нам нужно будет добавить к корневому элементу <svg> ещё один атрибут xmlns:xlink, описывающий пространство имён xlink.

Мне так и не удалось применить несколько градиентов к одному элементу одновременно с заливкой, и, кажется, это просто невозможно. Поэтому придётся продублировать наш треугольник трижды: сначала со сплошной заливкой, потом с левым и с верхим градиентом. Те элементы, что пойдут последними, окажутся выше, как и в HTML.

	<svg xmlns="http://www.w3.org/2000/svg"
	     xmlns:xlink="http://www.w3.org/1999/xlink"
	     viewBox="0 0 25 25">
	    <defs>
	        <!-- Описание градиентов -->
	    </defs>
	    <polygon points="9,8 17,12.5 9,17" fill="#1ABEF1"/>
	    <polygon points="9,8 17,12.5 9,17" fill="url(#shadow-left)"/>
	    <polygon points="9,8 17,12.5 9,17" fill="url(#shadow-top)"/>
	</svg>

Можно было бы конечно создать символ треугольника, а потом применить его снова с помощью элемента <use>, но у этого способа плохо с кроссбраузерностью в Webkit. Итак, наш супер-треугольник с градиентами, складывающимися в тень: play-active.svg.

Если совместить получившуюся картинку с нашей кнопкой и добавить активное состояние с помощью класса .active, то получится вот такая красота: play-plain.html. В этом примере, в силу очевидности, специально нет растрового фолбека, а кнопки специально увеличены в 10 раз, чтобы можно было рассмотреть, насколько прекрасна векторная графика.

Обычная и активная кнопки и их увеличенные варианты

Маски-шоу

Наша красивая кнопка готова, но не знаю, как вам, а мне всё мало и хочется больше чудес. Было бы хорошо не бегать в SVG, настраивая все параметры кнопки, а делать всё прямо в CSS. И даже больше — хочется иметь одну форму треугольника в SVG, а все его подробности рисовать в CSS, включая состояния по наведению и даже плавные переходы. Очень напоминает маску, не так ли?

Принцип псевдомаски

Как вы помните, полноценных кроссбраузерных масок в CSS нет. К сожалению, пока нет даже спецификации, в которой они были бы описаны. Маски уже давно есть в SVG, но в нашем случае это не поможет.

Поможет нам старый добрый трюк, допустимый только для однородного и постоянного фона под объектом. Допустим, что наша кнопка всегда будет на белом фоне или нам не лень нарисовать маски для нескольких других фонов. Мы нарисуем SVG-картинку, залитую сплошным цветом и сделаем в ней дырку как раз той формы, что и наш треугольник. А всё остальное оформление будем рисовать в CSS.

И если наш простой треугольник состоял из трёх точек, то маску с двумя контурами нужно будет рисовать уже с помощью кривых Безье, прямо в редакторе. На самом деле, всё просто. Мы берём квадрат 25×25, кладём на него треугольник и вычитаем формы, пробивая в прямоугольнике дырку нужного вида, любой векторный редактор это умеет.

Но в использовании таких масок есть небольшой нюанс. К сожалению, браузеры до сих пор не слишком точно рассчитывают размеры и расположение фона при масштабировании объектов, особенно это заметно на мобильных устройствах, как с растровой, так и с векторной графикой. Решить эту проблему можно, добавив дополнительно один или несколько пикселей фоновой заливки с каждой из сторон. В случае с SVG эти дополнительные пиксели могут лежать за пределами видимой области и всё равно будут нам помогать.

Поэтому размеры нашей маски будут на 3 пикселя больше с каждой стороны, при том же viewBox 25×25 пикселей. Почитать, как формируется кривая Безье в атрибуте d для элемента <path>, можно у Ярослава Карандашева. А мы просто экспортировали её из векторного редактора.

	<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25">
	    <path fill="#FFF" d="m-3-3v31h31v-31h-31zm12 20v-9l8 4.5-8 4.5z"/>
	</svg>

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

Основной цвет активной кнопки мы укажем в background-color, а в background-image перечислим через запятую маску и два градиента. Здесь всё наоборот — кто первый, тот и выше.

	.button.play.active {
	    background-color:#1ABEF1;
	    background-image:url(images/play-mask.svg),
	        linear-gradient(105deg, #0020FF 38%, rgba(26, 190, 241, 0) 49%),
	        linear-gradient(200deg, #0020FF 41%, rgba(26, 190, 241, 0) 52%);
	    }

Все необходимые префиксы для работы градиентов (-webkit, -moz и -o) перечислены в итоговом файле. Но это не единственная разница: градиенты с префиксами должны получить ещё и другие значения градусов. Дело в том, что с момента внедрения градиентов в браузерах, спецификация изменилась и если раньше значения отсчитывались от трёх часов (представьте циферблат часов) и против часовой стрелки, как на уроках геометрии, то сейчас отсчёт идёт от полудня и по часовой стрелке, что естественнее для CSS в целом. Значит по старому синтаксису повороты будут -15deg и -110deg, а по новому, без префикса, 105deg и 200deg, соответственно.

В итоге мы получим ту же самую роскошную кнопку, но всего с одним SVG-файлом для маски и с оформлением прямо в CSS: play-mask.html. Вы можете попробовать модифицировать этот пример и убедиться, насколько удобно работать с иконкой прямо в CSS. Все примеры, использованные в этой заметке, можно загрузить одним архивом: play.zip (17 КБ)

Понравилась кнопка? Можно сделать лучше? Не стесняйтесь, расскажите в комментариях.

Комментарии

69

Данная задача проще и эффективнее решается с помощью шрифта в 1 символ

Юра, кроме того, что шрифт ещё нужно нарисовать и сохранить в N форматах, и того, что градиент внутри символа не нарисуешь — наверное проще. Но это не решает всей задачи, речь шла о том, чтобы сделать иконку с тенью внутри.

Вадим, это потрясающе. Спасибо за ваше копание в SVG. Каким редактором пользовались для SVG?

Наверное, это сильно зависит от браузера, но вариант на SVG выглядит гораздо лучше (Хром на маке). В варианте на CSS градиенты заметно полосатые.

Юра, я понимаю, что такое веб-шрифты и что их можно (и модно) использовать для таких целей. Но вот смотрю я на сайте с этими стоковыми иконками, а они все плоские, однообразные и зачастую страдают какими-то кроссбраузерными или кроссплатформенными проблемами. Я сам для нарисовал для Shower иконку внешней ссылки, но она текстовая. На мой взгляд, рядом с текстом таким иконкам и место.

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

Михаил, экспортирую из Illustrator CS6, несмотря на кучу мусора, там сносный экспорт.

ты ведь заметил что шрифт — маска, который можно положить на любой плосикй фон и из css рулить и фоном и градиентами под ним?

p.s. пока что задачу которую ты описал легче решить шрифтом — это ровно то что я сказал, не более :)

Юра, да, теперь вижу. Но сложность создания шрифта не сравнится с простотой создания SVG. Вот мой главный аргумент.

Треугольник около правил форматирования над полем отправки комментария так и просит, чтобы ты его сделал в SVG. :)

А вообще, отличная статья. SVG масштабируем, гибок, прекрасен, и применять его надо было еще вчера.

Кто боится использовать SVG из-за отсутствия поддержки в старых браузерах, советую взглянуть на Raphaël (http://raphaeljs.com), который использует VML для IE8<, или попробовать сделать собственную VML/SVG вилку, если вы такой же любитель велосипедов, как я.

И насчет масок: для хороших браузеров можно использовать Canvas, а для старых — все тот же VML.

Денис, треугольник у правил форматирования уйдёт вместе со старым дизайном, когда я допилю новый (в августе?), и в нём точно не останется места растровой графике ;)

Денис, треугольник у правил форматирования уйдёт вместе со старым дизайном, когда я допилю новый (в августе?), и в нём точно не останется места растровой графике ;)

Вадим, новый дизайн это конечно здорово, но лучше бы вы статьи чуть почаще писали, чем так часто обновляли блог. А то скоро будет 1 статья, на одно обновление блога с такими темпами (

E {
background:url(image.png) no-repeat;
background:url(image.svg) no-repeat;
}

Браузер, который не поймёт векторную картинку, просто вернётся на одно правило назад и применит растровую…

К сожалению, это вовсе не так, в чём можно легко убедится на http://files.myopera.com/GreLI/tests/svg-test.html. Второе правило просто перебивает первое, браузер всегда загружает SVG, и если поддержки нет (IE8–, Firefox 3.6–, Andoid 2.3–), ничего не показывает.

К сожалению, с масштабированием тоже большие проблемы. Опера, Firefox в сложных случаях, и IE10 в режиме метро масштабируют SVG на фоне как растровое изображение. К тому же в Опере при этом неправильно считаются размеры, а также в IE10 в сложных случаях при загрузке страницы не со 100% масштабом (десктоп и метро). Под сложными случаями я подразумеваю SVG-картинки, где используются заготовки контуров с помощью dev, symbol и use.

и тут такой я со шрифтом! :)

Юра, да, теперь вижу. Но сложность создания шрифта не сравнится с простотой создания SVG. Вот мой главный аргумент.

действитеьно, мы же сайты за пять минут делаем :)

Юра, вы, как Яндекс, делаете сайты не за пять минут. Но зато иконка у вас одна (условно) и на все сервисы, а если каждый проект с новым дизайном и для каждой штуки нужно делать шрифт, то история получается грустной.

GreLI, твоё замечаение про фолбек в работе, скоро выпущу обновление поста.

Яндекс тут не при чем. Что за манера, стоит написать что-нибудь, тебя сбрасывают в рамки компании :) и еще нерепрезентативным называют.
В данном случае svg не позволяет управлять цветом фона на котором лежит не изменяя файл. Изменение файла = перевыкладка или перегенерация dataUrl. Шрифт более гибкий для такой цели.
SVG кажется подходит только для рисования комиксов пока что, как бы это ни было неприятно осознавать :(

…К сожалению, это не сработает в Firefox 3.6 и в старых браузерах на движке Webkit, которые стоят на системах вроде Android 2.2 (как на моём HTC Desire), поэтому для них будет уместнее использовать определение поддержики SVG с помощью Modernizr…

С обычным определением поддержки SVG с помощью Modernizr тоже есть проблемы. Дело в том, что Firefox 3.6 поддерживает SVG, но только через <object>. Таким образом, обычная проверка даст положительный результат, но SVG на фоне всё равно не будет работать.

Обойти можно, проверяя, например, на Inline SVG. В каких-то браузерах будет ложный отрицательный ответ, но это уже очень малая доля.

P.S. Firefox 3.6 используют есть где-то 1,5% пользователей.

GreLI, ух ты выкопал эту тему :)
1.72%, за последний месяц упала на 0,67%

Что за манера, стоит написать что-нибудь, тебя сбрасывают в рамки компании

Чья бы корова мычала, Юра, чья бы корова… ;) Но в словах про перевыкладку и перегенерацию есть смысл.

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

Остаётся только спросить у всех: когда последний раз вы тестировали свою вёрстку в Firefox 3.6?

pepelsbey, для этого тестировщики есть :-), А вообще я в сомнениях, делать ли для него закгруглённые уголки и пр. — они там ещё через префиксы. (-webkit префиксы уже давно можно не использовать).

GreLI, ну в крайних случаях да, типа кнопки плэй. Обчно это стрелочки или другая декорация, тогда пофигу

pepelsbey, я давно не смотрел у меня внутренняя аудитория сейчас, но ребята тестируют http://clubs.ya.ru/ui/replies.xml?item_no=2 перестаем смотреть после < 0.5%

А вот, наверное, более распространённый случай: как лучше делать логотяп, изменяющий цвет при наведении (на всех страницах кроме клавной)?

1. Твой способ — с маской.
2. Ховер внутри SVG.
3. Два SVG-файла разного цвета :)
4. Другой способ.

Ну и, конечно, хотелось бы, чтобы работали плавные переходы.

Мое мнение, у масок слишком много НО, чтобы использовать для такого простого случая, поэтому я бы сделал два svg-файла разного цвета или два path внутри одного svg. Для плавного перехода можно использовать opacity + transition.

Если через js, можно менять атрибуты color и fill у svg-элемента или элементов внутри него (типа path и т.д.).

Артём, если это возможно, я бы попробовал маску, чтобы сократить количество ресурсов и упростить поддержку. Либо SVG-спрайт фиксированных размеров, без viewBox.

Роман, я ждал именно такого комментария от тебя :) Делать треугольники на CSS — дело нехитрое, но любая чуть более сложная иконка возвращает нас к SVG или шрифту.

Да, именно потому я и не написал о том, что мой вариант лучше :) Согласен, что как только нужна будет звёздочка, или блок в форме кошки, то CSS тут не прокатит уже.

Мне кажется рано внедрять svg в свои сайты, а про шрифты из иконок лучше вообще забыть. Шрифты не только несемантичны, но и в пиксель не попадают, хотя насчёт pixel-perfect графики тоже самое касается и svg. Во всех примерах треугольник рендерится по саб-пикселям, левая сторона смазана. Ещё одна причина (не особо веская) почему лучше не использовать svg для retina-дисплеев заключается в другой настройке отображения элементов. К примеру есть тень box-shadow: inset 0 1px #fff; так вот на практике выявлено что для retina лучше всего использовать такую же однопиксельную тень, иначе эффект теряется.
Предположу что бум svg случится когда спецификация начнёт поддерживать все режимы наложения слоёв из фотошопа, появится уже наконец официальный экспортёр и импортёр в фотошоп (а большинство макетов делают именно там), ну и браузеры всю эту охапку будут нормально пережёвывать.
Технология отличная, но с текущим уровнем реализации я бы не стал её применять на продакшене.

CyberAP, вы неправы. Веб-шрифты сами по себе не несут никакой смысловой нагрузки, поэтому не могут быть «несемантичными», вопрос в том, как именно их применять. Можно ведь заменять не просто случайные символы, а целые слова или элементы :before/after.

Вы правы, что со шрифтами сложно попасть в пиксельную сетку, но это не проблема для SVG. Если изначально рисовать векторые фигуры с привязкой к пиксельной сетке для всех прямых линий и использовать смещения 0,5 для косых, то при экспорте и применении графика будет идеально смотреться на пиксельных экранах. Главное применять её в том же виде, в котором она нарисована или кратно масштабировать. Все живые примеры к этой статье следуют этим правилам: 25px — 250px, и всё отлично. А картинки к статье не следуют, там 25px — 230px (из-за сетки блога), поэтому вы видите поплывший пиксел.

Режимы наложения слоёв — это отдельная история, имеющая мало общего с SVG, и всё это будет поддерживаться в CSS уже в ближайшее время с лёгкой руки Adobe.

И что странно, вы так и не привели ни одного аргумента, почему не стоит использовать SVG в продакшене.

Если изначально рисовать векторые фигуры с привязкой к пиксельной сетке

Умоляю, ткните носом в ссылку, где про это пишут. Хочу сделать свой icon font. Если что, использую Inkscape. Извините за оффтоп.

Ну мои главные аргументы такие: составные фигуры создать на svg слишком сложно, на одних полигонах далеко не уедешь, нужна всегда какая-то стилизация. Даже в примере чтобы сделать внутреннюю тень пришлось элемент три раза дублировать один и тот же элемент, а что если понадобится сделать сложный логотип в svg который состоит из нескольких элементов?

Про попадание в пиксель: вот открыл пример http://pepelsbey.net/pro/2012/07/uneasy-easy-button/play-plain.html
Левая сторона ОК, но вот правая выглядит размыто. Я честно открывал все иконки, но в пиксель попадали только те что размером 8 на 9.

Ещё проблема с поддержкой в браузерах, нет отдельного ресурса где можно было бы узнать в каком браузере какая версия SVG поддерживается, что работает, а что нет. Т.е. каждый раз что-то добавляя в SVG придётся это тестировать на всех браузерах, вместо того чтобы знать что 100% можно безопасно использовать. Если есть такой ресурс ткните меня носом, буду только благодарен :)

CyberAP, правая выглядит размыто ровно настолько, насколько вообще чёткой может быть диагональная линия, идущая по квадратным пикселам. Уровень размытия совершенно обычный. Понятное дело, чем ближе угол к 45°, тем незаметнее будет сглаживание. Но на HD-дисплеях вы это размытие не заметите.

Что касается полигонов, то никто не заставляет вас рисовать логотип руками с помощью кубиков и кружочков. Нарисуйте его в Illustrator, экспортируйте в SVG и вставьте на страницу, дел-то. Главное не использовать сложные фильтры и эффекты, но формы — пожалуйста.

Если говорить про кроссбраузерность, то я слышу, как вы жалуетесь, как это сложно. Ну, да — если бы вам вчера впервые показали CSS, то вы бы сказали, что это сложно и нет единого сайта, где всё можно посмотреть. Зато есть зоопарк браузеров, голова и умелые руки, чтобы всё выяснить самому и научиться использовать векторную графику самостоятельно, благо она того стоит.

Т.е. каждый раз что-то добавляя в SVG придётся это тестировать на всех браузерах, вместо того чтобы знать что 100% можно безопасно использовать.

А тестировать во всех браузерах так и так надо, не зависимо от того SVG мы делаем или нет. А в случае тестирования SVG это вообще элементарнейшая задача.

Что касается практики использования SVG на сайте. В данный момент работаю в ResumUP, где SVG используется в очень больших масштабах.
Из проблем, SVG все-таки ведет себя не совсем так, как весь остальной DOM. Также, если использовать сложную графику, то SVG упирается в проблему, что каждый примтив — это элемент DOM, при большом кол-ве элементов, браузер начинает сильно тупить. Плюс озвученные проблемы с субпиксельным рендерингом. В остальном он всем хорош.
Касательно шритов, у github сравнительно недавно была отличная статья, как они делали octoicons.

Зачем я все это говорю, в ответ на комментарий, что ни шрифты, ни SVG использовать нельзя. Можно и сервисы, которые стоят миллионы долларов их используют.

pepelsbey, согласен, энтузиазм наше всё. Я пытался внедрить SVG графику, но всё уткнулось в ограниченность возможностей SVG. Несомненно, если надо вывести какую-то фигуру с заливкой, то он идеально подойдёт; но как только дело доходит до эффектов - SVG уже не помощник.

@thought_sync, не совсем то, там про базовую поддержку, а я хотел узнать как полно поддерживается текущая спецификация http://www.w3.org/TR/SVG/
И SVG 1.2 http://www.w3.org/TR/SVG12/

Главное не использовать сложные фильтры и эффекты

Вот-вот, не используй то, не используй сё...

В качестве котраргумента к комиксу лого Google в SVG и в PNG

Но на самом деле, статья очень вдохновляющая, конечно, спасибо.

CyberAP, если посмотреть на весь список параметров, там довольно много параметров типа inline-SVG, фильтров и т.д.

pepelsbey, спасибо за статью. Подскажите, пожалуйста, учебник по SVG, кроме спецификации.

Может я и не прав, но я считаю что SVG пока что - недоформат. Как бы ты не аргументировал.. простоты создания SVG нет. Даже в иллюстраторе. Ну ничего простого там нет.

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

Тем не менее я считаю что этому формату нужно уделять внимание.. потому как гибкость и.. как бы это по русски... scalable...

Но пока что я считаю использование SVG как чисто " на свой страх и риск" и "если хочется повозиться" :)

Я тут добавлю короткую, но важную мысль.

Для начала: да, у SVG есть проблемы и с точки зрения кроссбраузерности, и с точки зрения очень ограниченного количества инструментов, которыми можно было бы этот самый SVG пилить.

Но.

Тут аналог проблемы курицы и яйца: пока нет инструментов и кроссбраузерности, разработчики не особо стремятся использовать SVG, но и пока не будет достаточного числа разработчиков, SVG особо развиваться не будет.

Чтобы SVG развивался, надо его использовать, экспериментировать с ним, надо репортить баги, писать статьи (как это сделал Вадим), писать свои инструменты и участвовать в разработке имеющихся опенсорсных.

Говорить же: «да ну, технология ещё сыра, не надо её использовать» — бессмысленно и вредно. Надо разглядеть и понять перспективы, которые есть у SVG (а их много: от SVG-стеков, до использования SVG в качестве border-image), надо понять, что это потенциально может быть очень мощным инструментом, который мог бы быть постоянным спутником верстальщика.

Я считаю что использование "шрифтовых иконок" это очень неправильно! Шрифт это текст, а иконка это не текст а изображение ;) SVG очень хорошо подходит для иконок в любых пользовательских интерфейсах. Вот тут были интересно реализованы SVG-спрайты, жаль не везде работает.

SVG используется такими компаниями как Google, Apple, Facebook, New York Times и так далее. Официальный импорт/экспорт из Эдоби Фотошопа это Эдоби Иллюстратор. У него очень неплохой экспорт, и будет только лучше. Все браузеры работают над улучшением поддержки SVG и надо признать, что она довольно неплохая уже сейчас.
Но нет, всегда есть группа которая будет говорить, что что-то там сырое и не готово.
Да всё сырое, начиная с HTML. В том и отличатся профессионал от любителя, что он может использовать то, что ещё “сырое”. HTFU!

Роман Комаров, безусловно! Нужно использовать и экспериментировать.. я же сразу написал что "я считаю"... и так же написал "на свой страх и риск" :) Я не противник SVG, наоборот, просто на данный момент я считаю его слишком сырым.

Но справедливости ради добавлю, имел опыт работы со шрифтами.. извините затрахался с конвертациями..

SVG замучился с обработкой..

а Кроссбраузерность это не проблема, так как если будет мейнстрим, будет и она.

Ярослав, если бы в вашем блоге была страчка о вас или хотя бы в подвале упоминалось ваше настоящее имя, было бы гораздо проще. А вы «Карандашев» или «Карандашёв»?

Нифига себе, новая статья. Читаю вас с удовольствием, спасибо за труд!

В опере (сейчас в 12 под mac наблюдаю, но насколько я помню, проблема во всех воспроизводится) полная беда случается, если изменить масштаб страницы. В ваших примерах воспроизводится. И то же самое происходит, если растягивать картинку не через viewBox, а через background-size.
Из-за этого бага (и из-за проблем в FF 3.6) недавно пришлось отказаться от svg в пользу шрифта :(

чтобы передать цвет в SVG, предлагаю сделать элементарную обёртку на PHP
и никаких масок не надо

как Lea Verоu для RGBA сделала
http://lea.verou.me/rgba.php/

тут даже проще будет

Иван, продемонстрируйте, пожалуйста, что вы имеете в виду, я что-то не очень понял, как RGBA.php здесь применим.

на вскидку, с минимальной проверкой входных данных

<?
header("Content-Type:    image/svg+xml");
$color=isset($_GET['color'])?("#".$_GET['color']):"#000";
?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25">
    <polygon fill="<?=$color?>" points="9,8 17,12.5 9,17"/>
</svg>

RGBA.php - это просто пример скрипта генерирующего png по входным параметрам

Иван, теперь вижу — для статической передачи цвета подходит, но меня больше волнует динамическая :\

Комбинируя со стилями и :target можно будет выбирать одну из зашитых цветовых схем.
Но когда это ещё будет во всех браузерах?
Пока работает только в firefox.

svg.php

<?
header("Content-Type:    image/svg+xml");
$color=isset($_GET['color'])?("#".$_GET['color']):"#00000";
$color1=isset($_GET['color1'])?("#".$_GET['color1']):"#ff0000";
$color2=isset($_GET['color2'])?("#".$_GET['color2']):"#ffff00";
?>

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25">
<style type="text/css">
.polygon{
    fill:<?=$color?>;
}
#color1:target .polygon{
    fill:<?=$color1?>;
}
#color2:target .polygon{
    fill:<?=$color2?>;
}

</style>
<g id="color1">
<g id="color2">
    <polygon class='polygon' points="9,8 17,12.5 9,17"/>
</g>
</g>
</svg>

test.html


<style>
div{
height : 500px;
background:url("svg.php#color2");
}
</style>
<div>
</div>

Иван, да, SVG-стеки работают для фоновых изображений только в Firefox, в остальных они вроде работают через <object>, это подходит в случае какого-нибудь логотипа, который должен меняться при наведении.

Чуть не забыл

header("Expires: ".date("r", time() + 3600 * 4));

В противном случае чревато новым запросом для каждого якоря. Но даже так, это пока ещё светлое будущее.

Не работает в ФФ 3.6. Если интересует, где берут такое старье - в debian stable.

Кроме rgba() можно ещё воспользоваться тем, что Firefox поддерживает background-clip как раз с 4-й версии:

background: url(image.png) no-repeat;
background: url(image.svg) no-repeat content-box rgba(0,0,0,0);