Как правильно вставлять SVG


    Как правильно вставлять SVG?

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


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


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

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


    <svg width="20">
      <rect fill="#fc0" width="20" height="20"/>
      <line stroke="black" x1="0" y1="0" x2="20" y2="20"/>
    </svg>

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


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


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


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


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


    <img src="picture.svg" alt="За стеклом">

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


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


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

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


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


    <object type="image/svg+xml" data="picture.svg">
      <img src="picture.png" alt="Фолбэк">
    </object>

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


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


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


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


    <h1>Квадрат</h1>
    <svg width="20" height="20">
        <rect fill="#fc0" width="20" height="20"/>
    </svg>

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


    <style>
      rect:hover {
        fill: #090;
      }
    </style>
    <svg>
      <rect fill="#fc0"/>
    </svg>

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


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


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


    Видеоверсия



    Вопросы можно задавать здесь.

    HTML Academy 152,17
    Интерактивные онлайн-курсы
    Поделиться публикацией

    Вакансии компании HTML Academy

    • Front-end developer
      от 60 000 до 100 000 руб.
      Санкт-Петербург Полный рабочий день
    Комментарии 11
    • 0
      А как работает взаимодействие через object?
      Если «стекло разбивается», то значит можно через условный hover менять цвет линий SVG иконки?
      • +4

        У меня де-жа-вю?
        Не далее как позавчера я гуглил эту тему и нашёл вот что https://habrahabr.ru/post/260645/
        Те же четыре способа, только слегка подробнее и в 15 году.

        • 0
          Есть и более ранние посты — habrahabr.ru/post/111682
          FF нормально стал обрабатывать способ вставки через #img меньше года назад.
          Обрезка, масштабирование, смещение и прочие фокусы не просто игнорировались, а выдавали квадраты Малевича.
        • –1

          Вольф говорит:
          — Недавно прочел «Технологию секса». Плохая книга. Без юмора.
          — Что значит — без юмора? Причем тут юмор?
          — Сам посуди. Открываю первую страницу, написано — «Как правильно вставлять SVG». Разве так можно?»

          • 0
            Ещё можно упомянуть о недостатке inline-вставки, такие svg не кэшируются, и если на странице много сложных изображений, то она будет довольно увесистой
            • 0
              gzip по идее это решает, ему только это и подавай)

              как правило svg — это иконки в основном, а если векторная иллюстрация по настоящему сложная — то выгоднее, наверное, переводить в jpeg/png (от задачи зависит конечно же)
            • 0
              Так, постойте. Вот пример, внизу иконки fractal-group.ru/mashinnaya-shtukaturka они вставлены в коде, тут gzip вроде никак не поможет. Пришлось делать такую вставку, чтобы удобно управлять через css издалека.
              • 0
                Гзип поможет, но можно и асинхронно подгружать содержимое свг (по атрибуту src у img) и заменять им картинку. Т.е. если JS отключен, то просто ховеров не будет, а если включен, то вместо img загрузится полноценный svg-код и верти его как хочешь.
                • 0
                  1) Хорошая идея для большей кроссбраузерности.
                  2) Но как всё же поможет gzip, если мы просто запрашиваем с него урла содержимое svg файла, чтобы его вставить? Насколько я знаю gizp помогает только в тех случаях когда мы подключаем файл через src/url/link (ну и разумеется если на этот mime type настроено сжатие на сервере).

                  Если я прав, то изначальный мой коммент был к тому, что до сих пор есть проблема с удобством. Хочешь легко управлять svg вставляй содержимое, хочешь скорость, кэширование подключай файлом
                  • 0
                    Гзип поможет, если свг вставлен в коде (инлайн) — сожмётся вместе с остальным хтмл.
                    Если запрашивать асинхронно, то файл будет отдаваться из кэша, а потом вставляться в хтмл инлайном. Т.е. и кэш, и управление, но без js не работает.
                    Впрочем, гзип должен работать и для файла.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое