在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>");
}
http://jsfiddle.net/6WAtQ/ (注意,SVG內容需要進行url轉義才能工作,例如#被替換為%23。)
這在IE 9(支持SVG)中是可行的。數據URL在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轉義。換句話說,上面的例子顯示color='#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>
# # #我的解決方案是https://yoksel.github.io/url-encoder/ 您只需簡單地插入您的svg并獲得背景圖像代碼
# # #對于仍在掙扎的人,我設法讓它在所有現代瀏覽器IE11和更高版本上工作。
base64不是我的選擇,因為我想使用SASS根據任何給定的顏色生成SVG圖標。比如:@include svg_icon(heart,# ff 0000);這樣我就可以創建任何顏色的圖標,并且只需要在CSS中嵌入一次SVG形狀。(對于base64,您必須將SVG嵌入到您想要使用的每一種顏色中)
有三件事你需要知道:
URL編碼您的SVG 正如其他人建議的那樣,您需要對整個SVG字符串進行URL編碼,以便在IE11中工作。在我的例子中,我省略了fill="#00FF00 "和stroke="#FF0000 "等字段中的顏色值,并用一個SASS變量fill="#{$color-rgb} "來替換它們,這樣就可以用我想要的顏色替換它們。您可以使用任何在線轉換器對字符串的其余部分進行URL編碼。您將得到這樣一個SVG字符串:
% 3c SVG % 20 xmlns % 3D % 27 http % 3A % 2F % 2fwww . w3 . org % 2f 2000% 2 fsvg % 27% 20查看框% 3D % 270% 200% 20494.572% 20494.572% 27% 20寬度% 3D % 27512% 27% 20高度% 3D % 27512% 27% 3E % 0A % 20% 20% 3c路徑%
忽略數據URL中的UTF8字符集在創建數據URL時,您需要忽略該字符集,以便它在IE11中工作。
不是后臺-圖片:url(數據:圖片/SVG+XML;utf-8,%3Csvg%2....) 但背景-圖像:url(數據:圖像/svg+xml,%3Csvg%2....)
使用RGB()代替十六進制顏色,Firefox不喜歡SVG代碼中的#顏色。所以你需要用RGB值替換你的顏色十六進制值。
未填充="#FF0000 " 但是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從來不是這種情況),但是對于只有幾種顏色的平面圖標來說,這真的很棒。
我可以省去整個sprite位圖,并在我的CSS中用內聯SVG替換它,壓縮后只有25kb左右。因此,這是一個很好的方法來限制你的網站必須做的請求數量,而不會膨脹你的CSS文件。
# # #在Mac/Linux上,您可以使用這個簡單的bash命令輕松地將SVG文件轉換為CSS背景屬性的base64編碼值:
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)。
然后,只需替換%,& lt,& gt,",',帶有%xxcodes:
@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中還有一個圖像內嵌幫助函數,但是由于CodePen不支持它,這個解決方案可能會有用。
CodePen上的演示:http://codepen.io/terabaud/details/PZdaJo/
# # #我為SVG找到了一個解決方案。但是它只適用于Webkit,我只是想和你分享我的解決方法。在我的示例中,展示了如何通過過濾器使用DOM中的SVG元素作為背景(background-image: url('#glyph ')不起作用)。
此SVG圖標渲染所需的功能:
使用CSS將SVG濾鏡效果應用于HTML元素(例如 邊緣不支持) feImage片段加載支持(firefox不支持 支架)
.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>
# # #來自第三方來源(如Google charts)的內聯svg在SVG元素中可能不包含XML名稱空間屬性(xmlns = " http://www . w3 . org/2000/SVG ")(或者在呈現SVG后它可能會被刪除-瀏覽器檢查器和來自瀏覽器控制臺的jQuery命令都不會顯示SVG元素中的名稱空間)。
當您需要將這些svg片段用于其他用途時(CSS中的背景圖像或HTML中的img元素),請注意丟失的名稱空間。如果沒有名稱空間,瀏覽器可能會拒絕顯示SVG(不管編碼是utf8還是base64)。
# # #如果你正在使用postcss,你可以試試postcss-inline-svg插件https://www.npmjs.com/package/postcss-inline-svg
.up {
background: svg-load('img/arrow-up.svg', fill: #000, stroke: #fff);
}
.down {
background: svg-load('img/arrow-down.svg', fill=#000, stroke=#fff);
}
# # #基于已經提到的https://github.com/yoksel/url-encoder/所采用的方法以編程方式完成:
// Svg (string)
const hexagon = `
<svg
width="100"
height="20"
viewBox="0 0 100 20"
xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient
id="redyel"
gradientUnits="objectBoundingBox"
x1="0"
y1="0"
x2="1"
y2="1"
>
<stop offset="0%" stop-color="#ff0000" />
<stop offset="100%" stop-color="#ffff00" />
</linearGradient>
</defs>
<polygon
points="0,10 5,0 95,0 100,10 95,20 5,20"
fill="#eee"
stroke="url(#redyel)"
/>
</svg>
`
// svgToBackgroundImage
const symbols = /[%#()<>?[\\\]^`{|}]/g;
const newLine = /\r?\n/;
const notEmptyString = (str) => str.length;
const trim = (str) => str.trim();
const toOneLine = (str) =>
str.split(newLine).filter(notEmptyString).map(trim).join(" ");
function addNameSpace(svgString) {
if (svgString.indexOf(`http://www.w3.org/2000/svg`) < 0) {
svgString = svgString.replace(
/<svg/g,
`<svg xmlns="http://www.w3.org/2000/svg"`
);
}
return svgString;
}
function encodeSVG(svgString) {
svgString = svgString.replace(/>\s{1,}</g, `><`);
svgString = svgString.replace(/\s{2,}/g, ` `);
// Using encodeURIComponent() as replacement function
// allows to keep result code readable
return svgString.replace(symbols, encodeURIComponent);
}
const svgToBackgroundImage = (svgString) =>
`url('data:image/svg+xml,${encodeSVG(addNameSpace(toOneLine(svgString)))}')`;
// DOM
const element = document.querySelector("#hexagon");
element.style.backgroundImage = svgToBackgroundImage(hexagon);
#hexagon {
width: 100px;
height: 20px;
}
<div id="hexagon"/>
# # #你也可以這樣做:
<svg viewBox="0 0 32 32">
<path d="M11.333 13.173c0-2.51 2.185-4.506 4.794-4.506 2.67 0 4.539 2.053 4.539 4.506 0 2.111-0.928 3.879-3.836 4.392v0.628c0 0.628-0.496 1.141-1.163 1.141s-1.163-0.513-1.163-1.141v-1.654c0-0.628 0.751-1.141 1.419-1.141 1.335 0 2.571-1.027 2.571-2.224 0-1.255-1.092-2.224-2.367-2.224-1.335 0-2.367 1.027-2.367 2.224 0 0.628-0.546 1.141-1.214 1.141s-1.214-0.513-1.214-1.141zM15.333 23.333c-0.347 0-0.679-0.143-0.936-0.404s-0.398-0.597-0.398-0.949 0.141-0.689 0.398-0.949c0.481-0.488 1.39-0.488 1.871 0 0.257 0.26 0.398 0.597 0.398 0.949s-0.141 0.689-0.398 0.949c-0.256 0.26-0.588 0.404-0.935 0.404zM16 26.951c-6.040 0-10.951-4.911-10.951-10.951s4.911-10.951 10.951-10.951c6.040 0 10.951 4.911 10.951 10.951s-4.911 10.951-10.951 10.951zM16 3.333c-6.984 0-12.667 5.683-12.667 12.667s5.683 12.667 12.667 12.667c6.984 0 12.667-5.683 12.667-12.667s-5.683-12.667-12.667-12.667z"></path>
</svg>