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

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

  • автор:

Как с помощью 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, который поможет вам визуально сконструировать необходимый макет.

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

Наложение элементов — CSS: Позиционирование элементов

В уроке про плавающие элементы вы могли увидеть, что элементы HTML могут накладываться друг на друга. Такое же поведение было при выставлении позиционирования отличного от нормального. Наложением элементов можно управлять и с помощью CSS-свойства z-index . Из названия свойства можно увидеть, что речь идет об оси z .

Эта ось отвечает за то, какие элементы будут располагаться на переднем, а какие на дальнем плане. Попробуем использовать на трех блоках абсолютное позиционирование:

Возникнет естественный вопрос: «А где остальные два блока?». Они скрылись за последним блоком .block-three . Когда мы дали каждому блоку абсолютное позиционирование, то начали в одном и том же месте накладывать блоки друг на друга. Первым в угол встал блок .block-one , после этого у браузера возникла задача переместить блок .block-two ровно на это же место. Для этого он выставил приоритет по оси z второму блоку и наложил его на первый. Данная операция повторилась с последним блоком, и он занял видимую позицию, «заслонив» своих братьев.

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

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

Важным для понимания моментом является то, как браузер по умолчанию позиционирует элементы:

  1. Первым всегда идет элемент HTML. Поверх него накладываются все остальные элементы.
  2. Далее идут все элементы в нормальном потоке документа. Элементы идут по всем правилам расположения блочных и строчных элементов. Они позиционируются в том порядке, в котором определены внутри HTML-документа.
  3. В конце накладываются все элементы с position в том порядке, в котором они определены внутри HTML-документа. Это можно увидеть на примерах выше.

Попробуем поменять порядок элементов в последнем примере. Для этого установим второму и третьему блоку такие значения, чтобы они поменялись местами. Необходимо для блока .block-two установить значение z-index больше, чем у блока .block-three . В результате третий блок «исчезнет», так как имеет меньшие размеры:

Свойство z-index может принимать отрицательные, положительные значения и ноль. Здесь нет никакой магии и отрицательные значения будут находиться «ниже» положительных. В реальных проектах хорошей практикой считается установка значения z-index с шагом в 100 при достаточно больших значениях. Это делается для удобства чтения и правок стилей:

z-index: 34234; z-index: 43233; z-index: 34324; 

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

z-index: 34200; z-index: 43200; z-index: 34300; 

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Имитация относительного позиционирования в svg

Позиционирование элементов внутри SVG очень похоже на абсолютное позиционирование элементов в HTML, но не идентично ему. Каждый элемент в SVG позиционируется “абсолютно” относительно области видимости SVG, а позиция внутри области видимости регулируется используемой системой координат. Но это сходство в позиционировании элементов не должно скрывать тот факт, что между элементами SVG и HTML есть фундаментально различие: у элементов SVG нет блочной модели, как у элементов HTML в CSS.

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

Краткий обзор блочной модели в CSS

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

блочная модель

Блочная модель элемента в CSS включает контент, внутренний отступ, границу и внешний отступ. Изображение взято из статьи о box-sizing справочника по CSS Codrops

Обычно размер элемента определяется свойствами ширины и высоты блока контента. Добавление любого внутреннего отступа увеличит рассчитываемую ширину или высоту элемента — именно так по умолчанию работает блочная модель при формировании его размеров. Свойство box-sizing позволяет вам контролировать формирование размеров элемента. Если конкретнее, то используя свойство box-sizing , вы можете приказать браузеру учитывать как часть размера элемента ширину внутреннего отступа и (или) ширину границы, после чего их изменение не будет влиять на фактические размеры элемента. Это полезно во многих случаях, особенно при создании сеточных систем с помощью CSS. Все об этом свойстве и его значениях вы можете узнать из справочника Codrops.

Блочная модель элемента также используется для создания контекста позиционирования для содержимого элемента, где это применимо, или для самого элемента.

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

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

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

Однако в SVG есть единственная система координат, используемая по умолчанию для позиционирования элементов внутри области видимости — текущая система координат, заданная в атрибуте SVG viewBox . Когда элемент необходимо позиционировать внутри SVG, он позиционируется относительно всей области видимости SVG.

Технически в SVG по умолчанию существует две системы координат. Но только одна из них актуальна при работе с позиционированием SVG, если вы явно не измените значения обоих. Если вы не знакомы с системой координат SVG, их созданием и использованием, я настоятельно рекомендую ознакомиться с этой статьей, прежде чем продолжать дальше. В этой статье мы будем исходить из обычных условий, в которым нам достаточно одной системы координат.

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

Ответ: вложенные SVG.

Вложение SVG

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

Вы можете вкладывать SVG в другой SVG. И потом поместить результат в следующий SVG и так далее, сколько хотите.

Вы можете вкладывать SVG настолько глубоко, насколько хотите. Количество уровней вложенности зависит от того, что вы хотите сделать и что вам нужно или не нужно. Лично я не сталкивалась с необходимостью вкладывать SVG больше, чем на два уровня.

Несколько замечаний о вложении SVG

  • Внутренний элемент не требует задания пространства имен ( xmlns ), так как по умолчанию предполагается, что он находится в том же пространстве имен, что и внешний . И даже внешний (корневой) не требует задания пространства имен, если он встроен в документ HTML5.
  • Вы можете использовать вложение SVG для группирования элементов и последующего позиционирования в родительском SVG. Конечно, вы можете группировать элементы внутри SVG, используя тег группировки , но использование вместо этого имеет свои преимущества, такие как возможность задавать ширину и высоту всей группы, а также позиционировать с помощью абсолютных значений x и y вместо использования трансформаций. Задав ширину и высоту , вы ограничиваете содержимое границами области видимости (которая задается атрибутами width и height ), весь контент выходящий за пределы будет обрезан.
  • Значения в процентах, заданные для элементов, вложенных в будут расчитываться относительно именно этого , а не корневого. В то же время значения в процентах, заданные внутреннему рассчитываются относительно корневого.

Зачем вкладывать ?

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

Таким примером является следующий рисунок, изображающий маленькую птичку внутри яйца.

птичка внутри яйца

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

Изменение размера отзывчивого SVG в браузере

Изменение размера отзывчивого SVG в браузере, уменьшает SVG без воздействия на позиционирование и пространственные отношения между содержимым внутри него

Вкладывая элементы SVG, мы можем создавать отдельные “слои” внутри корневого , которые затем можно контролировать таким образом, что содержимое этих слоев будем менять позицию относительно корневого при изменении размеров области видимости. Делая так, мы можем показывать и прятать различные порции контента внутри SVG так, как мы хотим.

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

3 слоя в svg из первого примера

Этот эффект достигается путем использования в каждом из вложенных SVG разных значений preserveAspectRatio . Это обеспечивает “приклеивание” содержимого каждого SVG (т.е. каждого слоя) к корневому SVG, таким образом раскрывая содержимое между ними.

Я написала детальную статью о том, как добиться этого, вот она (пример с птицей из этой статьи).

Относительное позиционирование в SVG с помощью вложенных svg

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

Но как именно вложенный SVG дает нам возможность позиционирования элемента относительно другого элемента, не svg?

Перед тем как ответить на этот вопрос, нам надо понять, что является ограничивающий блоком (Bounding Box) у элементов SVG.

Что такое ограничивающий блок

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

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

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

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

ограничивающий блок

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

Три вида ограничивающих блоков могут быть рассчитаны для элемента:

  1. Ограничивающий блок объекта это блок, содержащий только геометрическую форму элемента.
  2. Ограничивающий блок обводки это блок, содержащий геометрическую форму элемента и форму обводки.
  3. Декорированный ограничивающий блок это блок, содержащий геометрическую форму элемента, форму обводки и маркеры.

Ограничивающий блок элемента характеризуется свойствами, которые могут быть извлечены при помощи метода getBBox() (эквивалент в SVG getBoundingClientRect(): x , y , width и height ).

var svgElement = document.getElementById('el'); bbox = svgElement.getBBox(); console.log( bbox.x ) ; console.log( bbox.y ) ; console.log( bbox.width ) ; console.log( bbox.height ) ; 

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

Более конкретно: мы будем создавать и использовать внутренний для установки новой системы координат вокруг элемента. Свойства будут определяться свойствами ограничивающего блока элемента — x , y , width и height .

Создание новой системы координат вокруг элемента SVG

Предположим, у нас есть следующее изображение SVG (позаимствовано с Vecteezy) с птицей и гнездом:

Итак, птица хочет попасть в гнездо. Мы можем поместить птицу над гнездом, задав позицию внутри SVG с помощью системы координат холста SVG.

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

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

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

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

Для определения сдвига позиции (его x и y внутри корневого SVG) и его измерений, мы будем использовать свойства ограничивающего блока гнезда.

Позиция — значения x и y , будут равны значениям x и y ограничивающего блока гнезда. Имеется в виду ограничивающий блок группы элементов, формирующих гнездо (у групп также как и у отдельных элементов могут быть ограничивающие блоки). У внутреннего SVG есть явно заданные ширина и высота, равные ширине и высоте ограничивающего блока гнезда.

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

Ограничивающий блок гнезда

Но на изображении выше птица еще расположена в левом верхнем углу. Вот как она накладывается на изображение гнезда:

Наложение птицы на гнездо

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

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

Также стоит обратить внимание на то, что хотя внутреннему SVG явно заданы ширина и высота ограничивающего блока гнезда, лапки птицы обрезаны потому что она так позиционирована. Если в ваших проектах есть другие элементы или больше элементов, с ними может произойти то же самое. Это совсем не то, что вам нужно. Чтобы разобраться с этим, вам надо явно задать стиль overflow: visible для внутреннего SVG. Это гарантирует, что внутренний SVG будет вести себя только как контекст позиционирования, а не как контейнер, ограничивающий отображение содержимого в этой области.

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

Bird & Nest

Также как у корневого SVG, значение viewBox внутреннего SVG с #coord-sys определяется его размерами.

Далее нам надо позиционировать птицу внутри новой системы координат. Я больше не буду упоминать в тексте термин “внутренний SVG”, в соответствии с кодом он у нас svg#coord-sys .

Так как мы позиционируем птицу внутри svg#coord-sys , нам нужна возможность задать позицию для всей группы элементов, формирующих птицу, ведь она не просто один элемент, а группа форм. И мы позиционируем группу, а не один элемент. Группа элементов, формирующих птицу, обернута тегом .

В чем наша проблема — у элемента нет атрибутов x и y . Поэтому мы не можем просто сдвинуть его на определенную позицию с их помощью:

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

А мы хотим имитировать позиционирование элементов в CSS относительно друг друга. Так сказать “сдвинуть группу элементов на позицию (x, y) внутри соответствующего контекста позиционирования”.

Так как у нет атрибутов x и y , мы заменим его другим .

 Bird & Nest 

SVG, оборачивающему птицу, задан ID bird. Этот svg в противоположность своему предку, будет работать исключительно контейнером, даже несмотря на то, что он создает новую систему координат — мы не будем ею пользоваться. Используя этот svg , мы теперь можем сдвинуть птицу внутри новой системы координат, установленной вокруг (на вершине) гнезда.

Теперь пришло время удалить лишнее пустое пространство рядом с птицей. svg#bird обладает теми же размерами и областью видимости, что и оборачивающий его svg#coord-sys — это значит, что при сдвиге птицы нам надо учитывать это пустое пространство. И если мы захотим сдвинуть птицу в левый верхний угол системы, мы не можем просто задать x и y равными нулю — чтобы добиться этого, нам нужен отрицательный отступ в обоих направлениях. Это не практично, ведь нам придется учитывать этот сдвиг каждый раз при позиционировании птицы.

А вот теперь вам надо не только что-то слышать о viewBox , но и понимать, как он работает. Если у вас с этим проблемы, уделите время ознакомлению с этой статьей.

Мы изменим значение viewBox в svg#bird для обрезки пустого пространства. Мы собираемся использовать систему координат svg#bird , но только совсем немного.

По умолчанию, вложенный SVG занимает 100% ширины и высоты контейнера, если вы явно не зададите иное.

Поэтому у svg#bird сейчас такие же размеры, как и у svg#coord-sys (на изображении ниже у него розовая рамка):

Сравнение размеров вложенного SVG и контейнера

Нам не нужно, чтобы размеры отличались в этом примере, поэтому мы оставим их как есть.

Изображение выше также показывает, количество пустого пространства, на которое птица сдвигается внутри svg . Чтобы отменить сдвиг, мы изменим значение viewBox в svg#bird для обрезки пустого пространства.

Это сдвинет птицу так, что она будет расположена в верхнем левом углу системы координат. Я уберу фокус с svg#bird на следующем изображении, там будет показана только система координат гнезда и новое место птицы внутри нее.

Птица расположена в левом верхнем углу системы координат

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

И получим следующий результат:

птица позиционирована на 50% по осям полученной системы координат

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

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

Да, это не самый простой процесс, но если у вас есть хорошее понимание системы координат SVG и работы viewBox , то это не так уж и сложно.

Вот работающее демо примера с птицей и гнездом, птица размещена на краю гнезда:

See the Pen AXRRZd by prgssr (@prgssr) on CodePen.

Заключение

В этой статье использован очень специфичный пример и, надо признать, это не самый частый случай на практике. У вас могут быть ситуации совершенно отличные от описанной. Вы можете работать с SVG, в которых вам совсем не понадобиться обрезка viewBox . Если вы создаете SVG самостоятельно, вы можете позиционировать свой элемент (типа птицы виз моего примера) в левом верхнем углу холста SVG и при обертывании другим SVG, он будет также позиционироваться в левом верхнем углу и вам не надо будет ничего обрезать. Я сделала этот пример немного более сложным, чтобы покрыть большую часть возможных сценариев (и потому что мне было немного лень редактировать SVG в Illustrator после написания половины статьи).

Главное понять, как имитировать относительное позиционирования с помощью вложенных SVG. Этот принцип не зависит от того, сколько уровней вложенности вы используете: один, два или больше.

Эта техника полезна для позиционирования элементов пользовательского интерфейса в формате 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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *