Введение
SVG это язык XML разметки, схожий с XHTML, который может использоваться для рисования векторной графики, такой как та, что показана справа. Он может быть использован для создания изображения путём указания всех необходимых линий и форм, путём модификации уже существующих растровых изображений, или путём комбинации обоих. Изображения и их компоненты также могут быть трансформированы, собраны вместе, или отфильтрованы чтобы полностью изменить их внешний вид.
В 1999 году, после конкурса нескольких форматов, SVG был включён в W3C, однако полностью ратифицирован не был. SVG поддерживается всеми наиболее популярными браузерами. Недостатком использования SVG является его медленная загрузка . При этом SVG даёт некоторые преимущества, такие как наличие соответствующего DOM interface, и отсутствие необходимости в стороннем расширении. Использовать данное решение или нет, часто зависит от конкретного случая применения.
Базовые компоненты
В HTML имеются элементы для определения заголовков, параграфов, таблиц и т.п. В SVG, с другой стороны, имеются элементы для кругов, прямоугольников, и простых и сложных кривых. Простой SVG документ состоит из корневого элемента и нескольких основных форм, которые вместе обеспечивают построение рисунка. Кроме того, есть элемент , который используется для группировки нескольких основных форм вместе.
Начиная с этого, SVG изображение может стать сколь угодно сложным. SVG поддерживает градиенты, вращения, фильтры, анимации, взаимодействие с JavaScript, и т.п. Но все эти дополнительные возможности языка полагаются на этот относительно небольшой набор элементов, определяющих графическую область.
До начала работы
Существует ряд приложений для рисования, такие как Inkscape, который свободный и использует SVG в качестве родного файлового формата. Однако, это руководство полагается только на надёжный XML или текстовый редактор (на ваш выбор). Идея в том, чтобы обучить основам SVG тех, кто хочет понять его, и это лучше всего сделать, самостоятельно поработав с разметкой. При этом вы должны знать свою конечную цель. Не все программы просмотра SVG одинаковы, и поэтому существует высокий шанс того, что написанное для одного приложения не будет отображаться таким же образом в другом, просто потому что они поддерживают разные уровни SVG детализации или другую детализацию, которую вы используете наряду с SVG (такую как, JavaScript или CSS).
SVG поддерживается всеми современными браузерами и даже, в некоторых случаях, паре их устаревших версий. Достаточно полную таблицу поддерживающих браузеров можно найти в Can I use. Firefox поддерживает некоторый контент SVG, начиная с версии 1.5, и этот уровень поддержки растёт с каждым новым выпуском. К счастью, наряду с этим руководством, MDN может помочь разработчикам не отставать от изменений между Gecko и некоторыми другими основными реализациями.
Перед тем как начать, вы должны иметь основное понимание XML или другого языка разметки, такого как HTML. Если вы не очень знакомы с XML, ниже имеются некоторые рекомендации, которые следует иметь ввиду:
- Элементы и атрибуты SVG должны быть все введены в указанном регистре, поскольку XML обладает чувствительностью к регистру (в отличии от HTML).
- Значения атрибутов в SVG должны быть помещены внутри кавычек, даже если они являются цифрами.
SVG имеет довольно большую спецификацию. Это руководство охватывает только основы. После ознакомления с ними, тебе следует использовать Справочник SVG элементов и SVG интерфейсы, чтобы найти что-либо ещё при необходимости.
Особенности SVG
Начиная с рекомендации 2003 года, самой свежей «полной» версией SVG является версия 1.1. Она построена на SVG 1.0, но содержит также больше модульности для упрощения реализации. Второй выпуск SVG 1.1 стал Рекомендацией в 2011 году. «Полная» версия SVG 1.2 стала следующим главным выпуском SVG. Ей пришла на смену развивающаяся SVG 2.0, которая сейчас усиленно разрабатывается и следует схожему с CSS 3 подходу, в котором она разделяет компоненты в несколько свободно связанных специфирований.
Кроме полных рекомендаций SVG, рабочая группа при W3C ввела SVG Tiny и SVG Basic в 2003 году. Эти две версии нацелены главным образом на мобильные устройства. Первый, SVG Tiny, должен выдавать графические примитивы для небольших устройств с низкими возможностями. SVG Basic имеет много общего с полным SVG, но не включает те компоненты, что трудны для реализации или являются тяжёлыми для воспроизведения (как анимации). В 2008, SVG Tiny 1.2 стала Рекомендацией W3C.
Существовали планы для спецификации SVG Print, которая имела бы поддержку для множества страниц и улучшенное управление цветом. Эта работа была прекращена.
- « Предыдущая статья
- Следующая статья »
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 3 авг. 2023 г. by MDN contributors.
Как использовать svg в css
С чего начать Этот урок поможет вам начать использовать SVG.
Масштабируемая векторная графика (Scalable Vector Graphics — SVG) является языком разметки расширенным из XML (en-US) для описания двухмерной векторной графики. SVG по существу является графикой, так же, как XHTML — текстом.
SVG по своим возможностям приближается к запатентованной технологии Adobe Flash, но отличается от неё тем, что SVG является рекомендацией W3C (то есть, стандартом), и тем, что это формат, основанный на XML, в противовес закрытому двоичному формату Flash. Он явно спроектирован для работы с другими стандартами W3C, такими, как CSS, DOM (en-US) и SMIL.
SVG-графика и связанные с ней поведения определяются в текстовых XML-файлах, что означает, что их можно искать, индексировать, создавать сценарии и сжимать. Кроме того, это означает, что они могут быть созданы и отредактированы с помощью любого текстового редактора и программ для рисования.
SVG — открытый стандарт, разработанный World Wide Web консорциумом (W3C) с 1999 года.
Документация
Подробная информация о каждом элементе SVG.
Подробная информация о каждом атрибуте SVG.
Подробная информация по всему SVG DOM API.
Замечания и информация о том, как SVG реализован в Mozilla.
- Полнота реализации SVG в Firefox
- SVG — учебное руководство
- SVG в XHTML
Инструменты
- Набор для тестирования SVG
- Валидатор SVG (уже не работает)
- Больше инструментов…
- Другие ресурсы: XML (en-US), CSS, DOM (en-US), Canvas
Примеры
- Карты Google (маршруты поверх карты) и Документы Google (диаграммы в электронных таблицах)
- Меню из пузырьков на SVG
- Рекомендации по составлению SVG
- Обзор Проекта Mozilla SVG
- Часто задаваемые вопросы, касающиеся SVG и Mozilla
- Слайды и демонстрации с обсуждения SVG и Mozilla, проходившего на SVG Open 2009
- Использование SVG в качестве изображения (en-US)
- SVG анимация при помощи SMIL (en-US)
- Художественная галерея SVG
- Больше примеров (примеры SVG с carto.net)
Анимация и взаимодействие
Как и HTML, SVG имеет объектную модель документа (DOM) и события и всё это может быть доступно через JavaScript. Это позволяет разработчикам создавать роскошные анимации и интерактивные изображения.
- Некоторые захватывающие работы с использованием SVG на svg-wow.org
- Расширение Firefox (Grafox) для добавления поддержки анимации с использованием SMIL
- Интерактивное управление фотографиями
- Использование foreignObject из SVG для изменения HTML
- Анимация SVG спидометр
Карты, диаграммы, игры и эксперименты с 3D
В то время, как маленькие документы SVG могут серьёзно улучшить веб-контент, здесь представлены некоторые примеры тяжёлого использования SVG.
- Тетрис
- Connect 4
- Популяционная карта США
- jVectorMap (интерактивные карты для визуализации данных)
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 6 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
Используем SVG на сайте

Оставим за скобками вопрос о целесообразности использования SVG на сайте. Каждый сам для себя должен определить полезность этой технологии. Тем более что эта тема поднималась уже неоднократно.
Сейчас мы рассмотрим методы встраивания SVG, их плюсы и минусы, а так же возможности манипулирования элементами SVG.
Статья рассчитана в первую очередь на тех, кто до сих пор не использует векторную графику на своих сайтах, но очень хочет быть одной ногой в будущем настоящем.
Для любопытных сразу приведу сводную таблицу:
| Иконочный шрифт | IMG, background-image | Object | Inline | |
|---|---|---|---|---|
| CSS Манипуляции | Частично 1 | Нет | Частично 2 | Да |
| JS манипуляции | Частично 1 | Нет | Да | Да |
| SVG анимации | Нет | Да | Да | Да |
| Интерактивные SVG анимации | Нет | Нет | Да | Да |
1 Можно менять цвет, размер, выравнивание и прочее стили обычного текста
2 Стили должны быть прописаны или в самом SVG файле, или подключены внешним стилем в SVG в начале файла:
По правде говоря стили прописанные внутри SVG так же будут работать и при использовании тега IMG или background-image, но в этом нет никакого смысла.
Иконочный шрифт

Пример на codepen.io
- http://fontello.com
- https://icomoon.io/app
Плюсы и минусы такого подхода:
+ иконка ведет себя как символ шрифта, и все параметры настраиваются так же через CSS (размер, цвет, выравнивание и прочее);
+ единственный способ работающий в IE 8 без дополнительных манипуляций;
– все элементы SVG файла объединяются в один символ, поэтому управлять им при помощи CSS или JS можно только как единым целым;
– поддерживаются только одноцветные иконки;
– при сбое загрузки шрифта у пользователя либо не отобразятся иконки совсем, либо, при совпадении кодов иконок с символами юникода, отобразятся соответстующие символы.
SVG как OBJECT

К сожалению (или к счастью) codepen и jsfiddle блокируют загрузку внешних object в целях безопасности.
Встраивание выглядит следующим образом:
Объект встраивает элмемент атрибута data наподобие iframe, добавляя внутрь себя разметку подключаемого файла, поэтому к элементам можно обращаться при помощи JS, но не совсем обычным образом:
var object = document.getElementById("’object’"); //получаем элмент object var svgDocument = object.contentDocument; //получаем svg элемент внутри object var svgElement = svgDocument.getElementById("some_id_in_svg"); //получаем любой элемент внутри svg svgElement.setAttribute("fill", "black"); //меняем атрибуты выбранного элемента
Стоит отметить что в CSS стили для SVG элементов отличаются от стандартных, полный список стилей поддерживаемых SVG можно посмотреть тут.
SVG ведет себя не как обычное изображение, его нельзя непропорционально трансформировать, задавая ширину и высоту. Объект внутри будет занимать максимальную площадь и центрироваться в контейнере:

Но объект можно трансформировать используя CSS например так:
transform: scale(2, 1);
IE 8 и ниже не поддерживают SVG от слова «совсем» поэтому, если среди пользователей вашего сайта есть эта специфичная аудитория стоит озаботиться проверкой и заменой svg на растровое изображение. Сделать это можно множеством способов, например используя Modernizr добавлять .no-svg класс для body:
if (!Modernizr.svg)
.no-svg .icon
Плюсы и минусы такого подхода:
+ можно использовать внешний CSS файл для управления стилями;
+ поддерживаются SVG анимации и фильтры;
+ поддерживаются интерактивные анимации;
– для IE 8 и ниже необходима замена на растровое изображение.
SVG в IMG или background-image

Пример на codepen.io
Оба способа встраивания чем-то похожи на встраивание при помощи тэга object, например нельзя менять пропорции изменением ширины и высоты контейнера, но имеют больше ограничений.
Подключаемые в SVG внешние стили не будут работать, обратиться к элементам через JS так же не получится. Интерактивные анимации в SVG тоже не сработают. А проблемы с IE 8 и ниже так же остаются.
Но SVG анимации будут работать, в обоих случаях.
В случае с IMG втраивание выглядит как обычная картинка:
В случае с background-image как обычный блок:
.icon
Так же при помощи background-image можно использовать спрайты, как с png изображениями, а менять размер можно при помощи background-size:
background-size: 90px 150px;
Учитывая что процент людей c экранами device-pixel-ratio которых выше 1 и их устройства не поддерживают svg стремится к нулю(если такие вообще есть), то можно использовать медиа выражения для подключения svg, только для них, а для остальных использовать png версию:
.icon < background-image: url("icon.png"); >@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min--moz-device-pixel-ratio: 1.5), only screen and (-o-device-pixel-ratio: 3/2), only screen and (min-device-pixel-ratio: 1.5) < .icon < background-image: url("icon.svg"); >>
Плюсы и минусы этих подходов:
+ поддерживаются SVG анимации и фильтры;
+ в случае с background-image можно использовать SVG спрайты;
– нельзя менять свойства элементов SVG через CSS или JS;
– не поддерживаются интерактивные анимации;
– для IE 8 и ниже необходима замена на растровое изображение.
Inline SVG

Пример на codepen.io
В этом варианте SVG код, получить который можно открыв любой SVG файл текстовым документом, встраивается непосредственно в код страницы.
Несомненно такая конструкция ухудшает читаемость кода, и увеличивает его объем, но открываются новые возможности.
Например имея набор иконок в SVG файле, можно использовать их повторно простой конструкцией вида:
где some_svg_element_id id элемента внутри исходного SVG файла.
К отдельно взятому элементу можно, например, применять SVG трансформации:
Но если внутри исходного SVG к элементу была применена интерактивная анимация, например по клику, как в демо выше, то при дублировании объекта анимация будет срабатывать на всех элементах одновременно.
SVG анимации и фильтры это тема для отдельной статьи, поэтому ограничусь лишь примером SVG фильтра (подробнее о SVG фильтрах), и примером SVG анимации (подробнее о SVG анимациях).
С обесепечением работоспособности для IE 8 и ниже все несколько сложнее, чем в других вариантах. Необходимо добавить дополнительную разметку:
if (!Modernizr.svg)
.no-svg .my-svg-alternate
Плюсы и минусы этого подхода:
+ никакой подгрузки внешних файлов;
+ доступны манипуляции с элементами SVG через CSS и JS;
+ поддерживаются SVG анимации и фильтры;
+ поддерживаются интерактивные анимации;
+ возможность повторного использования элементов;
– загрязняется код страницы;
– для IE 8 и ниже необходима дополнительная разметка, и замена на растровое изображение.
Заключение
Каждый из способов хорош по своему, и в зависимости от обстоятельств можно использовать любой из них.
Эта статья в первую очередь мой путь по освоению нюансов SVG, и надеюсь многим она будет так же полезна.
P.S. Всем добра и котиков.
Эффекты фильтрации SVG. Часть 1. SVG фильтры 101
Предлагаемая серия статей «Эффекты фильтрации SVG» Sara Soueidan, внештатного разработчика UI/UX интерфейса и автора многих технических статей, проживающей в Ливане, посвящена работе фильтров SVG и состоит из следующих статей:
Эффекты фильтрации SVG
- Эффекты фильтров SVG. Часть 1. SVG фильтры 101.
- Эффекты фильтров SVG. Часть 2. Контурный текст при помощи feMorphology.
- Эффекты фильтрации SVG. Часть 3. Эффект постеризации изображения при помощи feComponentTransfer.
- Эффекты фильтрации SVG. Часть 4. Двухцветные изображения при помощи feComponentTransfer.
- Эффекты фильтрации SVG. Часть 5. Соответствие текста текстуре поверхности при помощи feDisplacementMap
Это первая статья в серии об SVG фильтрах. Это руководство поможет понять, что это такое, и покажет, как использовать их для создания собственных визуальных эффектов.

CSS в настоящее время предоставляет нам способ применения цветовых эффектов к изображениям, таких как насыщенность, яркость и контрастность, среди других эффектов, с помощью свойства filter и его функций, поставляющихся с ним.
Теперь у нас есть 11 функций фильтра в CSS, которые выполняют ряд эффектов от размытия до изменения цветовой контрастности и насыщенности и многое другое. Подробную информацию об этом можно посмотреть в справочнике CSS.
Хотя мощные и очень удобные, CSS фильтры также очень ограничены. Эффекты, которые мы можем создать с их помощью, часто применимы к изображениям и ограничиваются цветовыми манипуляциями и простым размытием. Таким образом, для создания более мощных эффектов, которые мы можем применить к более широкому ряду элементов, нам понадобится более широкий ассортимент функций. Эти функции доступны сегодня, и доступны уже более десяти лет в SVG. В этой статье, которая является первой в серии о SVG-фильтрах, вы узнаете о функциях SVG-фильтров, известных как “примитивы”, и о том, как их использовать.
CSS-фильтры импортированы из SVG. Они являются достаточно хорошо оптимизированными версиями подмножества эффектов фильтрации, представленных в SVG и существующих в спецификации SVG уже в течение многих лет.
В SVG существует больше эффектов фильтрации, чем в CSS, а SVG-версии более мощные и выполняют гораздо более сложные эффекты, чем их CSS-ярлыки. Например, в настоящее время можно размыть элемент, используя CSS-функцию фильтрации blur(). Применение эффекта размытия с помощью этой функции создаст равномерное размытие по Гауссу элемента, к которому оно применяется. На следующем рисунке показан результат применения размытия в 6px к изображению в CSS:

Рис_1. Эффект применения CSS-функции blur() — размытия по Гауссу.
Функция blur() создает эффект размытия, который равномерно применяется в обоих направлениях (X и Y) на изображении. Но эта функция — просто упрощенное и ограниченное сокращение примитива фильтра размытия, доступного в SVG, который позволяет нам размыть изображение либо равномерно, либо применить однонаправленный эффект размытия вдоль осей X или Y.

Рис_2. Эффект применения SVG-функции blur() раздельно по осям.
SVG-фильтры могут применяться как к HTML-элементам, так и к SVG-элементам. Эффект фильтрации SVG может быть применен к HTML-элементу в CSS с помощью функции фильтра url(). Например, если у вас есть эффект фильтра с идентификатором myAwesomeEffect, определенным в SVG (мы поговорим об определении эффектов фильтров в SVG в ближайшее время), вы можете применить этот эффект к HTML-элементу или изображению вот так:
Лучше всего, как вы увидите в этой серии статей, SVG-фильтры способны создавать эффекты уровня Photoshop в браузере, используя несколько строк кода. Я надеюсь, что эта серия поможет развеять ореол тайны и раскрыть часть потенциала SVG фильтров, что вдохновит вас на использование их в собственных проектах.
Но а как насчет поддержки браузерами, спросите вы.
Поддержка браузерами
Поддержка браузерами большинства SVG фильтров впечатляет. Однако способ применения эффекта может отличаться у некоторых браузеров в зависимости от поддержки ими отдельных примитивов фильтра, используемых в эффекте SVG-фильтрации, а также от возможных ошибок браузера. Поддержка браузером также может отличаться, когда фильтр SVG применяется к элементам SVG или к элементам HTML.
Я бы рекомендовала вам рассматривать эффекты фильтрации как расширение: вы почти всегда можете применить эффект в качестве улучшения поверх совершенно полезного опыта работы без фильтра. Многие знают, что я поддерживаю прогрессивный подход создания UI, когда это возможно. Таким образом, мы не будем слишком беспокоиться о поддержке браузерами в этой серии статей.
Наконец, несмотря на то, что поддержка фильтров SVG в целом хороша, имейте в виду, что некоторые эффекты, которые мы рассмотрим позже, можно считать экспериментальными. Я буду указывать любые основные проблемы или ошибки, если и когда они будут.
Итак, как определить и создать эффект фильтрации в SVG?
Элемент
Подобно линейным градиентам, маскам, узорам и другим графическим эффектам в SVG, фильтры имеют удобно-названный специализированный элемент: .
Он никогда не отображается напрямую, а используется только как объект, на который можно ссылаться с помощью атрибута filter в SVG или функции url() в CSS. Такие элементы, которые не отображаются без явной ссылки, обычно определяются как шаблоны внутри элементов в SVG. Но SVG не нужно упаковывать в элемент defs. Обернете ли вы фильтр в элемент defs или нет, он все равно не будет отображаться.
Причина этого заключается в том, что фильтр требует исходное изображение для обработки. А если вы явно не определяете это исходное изображение, вызывая фильтр на нем, у фильтра не будет ничего для визуализации, и поэтому он не сработает.
Очень простой, минимальный пример кода, определяющий фильтр SVG и применяющий его к исходному изображению в SVG, будет выглядеть следующим образом:
Фильтр в приведенном выше примере кода ничего не делает на данный момент, так как он пуст. Чтобы создать эффект фильтра, необходимо определить серию из одной или нескольких операций фильтрации, которые создают этот эффект внутри фильтра. Другими словами, элемент является контейнером для серии операций фильтрации, которые совместно и создают эффект фильтра. Эти операции фильтрации в SVG называются “примитивами фильтра”.
Примитивы фильтра
Таким образом, в SVG каждый элемент содержит набор примитивов фильтра в качестве дочерних элементов. Каждый примитив фильтра выполняет одну элементарную графическую операцию на одном или нескольких входах, создавая графический результат.
Примитивы фильтра удобно названы в честь графических операций, которые они выполняет. Например, примитив, применяющий эффект размытия Гаусса (Gaussian Blur) к источнику графики, называется feGaussianBlur. Все примитивы имеют одинаковый префикс: fe, сокращенно от “filter effect”. Опять же, имена в SVG удобно выбирать, чтобы понимать, что это за элемент или что он делает.
В следующем фрагменте кода показано, как будет выглядеть простой фильтр, если применить к изображению размытие Гаусса размером 5px:
В настоящее время в спецификации SVG Filter определено 17 примитивов фильтров, которые способны создавать чрезвычайно мощные графические эффекты, включая, но не ограничиваясь, генерацию шума и текстуры, световые эффекты, цветовые манипуляции (от канала к каналу) и многое другое.
Примитив фильтра работает, принимая графический источник на ввод и выводя на другой. А выход одного эффекта фильтра может быть использован в качестве входа в другой. Это очень важно и очень действенно, потому что имея почти бесчисленное множество комбинаций эффектов фильтрации, вы можете создать почти бесчисленное количество графических эффектов.
Каждый примитив фильтра может принимать один или два входа и выводить только один результат. Входные данные примитива фильтра определяются в атрибуте in. Результат операции определяется в атрибуте result. Если эффекту фильтра требуется второй ввод, то он указывается в атрибуте in2. Результат операции может использоваться в качестве входных данных для любой другой операции, но если входные данные операции не указаны в атрибуте in, то результат предыдущей операции автоматически используется в качестве входных данных. Если не указать result примитива, то его результат будет автоматически использоваться в качестве входных данных для следующего примитива. Это станет яснее, когда мы начнем изучать примеры кода.
В качестве входных данных примитив фильтра может использовать и другие типы данных, наиболее важными из которых являются:
- SourceGraphic: элемент, к которому применяется весь фильтр; например, изображение или фрагмент текста.
- SourceAlpha: это то же самое, что и SourceGraphic, за исключением того, что эта графика содержит только альфа-канал элемента. Например, для изображения JPEG это черный прямоугольник размером с само изображение.
Вы обнаружите, что иногда вы хотите использовать источник графики в качестве входных данных, а иногда только ее альфа-канал. Примеры, которые мы рассмотрим в этой и следующих статьях обеспечат четкое понимание того, когда и что использовать.
Этот фрагмент кода является примером того, как может выглядеть фильтр с пакетом примитивов фильтра в качестве дочерних элементов. Не беспокойтесь о примитивах и о том, что они делают. На этом этапе просто обратите внимание на то, как определяются и используются входы и выходы определенных примитивов. Я добавила некоторые комментарии для помощи.
Теперь последняя концепция, которую я хочу кратко пояснить, прежде чем перейти к нашему первому примеру фильтра, это концепция области фильтрации (Filter Region).
Область фильтрации
Набору операций фильтрации требуется область для обработки, область, к которой они могут быть применены. Например, у вас может быть сложный SVG со многими элементами, и вы хотите применить эффект фильтрации только к определенной области или одному или группе элементов внутри того самого SVG.
В SVG элементы имеют “области”, границы которых определяются гранями прямоугольника, ограничивающего элемент. Ограничивающий прямоугольник (также сокращенно “bbox“) — это наименьший охватывающий прямоугольник вокруг элемента. Например, на следующем рисунке для фрагмента текста такой прямоугольник выделен розовым цветом.

Рис_3. Наименьший охватывающий прямоугольник вокруг фрагмента текста.
Обратите внимание, что этот прямоугольник может содержать еще несколько пробелов по вертикали, так как при вычислении высоты ограничивающего прямоугольника учитывается высота строки текста.
По умолчанию областью фильтра элемента является окаймляющей рамкой элемента. Поэтому, если вы примените эффект фильтра к нашему фрагменту текста, эффект будет ограничен этим прямоугольником, и любой результат фильтрации, который находится за его пределами, будет обрезан. Хотя это и разумно, это не очень практично, потому что многие фильтры будут воздействовать на некоторые пиксели за пределами ограничивающего прямоугольника, а по умолчанию эти пиксели в конечном итоге будут отрезаны.
Например, если применить эффект размытия к нашему фрагменту текста, можно увидеть что оно обрезается по левому и правому краям прямоугольника, ограничивающего текст:

Рис_4. Эффект размытия, применяемый к тексту, обрезается как с правой, так и с левой стороны области прямоугольника, ограничивающего текст.
Так как же нам предотвратить это? Ответ такой: путем расширения области фильтра. Мы можем расширить область, к которой применяется фильтр, изменив атрибуты x, y, width и height элемента < filter>.
Часто необходимо предусматривать поля в области фильтра, так как эффект фильтра может воздействовать на некоторые биты за пределами ограничивающего прямоугольника для данного объекта. Для этого можно давать отрицательные значения в процентах свойствам X и Y, а значения больше 100% свойствам width и height.
По умолчанию фильтры имеют области, расширяющие на 10% ширину и высоту ограничивающего прямоугольника во всех четырех направлениях. Другими словами, по умолчанию для атрибутов x, y, width и height используются следующие значения:
Если вы не включите эти атрибуты в элемент , то будут использоваться значения по умолчанию. Вы также можете переопределить их, чтобы расширить или уменьшить область по мере необходимости.
Следует иметь в виду, что единицы измерения, используемые в атрибутах x, y, width и height, зависят от того, какое значение атрибута filterUnits используется. Он определяет систему координат атрибутов x, y, width и height и может принимать одно из двух значений:
- objectBoundingBox. Это значение по умолчанию. Когда для filterUnits задано значение objectBoundingBox, то значения атрибутов x, y, width и height являются процентами или долями размера ограничивающего прямоугольника элемента. Это также означает, что вы можете использовать дробные значения вместо процентов, если вы предпочитаете.
- userSpaceOnUse Если для filterUnits задано значение userSpaceOnUse, координаты атрибутов x, y, width и height задаются относительно текущей системы координат, используемой пользователем. Другими словами, это относительно текущей системы координат, используемой в SVG, которая использует пиксели в качестве единиц измерения и, как правило, относительно размера самой SVG, предполагая, что значения viewBox соответствуют значениям исходной системы координат.
Все, что вам нужно знать о системах координат в SVG Вы можете узнать в этой статье, которую я написала несколько лет назад.
Быстрый совет: визуализация текущей области фильтра с помощью feFlood
Если вам когда-нибудь понадобится увидеть пределы области фильтра, вы можете визуализировать ее, залив каким-нибудь цветом. Удобно, что существует примитив фильтра под названием feFlood, единственной целью которого является именно это: заполнить текущую область фильтра цветом, указанным в атрибуте flood-color.
Итак, если предположить, что у нас есть фрагмент текста, область фильтра которого мы хотим увидеть, то код может выглядеть примерно так:
Как видно из приведенного выше фрагмента кода, примитив feFlood также принимает атрибут flood-opacity, который можно использовать для создания прозрачности цветного слоя заливки.
Приведенный выше фрагмент заливает область фильтра розовым цветом. Но вот в чем дело: когда вы заливаете область цветом, вы буквально заливаете ее цветом, что означает, что цвет будет охватывать все в области фильтра, включая любые элементы и эффекты, которые вы создали раньше, а также сам текст. В конце концов, таково понятие заливки, верно?

Рис_5. До и после заливки цветом текстовой области фильтра.
Чтобы это изменить, нам нужно переместить цветовой слой ниже, а сверху показать исходный текстовый слой.
Если у вас существует несколько слоев контекста, которые должны отображаться в фильтре SVG поверх друг друга, можно использовать примитив фильтра . Как следует из названия, примитив feMerge используется для объединения вместе слоев элементов или эффектов.
Примитив не имеет атрибута in. Для объединения слоев внутри используются два или более , каждый из которых имеет свой атрибут in, представляющий слой, который мы хотим добавить.
Укладка слоя (или “узла”) зависит от порядка источника — первый отображается “за” или “ниже” второго. Последний представляет самый верхний слой. И так далее.
Итак, в нашем примере с текстом цветная заливка это слой, а текстовый источник (источник графики) — это другой слой, и мы хотим поместить текст поверх цветной заливки. Наш код будет выглядеть следующим образом:
Обратите внимание, как я назвала результат работы feFlood в атрибуте result, чтобы я могла использовать это имя в слое в качестве входных данных. Поскольку мы хотим отобразить исходный текст поверх цвета потока, мы ссылаемся на этот текст с помощью SourceGraphic. Следующее демо показывает результат:
Применение тени к изображению
Позвольте мне начать с краткого предупреждения: вам лучше создать простую тень с помощью CSS-функции фильтрации drop-shadow(). Путь фильтра SVG гораздо более подробный. Ведь, как мы уже упоминали ранее, функции CSS фильтра — это удобные ярлыки. Но я все равно хочу рассмотреть этот пример как простую точку входа в более сложные эффекты фильтра, которые мы рассмотрим в следующих статьях.
Итак, как создается тень?
Тень обычно представляет собой светло-серый слой позади или под элементом, который имеет ту же форму (или фигуру), что и сам элемент. Другими словами, вы можете считать это размытой серой копией элемента.
При создании SVG-фильтров нужно рассуждать поэтапно. Какие шаги необходимы для достижения того или иного эффекта? Для тени размытая серая копия элемента может быть создана путем размытия черной копии элемента, а затем раскрашивания этой черной копии, т.е. сделать ее серой. Затем эта только что созданная размытая серая копия помещается позади исходного элемента и немного смещается в обоих направлениях.
Итак, мы начнем с получения черной копии нашего элемента и ее размытия. Черная копия может быть создана с помощью альфа-канала элемента, используя SourceAlpha в качестве входных данных фильтра.
Примитив feGaussianBlur будет использоваться для применения размытия Гаусса к этому SourceAlpha-слою. Необходимое количество размытия задается в атрибуте stdDeviation (сокращение от Standard Deviation). Если задать одно значение атрибута stdDeviation, это значение будет использоваться для применения равномерного размытия входных данных. Можно также указать два числовых значения, тогда первое будет использоваться для размытия элемента в горизонтальном направлении, а второе — для вертикального размытия. Для тени нам нужно применить равномерное размытие, поэтому наш код будет начинаться с этого:
Приведенный выше фрагмент кода приводит к следующему эффекту, где на данный момент отображается только размытый альфа-канал изображения:

Рис_6. Созданная черная копия изображения с размытием (тень).
Затем мы хотим изменить цвет тени и сделать ее серой. Мы сделаем это, применив цветную заливку к области фильтра, а затем соединим этот слой цветной заливки с созданным нами слоем тени.
Совмещение-это соединение графического элемента с размытым фоном. Размытым фоном является контент позади элемента, с которым элемент совмещается. В нашем фильтре цвет заливки — это верхний слой, а размытая тень — ее фон, потому что она лежит за ним. Мы будем рассматривать примитив feComposite подробнее в следующих статьях, поэтому, если вы не знакомы с композицией и как она работает, то я рекомендую ознакомиться с подробной статьей на эту тему в моем блоге.
Примитив feComposite имеет атрибут operator, который используется для указания, какую составную операцию мы хотим использовать.
Используя оператор in composite, слой цветной заливки будет “обрезан”, а отображаться будет только область цвета, которая совпадает с нашим теневым слоем. Оба слоя будут смешаны там, где они пересекаются, т.е. серый цвет будет использоваться для окрашивания нашей черной тени.
Примитив feComposite требует двух входных данных для работы, указанных в атрибутах in и in2. Первый вход — это наш цветной слой, а второй — размытый теневой фон. С помощью составной операции, указанной в атрибуте operator, наш код теперь выглядит следующим образом:
Обратите внимание, как результаты feGaussianBlur и примитивов feFlood используются в качестве входных данных для композита. Теперь наше демо выглядит так:

Рис_7. Теперь тень серая.
Перед тем, как мы наложим наше исходное изображение поверх тени, мы хотим сместить ее по вертикали и/или горизонтали. На сколько и в каком направлении полностью зависит от вас. Для этой демо я предположу, что у нас есть источник света, исходящего из верхнего левого угла нашего экрана, поэтому я смещу тень на несколько пикселей вниз и вправо.
Для смещения слоя в SVG используется примитив feOffset. Дополнительно к атрибутам in и result этот примитив принимает два главных атрибута: dx и dy, которые определяют расстояние, на которое вы хотите сместить слой вдоль осей X и Y соответственно.
После смещения тени, мы будет объединить ее с исходным изображением, используя feMerge, подобно тому, как мы объединяли текст и цветную заливку на предыдущем шаге — один mergeNode примет наши тени в качестве входных данных, а на другом mergeNode будет слой исходного изображения, используя SourceGraphic в качестве входных данных. Наш код теперь выглядит так:
И следующее демо для кода выше:
И именно так вы применяете эффект фильтра в SVG, используя фильтры SVG. Вы найдете, что этот эффект работает во всех основных браузерах.
Есть другой способ…
Существует другой, более распространенный способ создания тени. Вместо того, чтобы создавать черную тень и применять к ней цвет, чтобы сделать ее светлее, вы можете применить к ней прозрачность, сделав ее полупрозрачной и, следовательно, светлее.
В предыдущем демо мы узнали, как применить цвет к тени, используя feFlood, технику окраски, которую вы, вероятно, посчитаете нужной и станете часто пользоваться. Вот почему я подумала, что ее необходимо рассмотреть. Это также полезно узнать, потому что это путь, которым вы захотите создать тень, которая, по какой-то причине, будет пестрой, например, вместо черной или серой.
Для изменения прозрачности слоя можно использовать либо примитив feColorMatrix, либо feComponentTransfer. О примитиве feComponentTransfer я расскажу более подробно в следующих статьях, поэтому сейчас воспользуемся feColorMatrix, чтобы уменьшить непрозрачность нашей тени.
Примитив feColorMatrix заслуживает отдельной статьи. На данный момент я настоятельно рекомендую прочитать статью Una Kravet, которая будет отличным введением с действительно хорошими примерами.
Короче говоря, этот фильтр применяет матричное преобразование к каналам R(Красный), G(зеленый), B(синий) и A(Альфа) каждого пикселя на входной графике для получения результата с новым набором цветов и Альфа-значений. Другими словами, для управления цветами объекта используется матричная операция. Основа матрицы цвета выглядит так:
Еще раз рекомендую проверить статью Уны, чтобы узнать больше о ее синтаксисе.
Поскольку мы хотим только уменьшить непрозрачность нашей тени, мы будем использовать тождественную матрицу, которая не изменяет каналы RGB, но мы уменьшим значение альфа-канала в этой матрице:
А это наше живое демо:
Заключение
В этой серии я постараюсь отойти от очень технических определений операций с фильтрами и придерживаться упрощенных и понятных определений. Зачастую вам не нужно вдаваться в мелкие детали того, что происходит под капотом. Поэтому вхождение в эти мелочи только добавит сложности статьям, пожалуй сделает их менее понятными и принесет мало пользы. Понимание того, что делает фильтр и как его использовать, на мой взгляд, более чем достаточно, чтобы использовать преимущества, которые он может предложить. Если вы хотите получить более подробную информацию, я рекомендую для начала проконсультироваться со спецификацией. Тем не менее, она может оказаться мало полезной, поэтому вы, в конечном итоге проведете свое собственное исследование на стороне. Я приведу список отличных ресурсов для дальнейшего изучения в заключительной статье этой серии.
Теперь, когда мы рассмотрели основы SVG-фильтров и способы их создания и применения, мы рассмотрим дополнительные примеры эффектов использования дополнительных примитивов фильтров в следующих статьях. Оставайтесь с нами.
