CSS: использование raw svg в URL-параметре фонового изображения в IE

Итак, я пытаюсь сделать что-то вроде этого:

div {
    width: 100px;
    height: 100px;
    background-position: center center;
    background-repeat: no-repeat;
    background-size: 100px 100px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' style='fill:red; stroke:none'><rect x='0' y='40' width='100' height='20' /><rect x='40' y='0' width='20' height='100' /></svg>");
}

Смотрите здесь: http://jsfiddle.net/trxkcx41/4/

Это прекрасно работает в современных версиях Chrome, Safari (OS X и iOS) и Firefox. Однако SVG вообще не отображается в IE 9, 10 или 11.

Это потому, что это не поддерживается в IE или потому, что я делаю что-то неправильно?

[ОБНОВЛЕНИЕ С РЕШЕНИЕМ]

Благодаря hungerstar, у меня это работает. Чтобы обобщить его рекомендацию, мне нужно было внести следующие изменения:

  • Измените тип данных с data:image/svg+xml;utf8 на data:image/svg+xml;charset=utf8 (т.е. требуется charset=)

  • URL кодирует svg. Чтобы свести к минимуму URL-кодирование, используйте ' вместо ", чтобы заключить атрибуты. Итак, в моем случае необходимо было закодировать только теги < и >.

В конечном итоге мой CSS выглядел так:

    background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' style='fill:red; stroke:none' %3E%3Crect x='0' y='40' width='100' height='20' /%3E%3Crect x='40' y='0' width='20' height='100' /%3E%3C/svg%3E");

Ответы

Ответ 1

IE, похоже, поддерживает использование utf8 в URI данных, это просто более суетливо. Смотрите Сообщение о блоге Codepen для получения более подробной информации, но вот основные моменты:

Автор указывает RFC2397 и выделяет:

данные: [<MediaType> ] [; base64], < данные >

<mediatype> является спецификацией типа интернет-СМИ (с дополнительными параметрами). Внешний вид "; base64" означает, что данные кодируются как base64. Без "base64" данные (в виде последовательности октетов) представлены с использованием ASCII-кодирования для октетов внутри диапазона безопасных URL-адресов и с использованием стандартного xx-шестнадцатеричного кодирования URL-адресов для октетов вне этого диапазона. Если <mediatype> опускается, по умолчанию используется текст /plain; charset = US-ASCII. В качестве сокращенного текста "text/plain" может быть опущен, но предоставлен параметр charset.

  • Большинство браузеров снисходительны к строке charset =, но это необходимо для Internet Explorer. Это означает, что вам нужно использовать ;charset=utf8, вместо ;utf8,.
  • Сверху, без "base64", данные (как последовательность октетов) представлены с использованием ASCII-кодирования для октетов внутри диапазона безопасных URL-адресов и с использованием стандартного шестнадцатеричного кодирования% xx URL-адресов для октетов вне этого ассортимент." Это означает, что вам придется передавать проценты в символы, которые не являются безопасными для URL. Например, от <svg> до %3Csvg%3E. Вы можете свести к минимуму количество процентов кодирования, которое необходимо выполнить, используя одинарные кавычки ' вместо двойных кавычек ".

Ответ 2

Для IE9 я должен URL кодировать весь SVG-код.

Это мой рабочий процесс для фоновых изображений SVG.

Сначала вставьте SVG-код, чтобы его оптимизировать: https://jakearchibald.github.io/svgomg/ ( "разметка пасты" )

Вы можете удалить "viewBox", но убедитесь, что в SVG-коде определены "ширина" и "высота", для этого IE9 требуется для лучшей реализации CSS.

Теперь у вас есть что-то вроде:

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><path d="M0 0h100L50 50"/></svg>

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

fill="#cc0000"

до конца элемента путь (если в группе ( "g" ) есть несколько элементов пути, вы должны поместить этот цвет заливки во все эти. Если SVG имеет штрихи делают то же самое с такими штрихами, как stroke="#cc0000").

Теперь у нас есть следующий код SVG:

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><path d="M0 0h100L50 50" fill="#cc0000"/></svg>

Теперь закодируйте весь код SVG здесь: http://meyerweb.com/eric/tools/dencoder/

чтобы вы получили:

%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22100%22%20height%3D%22100%22%3E%3Cpath%20d%3D%22M0%200h100L50%2050%22%20fill%3D%22%23cc0000%22%2F%3E%3C%2Fsvg%3E

По крайней мере, соединить все это в CSS:

.apple {
    background-image: url('data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22100%22%20height%3D%22100%22%3E%3Cpath%20d%3D%22M0%200h100L50%2050%22%20fill%3D%22%23cc0000%22%2F%3E%3C%2Fsvg%3E');
    }

Некоторые преимущества, которые приводили меня в бешенство:

Обязательно обернуть код фона SVG с помощью ' в CSS, потому что внутри SVG мы используем "!

Обязательно использовать

data:image/svg+xml;charset=UTF-8

ничего другого.

Теперь SVG отображается с цветом "# cc0000" (темно-красный) даже в IE9 на окнах.

С этим URL-кодированным SVG я все еще могу изменить цвет с помощью переменной PHP. Например, я просто заменю "cc0000" на:

<?php echo preg_replace("/#/", "", $textcolor); ?>

Я делаю это для шаблонов WordPress, чтобы клиент мог выбрать цвет значка в бэкэнд.

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

Ответ 3

Только примечание к этому. В IE 11 вы можете использовать charset = utf8. Вам необходимо URL-кодировать не менее < и > (при условии, что вы используете '' для значений атрибутов not "". Также будьте осторожны, если вы используете любые символы, отличные от ASCII. Закодированное значение UTF-8 - то есть найти какой-нибудь инструмент, который даст вам код UTF-8 для символа (например, Babel Map), а затем предоставит его в кодировке URL, т.е. Я хотел отобразить символ (U+25BE). Представление символа UTF-8 \xE2\x96\xBE и %E2%96%BE в кодировке URL.

background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' height='10px' width='15px'%3E%3Ctext x='0' y='10' fill='gray'%3E%E2%96%BE%3C/text%3E%3C/svg%3E");

Ответ 4

Это решение работает хорошо для меня, я использую charset = utf8 вместо utf8.