Как наложить svg друг на друга
Перейти к содержимому

Как наложить svg друг на друга

  • автор:

Практическое
руководство

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

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

SVG

Scalable Vector Graphics это разметка, основанная на XML , который содержит двумерные векторы. Векторами могут быть простые геометрические формы, сложные контуры, да и всё то же самое, что можно сделать в Иллюстраторе. Этот формат изображений имеет намного больше общего с веб-страницей, чем тот же JPEG . SVG намного мощнее — им легко можно управлять при помощи кода (в текстовом редакторе или с помощью CSS / JS ).

  • не зависит от разрешения
  • поддерживается во всех современных браузерах
  • актуален в будущем ( W3C стандарт)
  • легко создавать и редактировать
  • изменяется с помощью CSS & JS
  • поддаётся сжатию

Подготовка и оптимизация

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

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

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

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

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

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

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

Pre optimisation

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

Post optimisation

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

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

Points off pixels

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

Pixel snapped

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

Post optimisation

И, наконец, последнее, но немаловажное, то, о чём обычно забывают — это активировать 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% при сжатии)

Дополнение: Rob Sterlini заметил, поскольку «b» повторяется, можно использовать элемент , для повторения, что ещё больше уменьшит размер файла — и был абсолютно прав.

После оптимизации с использованием : 311b

Размер файла стал меньше на ~78%

Если применить эту технику ко всем файлам SVG , это значительно улучшит ваш сайт.

Варианты использования (реализации)

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

Img

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

Background-image

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

.logo
Iframe

Вы можете загрузить SVG как . Это позволит сделать многое, но я не уверен, что это лучший вариант использования, чтобы продвинуться вперёд ¯\_(ツ)_/¯.

Embed

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

Object

возможно лучший вариант, если вам нужно изменять SVG , не встраивая его в HTML .

Your browser does not support SVGs
Inline

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

Заключение

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

Object Inline Img Background-image
CSS -манипуляции Да Да Частично Частично
JS -манипуляции Да Да Нет Нет
SVG -анимация Да Да Да Да
Интерактивная SVG -анимация Да Да Нет Нет

Важно: «Частично» означает, что частично работает, но при условии, что в CSS встроены в код SVG . Больше информации об этом в следующей части.

CSS -манипуляции

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

Есть два способа изменить стили — во встроенном SVG и через внешнее подключение (например, в списке стилей). Чтобы встроить стили, оберните их в тег и также внутри &lt![CDATA[ . ]]> . Лучше делать именно так, потому что иногда XML анализаторы могут конфликтовать с определённым символами (например > ). Даже если у вас нет шибко модных символов сейчас, лучше всё равно использовать CDATA , вдруг позже они появятся и всё сломают.

В основном встроенные стили будут работать со всеми реализациями и background-image не поддерживают CSS3 -анимацию, даже если они встроены (подробнее в разделе об анимации). background-image не поддерживает встроенные медиазапросы (подробнее в разделе о медиазапросах).

Встроенные стили
 <style type="text/css"> <![CDATA[ .firstb < fill: yellow; >.secondb < fill: red; >]]>  

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

Внешние стили
// Add to very start of SVG file before 
// In style.css .firstb < fill: yellow; >.secondb

Как с помощью CSS наложить элементы друг на друга

При разработке веб-дизайна часто нужно сделать так, чтобы два элемента перекрывались или полностью накладывались друг на друга. В CSS это можно реализовать с помощью свойства position и Grid.

Способ 1. Использование свойства Position

Свойство position со значением absolute разместит абсолютно позиционированный элемент на странице. В этом случае указывается позиция элемента относительно левого верхнего угла веб-страницы.

.child

При добавлении других элементов первый будет смещаться вниз. Это можно исправить, установив для родительского элемента position: relative. Тогда все дочерние элементы с position: absolute будут размещены абсолютно относительно верхнего угла родительского элемента.

.child < /* . */ position: absolute; top: 0; left: 0; >.parent

Также этот подход можно использовать для размещения одного элемента поверх другого. Например, два дочерних элемента, расположенных друг над другом, один из которых будет смещен на 150 пикселей. Они располагаются в одном родительском элементе и остаются внутри него.

Parent

Child 1

Child 2

.child < position: absolute; top: 0; >.child-1 < left: 0; >.child-2 < left: 150px; >.parent

Способ 2. Использование CSS Grid

Еще одним способом наложения элементов друг на друга является использование CSS Grid. Но эта технология поддерживается не всеми старыми браузерами.

С помощью Grid мы можем разместить элемент внутри контейнера следующим образом:

.parent < display: grid; grid-template-columns: 250px 1fr; grid-template-rows: 150px 1fr; >.child < grid-area: 1 / 1 / 2 / 2; >

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

.parent < display: grid; grid-template-columns: 250px 1fr; grid-template-rows: 150px 1fr; >.child < grid-area: 1 / 1 / 2 / 2; >.child-2

Для облегчения позиционирования я создал CSS Grid Generator , который поможет вам визуально сконструировать необходимый макет.

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

Как наложить два SVG друг на друга, но без CSS или HTML?

У меня есть две SVG картинки и я хочу, чтобы одна располагалась в другой. Я выяснил, что можно добавить один в другой через , как здесь. Но сложность в том, что, когда я так делаю, один SVG располагается на фоне, другой как надо на переднем плане, но первый вместо того, чтобы быть фоном для всего переднего плана, он остаётся маленьким в левом верхнем углу. Первый SVG выглядит так:

Второй выглядит так:

Второй должен служить фоном первому, но почему-то, если их объединить под получается вот так:

введите сюда описание изображения

Живое превью можно увидеть, если вставить код здесь. Я мало понимаю в векторных изображениях, просто хочу использовать итоговую картинку как favicon для сайта. Должно получиться что-то такое: Я пытался добавлять атрибуты ширины и высоты для , которые, видимо, неприменимы для этого, пробовал задать идентичный viewBox для каждого из SVG и добавить в , но тоже не получилось. Как можно объединить два SVG, чтобы получилось как на картинке выше, не используя HTML, CSS, JS и т.д. — используя только SVG?

Как наложить контур SVG на изображение?

Создал такую анимацию: на экране вырисовывается контур дома, а после этого вместо контура появляется само изображение этого дома.
Как только я вкрячил эту анимацию на сайт, контур дома съехал вниз вправо. Как сделать так, чтобы они совпадали?
https://vincent-job.codio.io/ блок с картинкой дома и его контуром нах-ся в блоке «Что такое утепление пенополиуретаном?» (после блока «Почему выбирают нас?»).
HTML: