Кто-то недавно спросил меня, как я подхожу к отладке встроенных SVG. Поскольку это часть DOM, мы можем проверить любой встроенный SVG в любом браузере DevTools. И благодаря этому у нас есть возможность оценить ситуацию и выявить любые потенциальные проблемы или возможности для оптимизации SVG.
Но иногда мы вообще не можем видеть наши SVG. В этих случаях есть шесть конкретных вещей, на которые я обращаю внимание при отладке.
1. Значения viewBox
viewBox часто вызывает путаницу при работе с SVG. Технически можно использовать встроенный SVG без него, но мы потеряем одно из его самых значительных преимуществ: масштабирование с помощью контейнера. В то же время он может работать против нас при неправильной настройке, что приводит к нежелательному обрезанию.
Элементы присутствуют, когда они обрезаны — они просто находятся в той части системы координат, которую мы не видим. Если бы мы открыли файл в какой-нибудь программе редактирования графики, это могло бы выглядеть так:
Самый простой способ исправить это? Добавьте overflow='visible' в SVG, будь то в нашей таблице стилей, встроенный в атрибут стиля или непосредственно как атрибут представления SVG. Но если мы также применим фоновый цвет к SVG или если у нас есть другие элементы вокруг него, все может выглядеть немного не так. В этом случае лучшим вариантом будет отредактировать viewBox, чтобы показать ту часть системы координат, которая была скрыта.
Есть несколько дополнительных моментов, связанных с viewBox, о которых стоит рассказать, пока мы обсуждаем эту тему.
Как работает viewBox?
SVG — это бесконечный холст, но мы можем контролировать то, что мы видим и как мы это видим, через viewport и viewBox.
Viewport — это рамка окна на бесконечном холсте. Его размеры определяются атрибутами ширины и высоты или в CSS с соответствующими свойствами ширины и высоты. Мы можем указать любую единицу длины, которую захотим, но если мы укажем безразмерные числа, по умолчанию они будут пикселями.
ViewBox определяется четырьмя значениями. Первые два являются отправной точкой в верхнем левом углу (значения x и y, допускаются отрицательные числа). Их можно редактировать, чтобы изменить кадр изображения. Последние два — это ширина и высота системы координат внутри области просмотра — здесь мы можем редактировать масштаб сетки (о чем мы поговорим в разделе «Масштабирование»).
Вот упрощенная разметка, показывающая SVG viewBox и атрибуты ширины и высоты, установленные в svg:
Переосмысление
Итак, это:
…сопоставляется с этим:
Окно просмотра, которое мы видим, начинается там, где встречаются 0 по оси x и 0 по оси y.
Изменив это:
…на это:
…ширина и высота остаются прежними (по 700 единиц каждая), но начало системы координат теперь находится в точке 300 по оси x и 200 по оси y.
Увеличение
Мы можем изменить последние два значения внутри viewBox, чтобы увеличить или уменьшить изображение. Чем больше значения, тем больше единиц SVG добавляется, чтобы поместиться в области просмотра, что приводит к уменьшению изображения. Если мы хотим сохранить соотношение 1:1, ширина и высота нашего viewBox должны соответствовать значениям ширины и высоты viewport.
Давайте посмотрим, что произойдет в Photoshop, когда мы изменим эти параметры. Монтажная область — это область просмотра, представленная белым квадратом размером 700 пикселей. Все остальное за пределами этой области является нашим бесконечным холстом SVG и по умолчанию обрезается.
На рис. 1 ниже показана синяя точка на 900° по оси x и 900° по оси y. Если я изменю последние два значения viewBox с 700 на 900 следующим образом:
…тогда синяя точка почти полностью снова видна, как показано на рисунке 2 ниже. Наше изображение уменьшено, потому что мы увеличили значения viewBox, но фактические размеры ширины и высоты SVG остались прежними, а синяя точка вернулась ближе к необрезанной области.
Розовый квадрат свидетельствует о том, как сетка масштабируется, чтобы соответствовать размеру окна просмотра: единица становится меньше, и больше линий сетки помещается в ту же область окна просмотра.
Вы можете поиграть с теми же значениями в CodePen, чтобы увидеть эту работу в действии.
2. Не хватает width и height
Еще одна распространенная вещь, на которую я обращаю внимание при отладке встроенного SVG, — содержит ли разметка атрибуты width или height. Во многих случаях это не имеет большого значения, если только SVG не находится внутри контейнера с абсолютным позиционированием или гибкого контейнера (поскольку Safari вычисляет значение ширины SVG с 0px вместо auto). Исключение width или height в этих случаях не позволяет нам увидеть полное изображение, в чем мы можем убедиться, открыв эту демонстрацию CodePen и сравнив ее в Chrome, Safari и Firefox.
Решение? Добавьте ширину или высоту в виде атрибута, встроенного в атрибут стиля или в CSS. Избегайте использования высоты отдельно, особенно если для нее установлено значение 100% или auto. Другой обходной путь — установить правое и левое значение.
Вы можете поиграть со следующим примером и комбинировать различные варианты.
3. Непреднамеренные цвета fill и stroke
Также может быть, что мы применяем цвет к тегу <svg>, будь то встроенный стиль или из CSS файла. Это нормально, но в разметке или стилях могут быть другие значения цвета, конфликтующие с цветом, установленным в svg, из-за чего части становятся невидимыми.
Вот почему я стараюсь искать атрибуты fill и stroke в разметке SVG и убирать их.
4. Отсутствующие идентификаторы
Это может показаться очень очевидным, но вы будете удивлены, как часто это возникает. Допустим, мы создали файл SVG в Illustrator и очень усердно называли наши слои, чтобы при экспорте файла вы получали хорошие совпадающие идентификаторы в разметке. Допустим, мы планируем стилизовать этот SVG в CSS, подключившись к этим идентификаторам.
Это хороший способ делать вещи. Но много раз я видел, как один и тот же SVG-файл экспортировался во второй раз в одно и то же место, а идентификаторы были разными, обычно при прямом копировании/вставке векторов. Возможно, был добавлен новый слой, или один из существующих был переименован или что-то в этом роде. Как бы то ни было, правила CSS больше не соответствуют идентификаторам в разметке SVG, что приводит к тому, что SVG отображается не так, как вы ожидаете.
В больших файлах SVG нам может быть трудно найти эти идентификаторы. Это хорошее время, чтобы открыть DevTools, проверить ту часть графики, которая не работает, и посмотреть, совпадают ли эти идентификаторы.
Итак, я бы сказал, что стоит открыть экспортированный SVG-файл в редакторе кода и сравнить его с оригиналом, прежде чем что-то менять. Такие приложения, как Illustrator, Figma и Sketch, умны, но это не значит, что мы не несем ответственности за их проверку.
5. Чек-лист для отсечения и маскирования
Если SVG неожиданно обрезается, а viewBox проверяется нормально, я обычно смотрю в CSS свойства clip-path или mask, которые могут мешать изображению. Заманчиво продолжать смотреть на встроенную разметку, но полезно помнить, что стиль SVG может происходить где-то еще.
Отсечение и маскирование CSS позволяют нам «скрывать» части изображения или элемента. В SVG <clipPath> — это векторная операция, которая вырезает части изображения без промежуточных результатов. Тег <mask> — это пиксельная операция, позволяющая использовать эффекты прозрачности, полупрозрачности и размытые края.
Это небольшой чек-лист для отладки случаев, когда задействовано отсечение и маскирование:
- Убедитесь, что обтравочный контур (или маска) и изображение перекрывают друг друга. Перекрывающиеся части - это то, что отображается.
- Если у вас есть сложный путь, который не пересекает вашу графику, попробуйте применить преобразования, пока они не совпадут.
- Вы по-прежнему можете проверять внутренний код с помощью DevTools, даже если <clipPath> или <mask> не отображаются, так что используйте их!
- Скопируйте разметку внутри <clipPath> и <mask> и вставьте ее перед закрытием тега </svg>. Затем добавьте заливку к этим фигурам и проверьте координаты и размеры SVG. Если вы все еще не видите изображение, попробуйте добавить overflow='hidden' в тег <svg>.
- Убедитесь, что для <clipPath> и <mask> используется уникальный идентификатор и что этот же идентификатор применяется к фигурам или группе фигур, которые обрезаются или маскируются. Несоответствующий идентификатор нарушит внешний вид.
- Проверьте наличие опечаток в разметке между тегами <clipPath> и <mask>.
- fill, stroke, opacity или некоторые другие стили, примененные к элементам внутри <clipPath>, бесполезны — единственной полезной частью является геометрия области заполнения этих элементов. Вот почему, если вы используете <polyline>, она будет вести себя как <polygon>, а если вы используете <line>, вы не увидите никакого эффекта отсечения.
- Если вы не видите свое изображение после применения <mask>, убедитесь, что заливка маскирующего содержимого не полностью черная. Яркость маскирующего элемента определяет непрозрачность конечного изображения. Вы сможете видеть сквозь более яркие части, а более темные части скроют содержимое вашего изображения.
В этом примере вы можете играть с маскированными и обрезанными элементами.
6. Пространства имен
Знаете ли вы, что SVG — это язык разметки на основе XML? Что ж, это так! Пространство имен для SVG задается в атрибуте xmlns:
О пространствах имен в XML нужно знать многое, и у MDN есть отличный учебник по этому вопросу. Достаточно сказать, что пространство имен предоставляет браузеру контекст, информируя его о том, что разметка специфична для SVG. Идея состоит в том, что пространства имен помогают предотвратить конфликты, когда в одном файле находится более одного типа XML, например SVG и XHTML. Это гораздо менее распространенная проблема в современных браузерах, но она может помочь объяснить проблемы с рендерингом SVG в старых браузерах или браузерах, таких как Gecko, которые строго определяют типы документов и пространства имен.
Спецификация SVG 2 не требует пространства имен при использовании синтаксиса HTML. Но это важно, если приоритетом является поддержка устаревших браузеров — к тому же добавить ее не помешает. Таким образом, когда атрибут xmlns элемента html определен, он не будет конфликтовать в тех редких случаях.
Это также верно при использовании встроенного SVG в CSS, например, при установке его в качестве фонового изображения. В следующем примере после успешной проверки на входе появляется значок галочки. Вот как выглядит CSS:
Когда мы удаляем пространство имен внутри SVG в свойстве фона, изображение исчезает.
Другой распространенный префикс пространства имен — xlink:href. Мы часто используем его, когда ссылаемся на другие части SVG, такие как шаблоны, фильтры, анимация или градиенты. Рекомендуется заменить его на href, так как другой устарел со времен SVG 2, но могут возникнуть проблемы совместимости со старыми браузерами. В этом случае мы можем использовать оба. Просто не забудьте включить пространство имен xmlns:xlink='http://www.w3.org/1999/xlink', если вы все еще используете xlink:href.
Прокачай свои навыки SVG!
Я надеюсь, что эти советы помогут вам сэкономить массу времени, если вы обнаружите, что устраняете неполадки с неправильно отображаемыми встроенными SVG. Это как раз то, что я ищу. Может быть, у вас есть другие красные флажки, за которыми вы следите — если да, сообщите мне в комментариях!
Суть в том, что стоит иметь хотя бы базовое представление о различных способах использования SVG. CodePen Challenges часто включают SVG и предлагают хорошую практику. Вот еще несколько ресурсов для повышения уровня:
- Использование SVG с CSS3 и HTML5 (Амелия Беллами-Ройдс, Курт Кейгл, Дадли Стори) — я считаю это Библией SVG.
- Леа Веру обладает обширными знаниями SVG и довольно много говорила на эту тему (например, это видео с Frontend United 2019)
- SVG Animations (Sarah Drasner)
- SVG Essentials (Amelia Bellamy-Royds, J. David Eisenberg)
- Practical SVG (Chris Coyier)
Перевод статьи "6 Common SVG Fails (and How to Fix Them)".