Можно ли использовать встроенное определение SVG в CSS?
Я имею в виду что-то вроде:
.my-class {
background-image: <svg>...</svg>;
}
Да, это возможно. Попробуйте следующее:
body { background-image:
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><linearGradient id='gradient'><stop offset='10%' stop-color='%23F00'/><stop offset='90%' stop-color='%23fcc'/> </linearGradient><rect fill='url(%23gradient)' x='0' y='0' width='100%' height='100%'/></svg>");
}
(Обратите внимание, что для этого нужно сохранить URL-адрес SVG, например, #
заменяется на %23
.)
Это работает в IE 9 (который поддерживает SVG). URL-адреса данных также работают в более старых версиях IE (с ограничениями), но они не поддерживают SVG.
Немного поздно, но если кто-то из вас сходит с ума, пытаясь использовать встроенный SVG в качестве фона, приведенные выше предложения не работают. Во-первых, он не работает в IE, и в зависимости от содержимого вашего SVG техника вызовет проблемы в других браузерах, таких как FF.
Если base64 кодирует svg (не весь URL-адрес, только тег svg и его содержимое!), он работает во всех браузерах. Вот пример jsfiddle в base64: http://jsfiddle.net/vPA9z/3/
Теперь CSS выглядит так:
body { background-image:
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+PGxpbmVhckdyYWRpZW50IGlkPSdncmFkaWVudCc+PHN0b3Agb2Zmc2V0PScxMCUnIHN0b3AtY29sb3I9JyNGMDAnLz48c3RvcCBvZmZzZXQ9JzkwJScgc3RvcC1jb2xvcj0nI2ZjYycvPiA8L2xpbmVhckdyYWRpZW50PjxyZWN0IGZpbGw9J3VybCgjZ3JhZGllbnQpJyB4PScwJyB5PScwJyB3aWR0aD0nMTAwJScgaGVpZ2h0PScxMDAlJy8+PC9zdmc+");
Не забудьте удалить любое экранирование URL перед преобразованием в base64. Другими словами, приведенный выше пример показал color = '# fcc', преобразованный в color = '% 23fcc', вы должны вернуться к #.
Причина, по которой base64 работает лучше, заключается в том, что он устраняет все проблемы с помощью одиночных и двойных кавычек и скрытия URL
Если вы используете JS, вы можете использовать window.btoa()
для создания вашего svg base64; и если он не работает (он может жаловаться на недопустимые символы в строке), вы можете просто использовать https://www.base64encode.org/.
Пример установки фона div:
var mySVG = "<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><linearGradient id='gradient'><stop offset='10%' stop-color='#F00'/><stop offset='90%' stop-color='#fcc'/> </linearGradient><rect fill='url(#gradient)' x='0' y='0' width='100%' height='100%'/></svg>";
var mySVG64 = window.btoa(mySVG);
document.getElementById('myDiv').style.backgroundImage = "url('data:image/svg+xml;base64," + mySVG64 + "')";
html, body, #myDiv {
width: 100%;
height: 100%;
margin: 0;
}
<div id="myDiv"></div>
С помощью JS вы можете генерировать SVG на лету, даже изменяя его параметры.
Одна из лучших статей по использованию SVG находится здесь: http://dbushell.com/2013/02/04/a-primer-to-front-end-svg-hacking/
Надеюсь, что это поможет
Mike
Для людей, которые все еще борется, мне удалось заставить эту работу работать со всеми современными браузерами IE11 и выше.
base64 не был для меня вариантом, потому что я хотел использовать SASS для создания значков SVG на основе любого заданного цвета. Например: @include svg_icon(heart, #FF0000);
Таким образом, я могу создать определенный значок в любом цвете и только встраивать SVG-форму один раз в CSS. (с базой64 вам придется встроить SVG в каждый отдельный цвет, который вы хотите использовать)
Есть три вещи, о которых вам нужно знать:
URL ENCODE YOUR SVG
Как и другие, вам необходимо URL-кодировать всю строку SVG, чтобы она работала в IE11. В моем случае я не учитывал значения цвета в полях, таких как fill="#00FF00"
и stroke="#FF0000"
, и заменил их на переменную SASS fill="#{$color-rgb}"
, чтобы их можно было заменить цветом, который я хочу. Вы можете использовать любой онлайн-конвертер для URL-кодирования остальной строки. В итоге вы получите строку SVG:
% 3Csvg %20xmlns% 3D% 27http% 3A% 2F% 2Fwww.w3.org% 2F2000% 2Fsvg% 27 %20viewBox% 3D% 270 %200 %20494,572 %20494,572% 27 %20width% 3D% 27512% 27 %20height% 3D% 27512% 27% 3E% 0A %20 %20% 3Cpath %20d% 3D% 27M257.063 %200C127.136 %200 %2021,808 %20105,33 %2021,808 %20235.266c0 %2041,012 %2010,535 %2079,541 %2028,973 %20113,104 L3.825 %20464.586c345 %2012,797 %2041,813 %2012,797 %2015,467 %200 %2029.872-4.721 %2041.813-12.797v158.184z% 27 %20fill% 3D% 27 # {$ цветной RGB}% 27% 2F% 3E% 3C% 3E% 2Fsvg
ОШИБКА UTF8 CHARSET В URL-адресе данных При создании URL-адреса данных вам нужно оставить кодировку для работы в IE11.
НЕ background-image: url (data: image/svg + xml; utf-8,% 3Csvg% 2....)
НО background-image: url (data: image/svg + xml,% 3Csvg% 2....)
ИСПОЛЬЗОВАТЬ RGB() ВМЕСТО цветов HEX Firefox не нравится # в SVG-коде. Поэтому вам нужно заменить шестнадцатеричные значения цвета на RGB.
НЕ fill = "# FF0000"
НО fill = "rgb (255,0,0)"
В моем случае я использую SASS для преобразования данного гексагона в действительное значение rgb. Как указано в комментариях, лучше всего URL-кодировать вашу строку RGB (так что запятая становится% 2C)
@mixin svg_icon($id, $color) {
$color-rgb: "rgb(" + red($color) + "%2C" + green($color) + "%2C" + blue($color) + ")";
@if $id == heart {
background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20494.572%20494.572%27%20width%3D%27512%27%20height%3D%27512%27%3E%0A%20%20%3Cpath%20d%3D%27M257.063%200C127.136%200%2021.808%20105.33%2021.808%20235.266c0%204%27%20fill%3D%27#{$color-rgb}%27%2F%3E%3C%2Fsvg%3E');
}
}
Я понимаю, что это может быть не лучшее решение для очень сложного SVG (встроенный SVG никогда не будет в этом случае), но для плоских значков только с несколькими цветами это действительно отлично работает.
Мне удалось оставить все растровое изображение спрайта и заменить его встроенным SVG в моем CSS, который, как оказалось, только около 25 кбайт после сжатия. Таким образом, это отличный способ ограничить количество запросов, которые должен выполнять ваш сайт, без раздувания вашего файла CSS.
rgb(255,0,0)
должен стать rgb(255%2C0%2C0)
после кодирования.
В Mac/Linux вы можете легко преобразовать SVG файл в кодированное значение base64 для атрибута фона CSS с помощью этой простой команды bash:
echo "background: transparent url('data:image/svg+xml;base64,"$(openssl base64 < path/to/file.svg)"') no-repeat center center;"
Протестировано на Mac OS X. Таким образом, вы также избегаете беспорядочного выхода из URL.
Помните, что base64-кодировка SVG файла увеличивает его размер, см. сообщение в блоге css-tricks.com.
Я разветкил демо-версию CodePen, которая имела ту же проблему с внедрением встроенного SVG в CSS. Решение, которое работает с SCSS, заключается в создании простой функции кодирования url.
Функция замены строк может быть создана из встроенных функций str-slice, str-index (см. css-tricks, благодаря Hugo Giraudel).
Затем просто замените %
, <
, >
, "
, '
, на коды
%xx
:
@function svg-inline($string){
$result: str-replace($string, "<svg", "<svg xmlns='http://www.w3.org/2000/svg'");
$result: str-replace($result, '%', '%25');
$result: str-replace($result, '"', '%22');
$result: str-replace($result, "'", '%27');
$result: str-replace($result, ' ', '%20');
$result: str-replace($result, '<', '%3C');
$result: str-replace($result, '>', '%3E');
@return "data:image/svg+xml;utf8," + $result;
}
$mySVG: svg-inline("<svg>...</svg>");
html {
height: 100vh;
background: url($mySVG) 50% no-repeat;
}
Существует также image-inline
вспомогательная функция, доступная в Compass, но поскольку она не поддерживается в CodePen, это решение, вероятно, может быть полезно.
Демо на CodePen: http://codepen.io/terabaud/details/PZdaJo/
<svg><path></svg>
в верхнюю часть textarea, и он будет напрямую выводить очищенный путь в значении url()
.
Я нашел одно решение для SVG. Но это работа только для Webkit, я просто хочу поделиться с вами своим обходным путем. В моем примере показано, как использовать элемент SVG из DOM в качестве фона через фильтр (background-image: url ('# glyph') не работает).
Функции, необходимые для визуализации иконки SVG:
.test {
/* background-image: url('#glyph');
background-size:100% 100%;*/
filter: url(#image);
height:100px;
width:100px;
}
.test:before {
display:block;
content:'';
color:transparent;
}
.test2{
width:100px;
height:100px;
}
.test2:before {
display:block;
content:'';
color:transparent;
filter: url(#image);
height:100px;
width:100px;
}
<svg style="height:0;width:0;" version="1.1" viewbox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="glyph">
<path id="heart" d="M100 34.976c0 8.434-3.635 16.019-9.423 21.274h0.048l-31.25 31.25c-3.125 3.125-6.25 6.25-9.375 6.25s-6.25-3.125-9.375-6.25l-31.202-31.25c-5.788-5.255-9.423-12.84-9.423-21.274 0-15.865 12.861-28.726 28.726-28.726 8.434 0 16.019 3.635 21.274 9.423 5.255-5.788 12.84-9.423 21.274-9.423 15.865 0 28.726 12.861 28.726 28.726z" fill="crimson"/>
</g>
<svg id="resized-glyph" x="0%" y="0%" width="24" height="24" viewBox="0 0 100 100" class="icon shape-codepen">
<use xlink:href="#glyph"></use>
</svg>
<filter id="image">
<feImage xlink:href="#resized-glyph" x="0%" y="0%" width="100%" height="100%" result="res"/>
<feComposite operator="over" in="res" in2="SourceGraphic"/>
</filter>
</defs>
</svg>
<div class="test">
</div>
<div class="test2">
</div>
Еще одно решение, это использовать url encode
var container = document.querySelector(".container");
var svg = document.querySelector("svg");
var svgText = (new XMLSerializer()).serializeToString(svg);
container.style.backgroundImage = 'url(data:image/svg+xml;utf8,${encodeURIComponent(svgText)})';
.container{
height:50px;
width:250px;
display:block;
background-position: center center;
background-repeat: no-repeat;
background-size: contain;
}
<svg height="100" width="500" xmlns="http://www.w3.org/2000/svg">
<ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" />
</svg>
<div class="container"></div>
Inline SVG, поступающий из сторонних источников (например, диаграммы Google), может не содержать атрибут пространства имен XML (xmlns="http://www.w3.org/2000/svg"
) в элементе SVG (или, возможно, он удаляется после визуализации SVG - ни браузерный инспектор, ни команды jQuery из консоли браузера не показывают пространство имен в элементе SVG).
Если вам нужно повторно использовать эти фрагменты svg для ваших других потребностей (фоновое изображение в CSS или img-элементе в HTML), обратите внимание на недостающее пространство имен. Без браузера пространства имен могут отказаться отображать SVG (независимо от кодировки utf8 или base64).
https://yoksel.github.io/url-encoder/
Этот сайт отлично подходит для этого.. полностью рекомендуется!
Пожалуйста, проверьте этот плункер. простой пример svg и его эффект наведения с использованием переменной
https://plnkr.co/edit/niXFn9FDYK7CyKaeJdJ5?p=preview
.svg-image{
--color:red;
}
<img>
и другими случаями, если SVG представляет собой сочетание нескольких изображений (если они не встроены), см. Фоновое изображение SVG с маской, использующей внешнее изображение, не работает и, в частности, ограничения на SVG используется в качестве изображения .