Стилизация SVG с помощью CSS. Возможности и ограничения

10.07.2019

Подготовил: Евгений Рыжков Дата публикации: 27.08.2010

Последнее обновление: 17.11.2010

Задача

Отобразить SVG-изображение на HTML-странице.

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

SVG через iframe

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

SVG через object

Ваш браузер не поддерживает формат SVG

Имеем: валидный чистый код, альтернативный текст, где можно снабдить пользователя инструкцией, что делать, если он не видит картинки (например, отправить на сайт нормального браузера или дать ссылку на плагин, установка которого ему поможет). Такое внедрение поддерживает прозрачность в SVG изображении (правда в IE тут проблема: прозрачные участки будут залиты белым). Из минусов: нет возможности влиять на изображения внешними скриптами (из HTML), только теми, которые находятся в самом SVG-файле.

Метод хорош для фоновых изображений или каких либо статичных картинок.

SVG через embed

Такой способ якобы позволяет взаимодействовать скриптам в HTML с содержимым SVG-файла (мне пока такого добиться не удалось). Для IE имеет атрибут wmode (), который поможет корректно отобразить прозрачные участки SVG-изображения. Атрибут pluginpage должен отправить пользователя, браузер которого не поддерживает SVG, на страницу плагина, который ему поможет. В реальности в чистом виде толку о этого атрибута ноль. Именно такой вариант рекомендует Adobe для корректной работы из SVG Viewer. Такой способ валидацию не пройдет.

Этот способ сейчас пользуется большой популярностью.

SVG в HTML коде

XHTML + SVG

  • следует обратить внимание на используемое пространство имен: xmlns:svg="http://www.w3.org/2000/svg"> ;
  • документ должен быть именно в xhtml формате (локально — это файл с расширением.xhtml)
  • с кроссбраузерностью у этого метода плохо. Особенно плоха реакция IE;
  • html код становится нереально грязным.

Сейчас этот метод лучше не использовать.

Заметка

IE, включая версии 8, не поддерживает SVG. В то время Microsoft активно продвигал свой формат — VML. Потому с этим браузером придется повозиться, чтобы увидеть и там SVG-изображение (об этом подробней в следующих статьях).

Светлое будущее

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

Дословно: масштабируемая векторная графика. МВГ? SVG! В векторных форматах хранится не само изображение, а инструкция по его построению по точкам и кривым.


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


�PNG IH�aV PLTE�������0� IDAcZ�d���� �W= S�3�o;���]P ���IEND�B`�~

Формат SVG тоже можно создавать и менять в редакторах графики, вроде Illustrator, Sketch или Inkscape. Но ещё он текстовый, а значит его можно открыть как HTML или CSS в любом редакторе кода.



Я вам больше скажу: SVG - это как отдельная HTML-страница. Когда вы вставляете SVG, вы, на самом деле, вставляете не просто картинку, а целую страницу. Со своей системой координат, вьюпортом, стилями, скриптами и удивительными особенностями.


Стилями и скриптами, Карл! Вот вам и простая картинка.


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


Первый и самый простой - элемент прямо в HTML-коде. Это в принципе самый эффективный способ загрузить любую картинку - браузеры заранее знают по HTML-коду, что она есть и начинают её подгружать.


Минус в том, что в таком SVG не будут работать скрипты и любые попытки взаимодействия с элементами внутри обречены. Файл будет как за стеклом: смотреть можно, а трогать нельзя. Хотя внутри всё остальное прекрасно работает, включая CSS-анимации.



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


Второй способ - фоновая картинка в CSS. Причём неважно, зададите вы его элементу, псевдоэлементу или контентом вставите - результат будет таким же, как с : за стеклом, но внутри что-то работает.


.picture { background-image: url(picture.svg); }

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


Третий способ, через , наконец-то выбивает стекло между страницей и внутренностями SVG-файла. Работают скрипты, взаимодействие, анимация - если они описаны внутри SVG. Между тегами можно вставить фолбэк, который покажется, если браузер не говорит на SVG.



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


За гибкость приходится платить: из-за того, что это уже не просто графика и там можно скриптовать, к такому способу предъявляются другие требования безопасности. Например, картинку с другого домена просто так уже не вставить.


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


Четвёртый способ заработал, когда браузеры переписали свои HTML-парсеры по новому стандарту и содержимое SVG-файлов стало можно вставлять прямо на страницу, как любые другие теги.


Квадрат

С таким SVG можно делать то же, что и с обычными HTML-элементами: стили, скрипты - ну, вы сами знаете. Можно, например, менять цвет заливки при наведении и описывать всё в общих стилях .


rect:hover { fill: #090; }

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


SVG гораздо больше, чем просто формат графики - это мы с вами уже поняли. Хотите закопаться глубже? Читайте статьи Сары Суайдан , это пока лучшее, из того, что есть. Все ссылки есть в описании к видео.


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

Видеоверсия

Продолжение предыдущей статьи “Стилизация SVG с помощью CSS - Часть 1”, посвященной формату векторной графики SVG.

Стилизация с помощью CSS

Между языками HTML и CSS существует четкая и ясная взаимосвязь: язык HTML предназначен для структуризации контента на странице; задача языка CSS - внешнее оформление этого контента . Формат SVG размывает четкие границы этой взаимосвязи. Например, формат версии SVG1.1 не нуждается в CSS для стилизации отдельных элементов SVG-объектов - для этой цели имеются так называемые презентационные атрибуты .

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

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

многоугольника в виде пятиконечной звезды:

В этом примере атрибуты

1 fill
, или , абсолютно не похожи на свои CSS-аналоги.

В формате SVG2 имеются несколько презентационных атрибутов , таких как

1 x
,
1 y
,
1 width
,
1 height
,
1 cx
,
1 cy
и некоторые другие, которые невозможно задать с помощью CSS в SVG1.1. Список новых SVG-атрибутов можно посмотреть по этой ссылке - SVG2 спецификация .

Другим способом стилизации SVG-элементов является использование для этой цели CSS-свойств. Точно также, как и в случае в HTML-элементами, CSS-свойства могут быть заданы с помощью inline-стиля:

Каскады стилей SVG

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

Презентационные атрибуты позиционируются как “авторские стилевые правила” и могут быть переопределены любыми другими определениями: внешними таблицами стилей, внутренними таблицами стилей или же inline-стилями.

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

Например, представленный ниже образец кода является кругом, написанным на SVG. Цвет заливки круга в виде атрибута

с помощью правила , , и . Замечания

Так как презентационные атрибуты имеют XML-синтаксис, то они чувствительны к регистру . Например, при задании цвета заливки SVG-элемента атрибут должен быть записан как

в ,
1
или внешние таблицы стилей.

На этом все.

Updated on March 26, 2015 gearmobile

Это сам Q & A из удобного кода, с которым я пришел.

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

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

Это вопрос:

17 ответов

Во-первых, используйте тег IMG в своем HTML, чтобы вставить SVG-графику. Я использовал Adobe Illustrator, чтобы сделать графику.

Это похоже на то, как вы вставляете обычный образ. Обратите внимание, что вам нужно установить IMG для класса svg. Класс "social-link" просто для примера. Идентификатор не требуется, но полезен.

Затем используйте этот код jQuery (в отдельном файле или встроенном в HEAD).

/* * Replace all SVG images with inline SVG */ jQuery("img.svg").each(function(){ var $img = jQuery(this); var imgID = $img.attr("id"); var imgClass = $img.attr("class"); var imgURL = $img.attr("src"); jQuery.get(imgURL, function(data) { // Get the SVG tag, ignore the rest var $svg = jQuery(data).find("svg"); // Add replaced image ID to the new SVG if(typeof imgID !== "undefined") { $svg = $svg.attr("id", imgID); } // Add replaced image classes to the new SVG if(typeof imgClass !== "undefined") { $svg = $svg.attr("class", imgClass+" replaced-svg"); } // Remove any invalid XML tags as per http://validator.w3.org $svg = $svg.removeAttr("xmlns:a"); // Replace image with new SVG $img.replaceWith($svg); }, "xml"); });

Что делает вышеприведенный код, это искать все IMG с классом "svg" и заменять его встроенным SVG из связанного файла. Массивным преимуществом является то, что он позволяет использовать CSS для изменения цвета SVG сейчас, например:

Svg:hover path { fill: red; }

Код jQuery я написал также порты по исходному идентификатору и классам изображений. Итак, этот CSS тоже работает:

#facebook-logo:hover path { fill: red; }

Social-link:hover path { fill: red; }

Svg path { fill: #000; }

$(document).ready(function() { $("img").each(function() { var $img = jQuery(this); var imgURL = $img.attr("src"); var attributes = $img.prop("attributes"); $.get(imgURL, function(data) { // Get the SVG tag, ignore the rest var $svg = jQuery(data).find("svg"); // Remove any invalid XML tags $svg = $svg.removeAttr("xmlns:a"); // Loop through IMG attributes and apply on SVG $.each(attributes, function() { $svg.attr(this.name, this.value); }); // Replace IMG with SVG $img.replaceWith($svg); }, "xml"); }); });

Если вы можете включить в свою версию файлы (включая PHP или включить через ваш CMS), вы можете добавить SVG-код и включить его на свою страницу. Это работает так же, как вставка источника SVG на страницу, но делает очистку страницы более чистым.

Преимущество состоит в том, что вы можете нацелить части своего SVG с помощью CSS для зависания - не требуется javascript.

Вам просто нужно использовать правило CSS следующим образом:

#pathidorclass:hover { fill: #303 !important; }

Обратите внимание, что бит!important необходим для переопределения цвета заливки.

Теперь вы можете использовать свойство filter CSS в большинстве современных браузеров (включая Edge, но не IE11). Он работает с изображениями SVG, а также с другими элементами. Вы можете использовать hue-rotate или invert для изменения цветов, хотя они не позволяют изменять разные цвета независимо друг от друга. Я использую следующий класс CSS, чтобы показать "отключенную" версию значка (где оригинал представляет собой изображение SVG с насыщенным цветом):

Disabled { opacity: 0.4; filter: grayscale(100%); -webkit-filter: grayscale(100%); }

Это делает его светло-серым в большинстве браузеров. В IE (и, возможно, Opera Mini, который я не тестировал), он заметно угасает с помощью свойства непрозрачности, которое по-прежнему выглядит довольно хорошо, хотя оно не серое.

Здесь приведен пример с четырьмя различными классами CSS для значка колокола Twemoji : оригинал (желтый), вышеперечисленный класс "отключен", hue-rotate (зеленый) и invert (синий).

Twa-bell { background-image: url("https://twemoji.maxcdn.com/svg/1f514.svg"); display: inline-block; background-repeat: no-repeat; background-position: center center; height: 3em; width: 3em; margin: 0 0.15em 0 0.3em; vertical-align: -0.3em; background-size: 3em 3em; } .grey-out { opacity: 0.4; filter: grayscale(100%); -webkit-filter: grayscale(100%); } .hue-rotate { filter: hue-rotate(90deg); -webkit-filter: hue-rotate(90deg); } .invert { filter: invert(100%); -webkit-filter: invert(100%); }

@Drew Baker дал отличное решение для решения проблемы. Код работает правильно. Тем не менее, те, кто использует AngularJs, могут найти большую зависимость от jQuery. Следовательно, я подумал, что неплохо вставить для пользователей AngularJS код, следующий за решением @Drew Baker.

Метод AngularJs одного и того же кода

1. Html: используйте тег ниже в файле html:

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

"use strict"; angular.module("myApp") .directive("svgImage", ["$http", function($http) { return { restrict: "E", link: function(scope, element) { var imgURL = element.attr("src"); // if you want to use ng-include, then // instead of the above line write the bellow: // var imgURL = element.attr("ng-include"); var request = $http.get(imgURL, {"Content-Type": "application/xml"}); scope.manipulateImgNode = function(data, elem){ var $svg = angular.element(data); var imgClass = elem.attr("class"); if(typeof(imgClass) !== "undefined") { var classes = imgClass.split(" "); for(var i = 0; i < classes.length; ++i){ $svg.classList.add(classes[i]); } } $svg.removeAttribute("xmlns:a"); return $svg; }; request.success(function(data){ element.replaceWith(scope.manipulateImgNode(data, element)); }); } }; }]);

Any-class-you-wish{ border: 1px solid red; height: 300px; width: 120px }

4. Единичный тест с карма-жасмином:

"use strict"; describe("Directive: svgImage", function() { var $rootScope, $compile, element, scope, $httpBackend, apiUrl, data; beforeEach(function() { module("myApp"); inject(function($injector) { $rootScope = $injector.get("$rootScope"); $compile = $injector.get("$compile"); $httpBackend = $injector.get("$httpBackend"); apiUrl = $injector.get("apiUrl"); }); scope = $rootScope.$new(); element = angular.element(""); element = $compile(element)(scope); spyOn(scope, "manipulateImgNode").andCallThrough(); $httpBackend.whenGET(apiUrl + "me").respond(200, {}); data = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; $httpBackend.expectGET("/icons/icon-man.svg").respond(200, data); }); afterEach(function() { $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); it("should call manipulateImgNode atleast once", function () { $httpBackend.flush(); expect(scope.manipulateImgNode.callCount).toBe(1); }); it("should return correct result", function () { $httpBackend.flush(); var result = scope.manipulateImgNode(data, element); expect(result).toBeDefined(); }); it("should define classes", function () { $httpBackend.flush(); var result = scope.manipulateImgNode(data, element); var classList = ["svg"]; expect(result.classList).toBe(classList); }); });

Я понимаю, что вы хотите выполнить это с помощью CSS, но просто напоминание на случай, если это маленький, простой образ - вы всегда можете открыть его в Notepad++ и изменить путь /whatelement fill:

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

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

Я написал директиву для решения этой проблемы с помощью AngularJS. Доступно .

Он заменяет элемент SVG после его рендеринга и помещает его внутри элемента div , что делает его CSS легко изменчивым. Это помогает использовать один и тот же файл SVG в разных местах, используя разные размеры/цвета.

Использование прост:

После этого вы можете легко:

Svg-class svg { fill: red; // whichever color you want }

Здесь нет кода рамки, только чистый js:

Document.querySelectorAll("img.svg").forEach(function(element) { var imgID = element.getAttribute("id") var imgClass = element.getAttribute("class") var imgURL = element.getAttribute("src") xhr = new XMLHttpRequest() xhr.onreadystatechange = function() { if(xhr.readyState == 4 && xhr.status == 200) { var svg = xhr.responseXML.getElementsByTagName("svg"); if(imgID != null) { svg.setAttribute("id", imgID); } if(imgClass != null) { svg.setAttribute("class", imgClass + " replaced-svg"); } svg.removeAttribute("xmlns:a") if(!svg.hasAttribute("viewBox") && svg.hasAttribute("height") && svg.hasAttribute("width")) { svg.setAttribute("viewBox", "0 0 " + svg.getAttribute("height") + " " + svg.getAttribute("width")) } element.parentElement.replaceChild(svg, element) } } xhr.open("GET", imgURL, true) xhr.send(null) })

Здесь версия для knockout.js на основе принятого ответа:

Важно: Это действительно требует jQuery для замены, но я подумал, что это может быть полезно для некоторых.

Ko.bindingHandlers.svgConvert = { "init": function () { return { "controlsDescendantBindings": true }; }, "update": function (element, valueAccessor, allBindings, viewModel, bindingContext) { var $img = $(element); var imgID = $img.attr("id"); var imgClass = $img.attr("class"); var imgURL = $img.attr("src"); $.get(imgURL, function (data) { // Get the SVG tag, ignore the rest var $svg = $(data).find("svg"); // Add replaced image ID to the new SVG if (typeof imgID !== "undefined") { $svg = $svg.attr("id", imgID); } // Add replaced image classes to the new SVG if (typeof imgClass !== "undefined") { $svg = $svg.attr("class", imgClass + " replaced-svg"); } // Remove any invalid XML tags as per http://validator.w3.org $svg = $svg.removeAttr("xmlns:a"); // Replace image with new SVG $img.replaceWith($svg); }, "xml"); } };

Затем просто примените data-bind="svgConvert: true" к вашему тегу img.

Это решение полностью заменяет тег img SVG, и любые дополнительные привязки не будут соблюдаться.

Существует библиотека с открытым исходным кодом под названием SVGInject, которая использует атрибут onload для запуска инъекции. Проект GitHub можно найти на странице https://github.com/iconfu/svg-inject

Ниже приведен минимальный пример использования SVGInject:

После загрузки изображения onload="SVGInject(this) вызовет инъекцию, а элемент будет заменен содержимым SVG файла, указанного в атрибуте src .

Он решает несколько проблем с инъекцией SVG:

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

Элементы автоматически внедряют их. Если вы добавляете SVG динамически, вам не придется беспокоиться о вызове функции впрыска снова.

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

SVGInject - это простой Javascript и работает со всеми браузерами, поддерживающими SVG.

Если у нас есть большее количество таких svg-изображений, мы также можем воспользоваться файлами-шрифтами.
Такие сайты, как https://glyphter.com/ , могут получить файл шрифтов из наших svgs.

например.

@font-face { font-family: "iconFont"; src: url("iconFont.eot"); } #target{ color: white; font-size:96px; font-family:iconFont; }

Поскольку SVG - это в основном код, вам нужно просто содержимое. Я использовал PHP для получения контента, но вы можете использовать все, что захотите.

Затем я печатал содержимое "как есть" внутри контейнера div

Чтобы финализировать правило для контейнеров SVG childs на CSS

Fill-class > svg { fill: orange; }

Я получил эти результаты с помощью значка материала SVG:

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

/** * A jQuery plugin that loads an svg file and replaces the jQuery object with its contents. * * The path to the svg file is specified in the src attribute (which normally does not exist for an svg element). * * The width, height and class attributes in the loaded svg will be replaced by those that exist in the jQuery object"s * underlying html. Note: All other attributes in the original element are lost including the style attribute. Place * any styles in a style class instead. */ (function ($) { $.fn.svgLoader = function () { var src = $(this).attr("src"); var width = this.attr("width"); var height = this.attr("height"); var cls = this.attr("class"); var ctx = $(this); // Get the svg file and replace the element. $.ajax({ url: src, cache: false }).done(function (html) { let svg = $(html); svg.attr("width", width); svg.attr("height", height); svg.attr("class", cls); var newHtml = $("").append(svg.clone()).html(); ctx.replaceWith(newHtml); }); return this; }; }(jQuery));

В html укажите элемент svg следующим образом.

Подготовка SVG для использования в вебе это очень простой процесс, не сложнее экспорта JPEG или PNG . Используйте любой привычный для вас графический редактор (Illustrator, Sketch, Inkscape [бесплатен], и тому подобное [или даже Photoshop, если вы используете слои с формами]) с тем размером изображения, который вы планируете использовать. Обычно я работаю в Иллюстраторе, поэтому я объясню некоторые способы подготовки файлов в этой программе, но вообще они применимы и для любой другой программы. Вам, возможно, стоит перевести текст в кривые, поскольку шрифт, скорее всего, будет неправильно отображаться, если, конечно, вы не планируете стилизовать их с помощью веб-шрифта, используемого на странице (что возможно!). Не стоит также превращать все объекты в единые формы, особенно если у вас есть обводка, которой необходимо будет управлять на странице, тем более преобразование объектов зачастую не уменьшает размер файла. Любые имена, присвоенные группам или слоям, будут добавлены к SVG как ID элемента. Это довольно удобно для стилизации, но немного увеличит общий размер файла.

Перед тем как сделать экспорт, необходимо проверить, все ли изображения находятся в целочисленной пиксельной сетке (то есть, например не 23.3px × 86.8px ). В противном случае скорее всего изображению не будет хватать чёткости и часть изображения обрежется. В Иллюстраторе это можно сделать следующим образом: Object > Artboards > Fit to Artwork Bounds . Затем жмём save as и выбираем SVG , и оставляем настройки по умолчанию. Здесь можно сделать небольшую оптимизацию, но на самом деле не стоит, так как далее мы будем применять разные улучшающие приёмы, поэтому сейчас мы не будем тратить впустую время на эти настройки.

Приёмы для уменьшения размеров файла.

(Смотрите по оптимизации)

Чтобы добиться наименьшего размера SVG , логично будет удалить из него всё лишнее. Наиболее известная и полезная программа (по крайней мере я так думаю) для обработки SVG это SVGO . Она удаляет весь не нужный код. Но! Будьте внимательны используя эту программу, если планируете управлять SVG при помощи CSS / JS , так как она может слишком сильно почистить код, что затруднит дальнейшие изменения. Удобство SVGO ещё и в том, что её можно включить в процесс автоматической сборки проекта, но можно также использовать GUI если хочется.

Разбираясь подробнее с правильным удалением всего ненужного, мы можем сделать ещё кое-что в графическом редакторе. Сперва нужно убедиться, что используется настолько мало контуров/форм, насколько это возможно, так же как и точек на этих контурах. Можно объединять и упрощать всё, что поддаётся упрощению, и удалить все ненужные точки. В Иллюстраторе есть плагин VectorScribe с инструментом Smart Remove Brush Tool , который поможет удалить точки и при этом оставить общую форму той же.

Предварительная оптимизация

Smart Remove Brush Tool удалил точки

Дальше будем увеличивать изображение. В Иллюстраторе удобно включить просмотр с пиксельной сеткой View > Pixel Preview и проверить, как располагаются контуры. Чтобы разместить контуры по сетке, потребуется немного времени, но эти усилия окупятся и позволят добиться более чёткого рендеринга (лучше обратить на это внимание заранее).

Точки вне сетки

Выравнивание по сетке

Если есть два и более объекта для выравнивания, то стоит удалить все ненужные перекрытия. Иногда даже если контуры тщательно выровнены, может быть видна тонкая белая линия. Чтобы предотвратить такое, можно немного наложить объекты друг на друга в местах перекрытия. Важно: в SVG z-index имеет определённый порядок, который зависит от объекта, находящегося снизу, поэтому стоит поместить верхний объект в нижнюю часть файла в коде.

И, наконец, последнее, но немаловажное, то, о чём обычно забывают - это активировать gzip сжатие SVG на вашем сайте в.htaccess файле.

AddType image/svg+xml svg svgz AddOutputFilterByType DEFLATE "image/svg+xml" \ "text/css" \ "text/html" \ "text/javascript" ... etc

В качестве примера того, насколько эффективна эта техника, я воспользуюсь оригинальным логотипом Breaking Borders и оптимизирую его таким образом: увеличиваю размер до того, каким он должен быть; приведу в порядок контуры; удалю максимально возможное количество точек; передвину точки на целочисленные пиксели; сдвину все области перекрытий и отправлю это всё в SVGO .

Оригинал: 1,413b После оптимизации: 409b

В итоге размер файла стал меньше на ~71% (и на ~83% при сжатии)

Похожие статьи