問題描述
是否可以在 CSS 中使用內聯 SVG 定義?
我的意思是:
.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>");
}
(請注意,SVG 內容需要為 url-escaped 才能正常工作,例如 #
被%23
替代。)
This works in IE 9 (which supports SVG)。 Data-URLs 在舊版本的 IE 中工作 (有限制),但是它們本身不支援 SVG 。
次佳解決方案
有點遲了,但是如果你們中的任何一個人都瘋狂地嘗試使用內建 SVG 作為背景,上面的轉義建議並不會奏效。一個,它在 IE 中不起作用,根據 SVG 的內容,該技術會在其他瀏覽器 (如 FF) 中引起麻煩。
如果您對 svg 進行 base64 編碼 (而不是整個 url,只是 svg 標籤及其內容!),它可以在所有瀏覽器中執行。這是在 base64 中相同的 jsfiddle 示例:http://jsfiddle.net/vPA9z/3/
CSS 現在看起來像這樣:
body { background-image:
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+PGxpbmVhckdyYWRpZW50IGlkPSdncmFkaWVudCc+PHN0b3Agb2Zmc2V0PScxMCUnIHN0b3AtY29sb3I9JyNGMDAnLz48c3RvcCBvZmZzZXQ9JzkwJScgc3RvcC1jb2xvcj0nI2ZjYycvPiA8L2xpbmVhckdyYWRpZW50PjxyZWN0IGZpbGw9J3VybCgjZ3JhZGllbnQpJyB4PScwJyB5PScwJyB3aWR0aD0nMTAwJScgaGVpZ2h0PScxMDAlJy8+PC9zdmc+");
記住在轉換為 base64 之前刪除任何轉義的 URL 。換句話說,上面的例子顯示顏色= ‘#fcc’ 轉換為 color = ‘%23fcc’,你應該回去#。
base64 工作更好的原因是它消除了單引號和雙引號和 url 轉義的所有問題
如果您使用 JS,可以使用 window.btoa()
生成您的 base64 svg; 如果它不起作用 (可能會抱怨字串中的無效字元),您可以簡單地使用 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/
希望這可以幫助
麥克風
第三種解決方案
對於仍在努力的人們,我設法讓所有現代瀏覽器 IE11 及以上版本都能正常工作。
base64 對我而言是不可取的,因為我想使用 SASS 根據任何給定的顏色生成 SVG 圖示。例如:@include svg_icon(heart, #FF0000);
這樣我可以建立任何顏色的某個圖示,只需要在 CSS 中嵌入一次 SVG 形狀。 (使用 base64,您必須將 SVG 嵌入到您要使用的每種顏色中)
你需要注意的事情有三件事:
-
URL ENCODE 您的 SVG 如其他人所建議的,您需要對整個 SVG 字串進行 URL 編碼,以使其在 IE11 中工作。在我的情況下,我在
fill="#00FF00"
和stroke="#FF0000"
等欄位中省略了顏色值,並用 SASS 變數fill="#{$color-rgb}"
替換,這樣可以用我想要的顏色代替。您可以使用 any online converter 對字串的其餘部分進行 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.104L3.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#{$ color-rgb}% 27%2F%3E%3C%2Fsvg%3E
-
OMIT 資料 URL 中的 UTF8 CHARSET 建立資料 URL 時,需要省略其在 IE11 中工作的字元集。不是 background-image:url(data:image /svg + xml; utf-8,%3Csvg%2 ….) 但是 background-image:url(data:image /svg + xml,%3Csvg%2 ….)
-
USE RGB() INSTEAD OF HEX 顏色 Firefox 在 SVG 程式碼中不喜歡#。所以你需要用 RGB 替換你的顏色十六進位制值。 NOT fill = “#FF0000” BUT fill = “rgb(255,0,0)”
在我的情況下,我使用 SASS 將給定的十六進位制轉換為有效的 rgb 值。正如在評論中指出的,最好是對你的 RGB 字串進行 URL 編碼 (因此逗號變成%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 從不在這種情況下),但是對於只有幾種顏色的平面圖示,這真的很好用。
我可以省略一個完整的精靈點陣圖,並將其替換為 CSS 中的內聯 SVG,壓縮之後只有 25kb 左右。所以這是一個很好的方式來限制網站的請求量,而不會使你的 CSS 檔案膨脹。
第四種方案
您可以使用此簡單的 bash 命令,將 SVG 檔案輕鬆轉換為 CSS background 屬性的 base64 ecoded 值:
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 blog post
第五種方案
我已經分發了一個 CodePen 演示程式,將嵌入式 SVG 嵌入到 CSS 中也是一樣的。與 SCSS 協同工作的解決方案是構建簡單的 url-encoding 功能。
可以從內建 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;
}
Compass 中還提供了一個 image-inline
輔助功能,但由於它在 CodePen 中不受支援,因此該解決方案可能很有用。
CodePen 演示:http://codepen.io/terabaud/details/PZdaJo/
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。