Use SVG

Поскольку «Макбук» у меня с «ретиной», я давно озаботился тем, чтобы продукт, разработкой которого я управляю, хорошо смотрелся и на «ретине» тоже. Я считаю за такими экранами будущее и не грех позаботиться об этом будущем уже в настоящем. Если уж и не внедрить везде, так хоть научиться верстать.

Одним из главных помощников в такой вёрстке является, без сомнения, формаг СВГ — формат векторной графики, который на данный момент поддерживают все распространённые браузеры (включая ИЕ, с девятой версии). Особенно приятно, что его можно включать прямо внутрь ХТМЛя, это очень удобно — если СВГ используется для кучи мелких значков на странице, то не будет лишних соединений с сервером — ведь всё грузится вместе с основным кодом.

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

К счастью, есть выход. СВГ — гибкая штука, в этом формате есть возможность использования частей изображения повторно. Первым шагом нужно определить тег-контейнер с необходимыми нам изображениями, по одному в теге symbol. У каждого из них будет собственный идентификатор, по которому мы ниже будем на них ссылаться:
<svg style="display:none">
    <symbol id="folder" viewBox="0 0 49.833 67.167">
        <!-- код не рабочий, только для примера -->
        <path d="M15.938,67.…"/>
        <path d="M3.59,30.531c…"/>
    </symbol>
    <symbol id="file" viewBox="0 0 49.833 67.167">
        <path d="M12.233c0.…"/>
        <path d="M3.28C2.76…"/>
    </symbol>
</svg>
Тут у нас два изображения — folder и file, на которые мы можем сослаться следующим образом:
<svg width="28" height="37">
    <use xlink:href="#folder"/>
</svg>

<svg width="28" height="37">
    <use xlink:href="#file"/>
</svg>
Таких вставок может быть сколько угодно и все они будут использовать одни и те же изображения, описанные в теге-контейнере. Остаётся даже возможность лёгкой настройки под себя, например, можно задать парочку классов и раскрасить часть изображения в разные цвета:
svg.green {
    fill: green;
}

svg.red {
    fill: red;
}
Классы можно повесить на ссылающиеся теги СВГ, жаль только этот способ полон ограничений. Кроме как в ФФ более избирательные селекторы использовать не удаётся — всё, что ниже тега use для таблицы стилей как будто не существует. Если и есть какой-то способ это починить, я его не нашёл.
5 комментариев
29 июля 2014 00:09

Свёртка в вебе

Я как-то пропустил момент, когда фильтры SVG стало можно накладывать на обычный тег IMG, а не на изображения внутри SVG же. Любопытные эффекты можно делать, например, можно наложить свёртку для выделения краёв и это будет работать:
<style>
    .edge {
        -webkit-filter: url(#edge);
        filter: url(#edge);
    }
</style>

<svg style="width: 0; height: 0">
<filter id="edge">
<feConvolveMatrix kernelMatrix="-1 -1 -1 -1  9  -1 -1  -1  -1" />
</filter>
</svg>

<image src="sample.jpg" class="edge">
Магические числа в матрице — специальное ядро.

Впрочем, и раньше можно было внедрить в ХТМЛ СВГ-картинку и наложить сверху фильтр, ничего особенного, но мороки чуть больше. При желании этот фильтр можно унести прямо в ЦСС при помощи data URI, но тогда он продублируется два раза — для префиксной и безпрефиксной формы (несмотря на уверения «Кэнайюз», «Хром» и «Сафари» отказались работать без префикса).

С таким возможностями, немудрено, что онлайновых «фотошопов» развелось, как грязи. Немного помучавшись с консолью, можно найти способ как поменять матрицу и это тоже будет работать! Например, вот так меняется число по центру (где у меня в примере девятка записана):
var arr = document.getElementById('edge').childNodes;

for (var i = 0; i < arr.length; i++) {
    if (arr[i].kernelMatrix) {
        arr[i].kernelMatrix.baseVal.getItem(4).value = newvalue;
        break;
    }
}
Осталось только соединить этот код с «крутилкой» и готов онлайн-фильтр «выделение краёв».
10 комментариев
26 мая 2014 07:41

SVG с fallback на не векторные форматы

Нравятся мне такие вещи. Алексей Тен из Яндекса придумал очень изящный способ внедрения СВГ в код с возвратом к растровому формату, если браузер не поддерживает СВГ:
<svg width="96" height="96">
    <image xlink:href="svg.svg" src="svg.png" width="96" height="96"/>
</svg>
Принцип виден из кода, я думаю, но я всё же расшифрую. Если браузеры поддерживают внедрение СВГ в ХТМЛ, то почти весь выше приведённый код будет для них значимым: кроме атрибута «src», его у тега СВГешного image не бывает и он будет отброшен. Соответственно, картинка загрузится из файла svg.svg.

Если же браузер СВГ в таком виде не понимает, то будет отброшен тег svg и атрибут «xlink:href», а тег image будет преобразован в img — это старая особенность браузеров, которой я тщетно пытался придумать применение. В этом случае будет загружен svg.png.

Я уже на сайте в одном месте использую этот трюк.
4 комментария
3 сентября 2013 08:55

SVG-спрайты

Вчера ночью, эксперементируя с различными способами внедрения картинок в ХТМЛ, я понял, что уже все браузеры (кроме «Оперы Мини»), понимают СВГ прямо в коде страницы. А это значит, можно отказаться от CSS-спрайтов в пользу того, что можно назвать «SVG-спрайтами»: SVG-спрайты (162.51КиБ) Принцип, в общем-то, тот же: большая картинка, из которой показывается фрагмент, только фрагмент задаётся не через ЦСС, а прямо в ХТМЛе.

Думаю, всем понятен код: в теге svg задаются размеры кусочка спрайта, в image обязательно нужно указать полные размеры картинки (для Ретины можно указать их в два раза меньше, если спрайт подготовлен к этому типу экранов), при помощи параметров x и y позиционируем в каком именно месте спрайта расположена наша картинка.

В комментариях спрашивают зачём это всё надо, чем это лучшее спрайтов в ЦСС.

Ну, во-первых, это семантичнее. Понимаю, для многих это не аргумент, поэтому у меня есть два других. Итак, во-вторых, браузеры стараются фоновые картинки (в спрайтах ЦСС используются именно они) грузить в последнюю очередь, это логично — как правило, они менее важны. В-третьих, фоновые картинки часто не отображаются при печати (у некоторых браузеров в настройках печати есть возможность вывести на печать с фоном, но по-умолчанию это отключено).
14 комментариев
14 июня 2013 08:56

Прозрачный фон SVG в Хроме и Сафари

Владислав Шкодин написал статью на «Хабре», где рассказал как ему удалось победить старый баг в движке WebKit — если вставить SVG с прозрачным фоном в тег OBJECT, что «Сафари» и «Хром» (до 8-й версии) зальют фон белым цветом.

Решение очень простое. Прямо внутри файла SVG, после тега svg нужно написать следующее:
<style>
    svg { -webkit-background-clip: text; }
</style>
Комментировать
21 декабря 2010 19:11

Мощь SVG и media queries

Вадим Макеев демонстрирует сейчас на фестивале «404» мощь SVG — картинка сама (через CSS media queries) изменяется для разных разрешений экрана, при масштабировании полноценное лого с текстом ужимается, текст сначала переносится, потом исчезает и остаётся один логотип.

Ребята, о таком применении SVG я даже и не думал, это очень круто.

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

Дополнено позднее: Вадим выложил слайды своего доклада (смотреть надо в «Опере»).
16 комментариев
10 октября 2010 14:18

SVG и браузеры

Поддержка браузерами SVG (15.68КиБ) Это таблица показывает насколько успешно проходят разные браузеры тесты SVG с сайта W3C (таблица с сайта CodedRead). В таблице, на мой взгляд, примечателен уровень поддержки SVG браузером IE 9 preview. Несмотря на уверения Microsoft о 100% уровне поддержки SVG, видно, что до идеала ещё делековато.

Я, правда, не понимаю что происходит и где правда. С одной стороны, таблица как бы говорит нам, с другой, на сайте IE9 написано следующее:

I want to thank the members in the W3C working groups that helped us develop these tests, the community members for providing valuable feedback on the tests, as well as the engineers on the IE team that made these possible
То есть тесты придуманы не самим Майкрософтом и наверняка в W3C их видели и одобрили. Где правда?
10 комментариев
18 марта 2010 00:02

Raphaël — графические эффекты на JS

«Raphaël» — небольшая (18 килобайт) библиотечка для быстрого применения графических эффектов (на сайте есть примеры отражения, вращения картинки и текста) и работы с графическими примитивами.

Работает под Safari 3.0+, FireFox 3.0+, Opera 9.50+, IE 6.0+. Используются SVG и VML. Как видно, большинство браузеров самых последних версий, именно из-за SVG. Надеюсь, автор со временем сделает degradation через Canvas, который работает медленее, но зато поддерживается предыдущими версиями Safari, FireFox и Opera.
16 комментариев
15 августа 2008 00:15

[Без заголовка]

Искал код для проверки - поддерживает ли браузер SVG, так и не нашёл ничего подходящего. Написал свой, делюсь:
function DetectSVG()
{
    if (navigator.mimeTypes != null && navigator.mimeTypes.length > 0)
    return navigator.mimeTypes["image/svg-xml"] != null

    var svg = 0
    /*@cc_on
    @if (@_jscript_version>4)
        try { svg = 1; new ActiveXObject("Adobe.SVGCtl") }
        catch (e) { return 0 }
    @end
    @cc_off @*/

   return svg
}
Первая половина кода проверяет наличие SVG-плагина в браузерах Opera, FireFox и иже с ними, вторая - проверяет наличие SVG-плагинов (выпускаются фирмами Adobe и Corel) к Internet Explorer.
Комментировать
16 декабря 2006 20:00

[Без заголовка]

Недавно возникла задача написания вертикального текста. Причём, именно текстом. В CSS3 есть свойство "writing-mode", но пока его никто, кроме Internet Explorer не поддерживает. Так что для остальных браузеров генерируется SVG с вертикальным текстом - изображение подключается при помощи протокола "data". Текст пишется дважды: для IE внутри div, для остальных браузеров (Safari, Mozilla/FireFox и Opera) - внутри атрибута тега "object". Дважды задаются и параметры текста (размер и имя шрифта).
<html>
<head>
    <style type="text/css">
        html>body .canv { display: none }
        .canv { filter: flipv() fliph(); writing-mode: tb-rl; width: 10px; height: 150px;
                font-size:12px; font-family: Arial; background-color: white }

        html>body .obj  { display: block; width: 10px; height: 150px }
        .obj { display: none }
    </style>
</head>

<body>
<div class="canv">Hello!</div>

<object class="obj" type="image/svg+xml"
    data="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'>
    <text x='-150' y='10' font-family='Arial' font-size='12' transform='rotate(-90)'>Hello!</text>
    </svg>">
</object>

</body>
</html>
Замечательно работает во всех соврененных браузерах, но есть недостатки: Safari до сих пор не умеет масштабировать SVG вместе с текстом (а SVG - это вектор!), а FireFox, масштабируя SVG, не увеличивает размеры object. Задание размеров в "pt" ситуацию не исправило.

Тег "object" задан фиксированных размеров, если нужно изменить размер, то параметры "x" и "y" у текста внутри SVG нужно будет исправить (процедура пересчёта значений очевидна, по-моему).

Конструкция "html>body" позволяет "прятать" CSS от Internet Explorer (включая седьмую версию), свойство background-color у класса "canv" проставлено для исправления ошибки отображения в Internet Explorer 6 и ниже - без этого свойства текст портится.
2 комментария
16 декабря 2006 20:00

SVG

Популярно о формате SVG (на русском) [ <<> ]
Комментировать
8 марта 2003 10:39

Tetris и SVG

Тетрис на EMCAScript (стандартизованный JavaScript) с использованием нового стандарта векторной графики SVG (XML-based). [ <<> ]
Для просмотра в Microsoft Internet Explorer требуется плагин [ <<> ]
2 комментария
7 марта 2003 17:17