[css] CSS의 인라인 SVG

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 이스케이프해야합니다 (예 : #로 대체 됨 %23).

이것은 SVG를 지원하는 IE 9에서 작동합니다 . 데이터 URL은 이전 버전의 IE에서도 작동하지만 제한이 있지만 기본적으로 SVG를 지원하지는 않습니다.


답변

조금 늦었지만 인라인 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/

도움이 되었기를 바랍니다

마이크


답변

여전히 어려움을 겪고있는 사람들을 위해 모든 최신 브라우저 IE11 이상 에서이 작업을 수행 할 수있었습니다.

base64는 SASS를 사용하여 주어진 색상을 기반으로 SVG 아이콘을 생성하기를 원했기 때문에 선택의 여지가 없었습니다. 예를 들어 : @include svg_icon(heart, #FF0000);이렇게하면 어떤 색상 으로든 특정 아이콘을 만들 수 있으며 CSS에 SVG 모양을 한 번만 포함하면됩니다. (base64를 사용하려면 사용하려는 모든 단일 색상으로 SVG를 포함해야합니다)

알아야 할 세 가지가 있습니다.

  1. 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


  1. 데이터 URL에서 UTF8 문자 세트 생략 데이터 URL을 작성할 때 IE11에서 작동하려면 문자 세트를 생략해야합니다.

    NOT background-image : url (data : image / svg + xml; utf-8, % 3Csvg % 2 ….)
    그러나 배경 이미지 : url (data : image / svg + xml, % 3Csvg % 2 … .)


  1. 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 파일을 부 풀리지 않고 사이트에서 수행해야 할 요청의 양을 제한하는 좋은 방법입니다.


답변

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-inlineCompass 에는 도우미 기능 도 있지만 CodePen에서는 지원되지 않으므로이 솔루션이 유용 할 수 있습니다.

CodePen 데모 : http://codepen.io/terabaud/details/PZdaJo/


답변

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 아이콘 렌더링에 필요한 기능 :

  1. CSS를 사용하여 HTML 요소에 SVG 필터 효과 적용 (IE 및 Edge는 지원하지 않음)
  2. 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>

하나 더 해결책은 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>