SVG как фоновое изображение, встроенное в атрибут style - PullRequest
1 голос
/ 24 апреля 2019

Я пытаюсь встроить SVG в качестве фонового изображения div. Это прекрасно работает в таблице стилей:

div {
  background-image:
    url('data:image/svg+xml;charset=utf8,<svg width="30" height="25" viewBox="0 0 30 25" fill="none" xmlns="http://www.w3.org/2000/svg" version="1.1"><path d="M3 14.0204L10.8806 21L27 3" stroke="%231CDFAF" stroke-width="5" stroke-linecap="round"/></svg>');
}

Поскольку я использую язык шаблонов с PHP, мне нужно сделать stroke SVG-динамическим. Чтобы сделать его динамичным, я пытаюсь встроить фоновое изображение SVG в атрибут стиля HTML, но не могу экранировать символы " в SVG.

Что я пробовал:

Встраивание без выхода

<div
  style="background-image: url('data:image/svg+xml;charset=utf8,<svg width="30" height="25" viewBox="0 0 30 25" fill="none" xmlns="http://www.w3.org/2000/svg" version="1.1"><path d="M3 14.0204L10.8806 21L27 3" stroke="%231CDFAF" stroke-width="5" stroke-linecap="round"/></svg>');"
>
</div>

Добавление \ перед каждым "

<div
  style="background-image: url('data:image/svg+xml;charset=utf8,<svg width=\"30\" height=\"25\" viewBox=\"0 0 30 25\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"><path d=\"M3 14.0204L10.8806 21L27 3\" stroke=\"%231CDFAF\" stroke-width=\"5\" stroke-linecap=\"round\"/></svg>');"
>
</div>

Замена " на %22

<div
  style="background-image: url('data:image/svg+xml;charset=utf8,<svg width=%2230%22 height=%2225%22 viewBox=%220 0 30 25%22 fill=%22none%22 xmlns=%22http://www.w3.org/2000/svg%22 version=%221.1%22><path d=%22M3 14.0204L10.8806 21L27 3%22 stroke=%22%231CDFAF%22 stroke-width=%225%22 stroke-linecap=%22round%22/></svg>');"
>
</div>

Можно ли избежать этого встроенного SVG?

Ответы [ 2 ]

3 голосов
/ 24 апреля 2019

Использовать экранирование HTML внутри значения атрибута: &quot; для двойной кавычки и (в этом случае нет необходимости, но если возникает необходимость) &apos; для одиночной кавычки.

<div
  style="background-image: url('data:image/svg+xml;charset=utf8,<svg width=&quot;30&quot; height=&quot;25&quot; viewBox=&quot;0 0 30 25&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; version=&quot;1.1&quot;><path d=&quot;M3 14.0204L10.8806 21L27 3&quot; stroke=&quot;%231CDFAF&quot; stroke-width=&quot;5&quot; stroke-linecap=&quot;round&quot;/></svg>');"
>
<br style="line-height:25px">
</div>

(Обратите внимание, что мне пришлось дать div некоторый контент, чтобы сделать фон видимым; в противном случае его высота была бы равна 0. Но это только для фрагмента здесь.)

Редактировать: как отмечено в комментариях, код также работает, когда вы используете %22 для кавычек вместо &quot;.

<div
  style="background-image: url('data:image/svg+xml;charset=utf8,<svg width=%2230%22 height=%2225%22 viewBox=%220 0 30 25%22 fill=%22none%22 xmlns=%22http://www.w3.org/2000/svg%22 version=%221.1%22><path d=%22M3 14.0204L10.8806 21L27 3%22 stroke=%22%231CDFAF%22 stroke-width=%225%22 stroke-linecap=%22round%22/></svg>');"
>
<br style="line-height:25px">
</div>

Значит, что-то еще могло пойти не так в вашем коде? Ваш div имеет рост?

0 голосов
/ 24 апреля 2019

Для более сложного SVG вам нужно избегать не только кавычек.

Проект, с которым я работал, написан на языке шаблонов Twig, который поставляется с escape фильтр, который можно использовать с html_attr.

Например:

<div
  style="background-image: url('data:image/svg+xml;charset=utf8,{{ '<svg>...</svg>' | escape('html_attr') }}');"
>
</div>

Код для escape('html_attr') можно найти здесь: https://github.com/twigphp/Twig/blob/8a78e8bd20f228469cba345284ef8496f84010dd/src/Extension/CoreExtension.php#L1117

Этопо сути, экранирует любой символ, который не соответствует этому регулярному выражению: [^a-zA-Z0-9,\.\-_]

Основные символы, необходимые для экранирования:

"    &quot;
&    &amp;
<    &lt;
>    &gt;

Следующий JavaScript может использоваться как утилита для выхода из SVGстрока для использования в качестве атрибута HTML:

function escapeHtmlAttr(str) {
  return str.replace(/["&<>]/g, char => {
    switch (char) {
      case '"':
        return '&quot';

      case '&':
        return '&amp';

      case '<':
        return '&lt';

      case '>':
        return '&gt';
    }
    return char;
  });
}

// Usage
const str = `<svg>...</svg>`;           // Your SVG
const escapedStr = escapeHtmlAttr(str); // Escaped SVG
...