CSS에서 인라인 SVG 정의를 사용할 수 있습니까?
나는 다음과 같은 것을 의미한다 :
.my-class {
background-image: <svg>...</svg>;
}
<img>
는 SVG가 (포함하지 않는) 여러 이미지의 혼합 태그와 다른 경우 경우를 볼 작동하지 않는 외부 이미지를 사용하여 마스크와 배경 이미지 SVG를 , 특히 SVG에 대한 제한 사용 이미지 .
CSS에서 인라인 SVG 정의를 사용할 수 있습니까?
나는 다음과 같은 것을 의미한다 :
.my-class {
background-image: <svg>...</svg>;
}
<img>
는 SVG가 (포함하지 않는) 여러 이미지의 혼합 태그와 다른 경우 경우를 볼 작동하지 않는 외부 이미지를 사용하여 마스크와 배경 이미지 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 이스케이프해야합니다 (예 : #
로 대체 됨 %23
).
이것은 SVG를 지원하는 IE 9에서 작동합니다 . 데이터 URL은 이전 버전의 IE에서도 작동하지만 제한이 있지만 기본적으로 SVG를 지원하지는 않습니다.
url()
해야합니다. Opera, Firefox 및 Safari에서 잘 작동하는 예제는 jsfiddle.net/6WAtQ 를 참조하십시오 .
조금 늦었지만 인라인 SVG를 배경으로 사용하려고 미쳤다면 위의 탈출 제안이 제대로 작동하지 않습니다. 하나는 IE에서 작동하지 않으며 SVG의 내용에 따라이 기술은 FF와 같은 다른 브라우저에서 문제를 일으킬 수 있습니다.
svg (전체 URL이 아니라 svg 태그와 내용 만!)를 base64로 인코딩하면 모든 브라우저에서 작동합니다. 다음은 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/ 를 사용하면됩니다 .
사업부 배경을 설정하는 예 :
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/
도움이 되었기를 바랍니다
마이크
xmlns
하는 속성 세트 svg
요소를 하기 전에 같은 base64로 인코딩 당신 <svg xmlns="http://www.w3.org/2000/svg">...</svg>
이 :하지의 경우 - SVG는 HTML에 바로 때없이 때때로 브라우저 덩어리를
여전히 어려움을 겪고있는 사람들을 위해 모든 최신 브라우저 IE11 이상 에서이 작업을 수행 할 수있었습니다.
base64는 SASS를 사용하여 주어진 색상을 기반으로 SVG 아이콘을 생성하기를 원했기 때문에 선택의 여지가 없었습니다. 예를 들어 : @include svg_icon(heart, #FF0000);
이렇게하면 어떤 색상 으로든 특정 아이콘을 만들 수 있으며 CSS에 SVG 모양을 한 번만 포함하면됩니다. (base64를 사용하려면 사용하려는 모든 단일 색상으로 SVG를 포함해야합니다)
알아야 할 세 가지가 있습니다.
SVG
URL 인코딩 다른 사람들이 제안했듯이 IE11에서 작동하려면 전체 SVG 문자열을 URL 인코딩해야합니다. 필자의 경우는 다음과 같은 분야의 색상 값을 왼쪽 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.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
데이터 URL에서 UTF8 문자 세트 생략 데이터 URL을 작성할 때 IE11에서 작동하려면 문자 세트를 생략해야합니다.
NOT background-image : url (data : image / svg + xml; utf-8, % 3Csvg % 2 ....)
그러나 배경 이미지 : url (data : image / svg + xml, % 3Csvg % 2 ... .)
RGB () INSTEAD OF HEX 색상 사용 Firefox는 SVG 코드에서 #을 좋아하지 않습니다. 따라서 색상 16 진수 값을 RGB 값으로 바꿔야합니다.
NOT = "="FF0000 "
BUT fill = "rgb (255,0,0)"
필자의 경우 SASS를 사용하여 주어진 16 진수를 유효한 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 파일을 부 풀리지 않고 사이트에서 수행해야 할 요청의 양을 제한하는 좋은 방법입니다.
rgb(255,0,0)
이되어야 rgb(255%2C0%2C0)
인코딩하면.
%23ff0000
#ff0000
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 이스케이프 혼란을 피할 수 있습니다.
SVG 파일을 인코딩하는 SVG 파일은 크기가 커짐을 기억하십시오. css-tricks.com 블로그 게시물을 참조하십시오 .
인라인 SVG를 CSS에 포함시키는 것과 동일한 문제가있는 CodePen 데모를 포크했습니다. SCSS와 함께 작동하는 솔루션은 간단한 URL 인코딩 기능을 구축하는 것입니다.
내장 된 str-slice, str-index 함수에서 문자열 대체 기능을 작성할 수 있습니다 ( Hugo Giraudel 덕분에 css-tricks 참조 ).
그런 다음, 바로 교체 %
, <
, >
, "
, '
, 으로
%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>
상단의 텍스트 영역으로하고, 직접 출력 경로를 소독합니다 url()
값 내에서 .
Google 차트와 같은 타사 소스에서 제공되는 인라인 SVG에는 XML 네임 스페이스 속성 (xmlns="http://www.w3.org/2000/svg"
는 SVG 요소에 )을 (또는 SVG가 렌더링되면 제거 될 수 있습니다. 브라우저 콘솔의 브라우저 관리자 나 jQuery 명령은 SVG 요소에 네임 스페이스를 표시하지 않습니다).
다른 요구 사항 (CSS의 배경 이미지 또는 HTML의 img 요소)을 위해 이러한 svg 스 니펫을 재사용 해야하는 경우 누락 된 네임 스페이스를 조심하십시오. 네임 스페이스가 없으면 브라우저는 인코딩 utf8 또는 base64에 관계없이 SVG 표시를 거부 할 수 있습니다.
SVG에 대한 하나의 솔루션을 찾았습니다. 그러나 그것은 Webkit에서만 작동하며, 해결 방법을 당신과 공유하고 싶습니다. 내 예제에서는 DOM을 통해 SVG 요소를 필터를 통해 배경으로 사용하는 방법을 보여줍니다 (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 인코딩을 사용하는 것입니다.
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>