외부 CSS로 SVG 스타일을 지정하는 방법은 무엇입니까?


102

각 SVG 파일 내에서 직접적으로가 아니라 외부 스타일 시트를 통해 색상을 수정하고 싶은 여러 SVG 그래픽이 있습니다. 그래픽을 인라인으로 넣지 않고 내 이미지 폴더에 저장하고 가리키고 있습니다.

툴팁이 작동 할 수 있도록 이러한 방식으로 구현 <a>했으며 링크를 허용하기 위해 각각을 태그로 래핑했습니다 .

<a href='http://youtube.com/...' target='_blank'><img class='socIcon' src='images/socYouTube.svg' title='View my videos on YouTube' alt='YouTube' /></a>

다음은 SVG 그래픽의 코드입니다.

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="stylesheets/main.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
<g>
    <path d="M28.44......./>
</g>
</svg>

외부 CSS 파일 (main.css)에 다음을 넣습니다.

.socIcon g {fill:red;}

그러나 그래픽에는 영향을 미치지 않습니다. 나는 또한 .socIcon g path {} 및 .socIcon path {}를 시도했습니다.

문제가 있거나 내 구현이 외부 CSS 수정을 허용하지 않거나 단계를 놓쳤습니까? 도와 주셔서 정말 감사합니다! 외부 스타일 시트를 통해 SVG 그래픽의 색상을 수정할 수있는 기능이 필요하지만 툴팁과 링크 기능을 잃을 수는 없습니다. (하지만 툴팁없이 살 수 있을지도 모릅니다.) 감사합니다!



svg { fill:red; }경로에 클래스 이름을 지정하거나 시도하십시오 . 예를 들어 <path class="socIcon" d="M28.44 ..... />이것이 트릭을해야합니다.
Dwza

답변:


92

main.css 파일은 SVG 파일이 HTML에 인라인으로 포함 된 경우 SVG의 콘텐츠에만 영향을 미칩니다.

https://developer.mozilla.org/en/docs/SVG_In_HTML_Introduction

<html>
  <body>
  <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
    <g>
      <path d="M28.44......./>
    </g>
  </svg>
</html>

SVG를 파일에 보관하려면 SVG 파일 내부에 CSS를 정의해야합니다.

스타일 태그로 할 수 있습니다.

http://www.w3.org/TR/SVG/styling.html#StyleElementExample

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
     width="50px" height="50px" viewBox="0 0 50 50">
  <defs>
    <style type="text/css"><![CDATA[
      .socIcon g {
        fill:red;
      }
    ]]></style>
  </defs>
  <g>
    <path d="M28.44......./>
  </g>
</svg>

서버 측 도구를 사용하여 활성 스타일에 따라 스타일 태그를 업데이트 할 수 있습니다. 루비에서는 Nokogiri로 이것을 달성 할 수 있습니다. SVG는 XML 일뿐입니다. 따라서이 작업을 수행 할 수있는 XML 라이브러리가 많이 있습니다.

그렇게 할 수 없다면 마치 PNG처럼 사용하면됩니다. 각 스타일에 대한 세트를 만들고 스타일을 인라인으로 저장합니다.


17
이것은 SVG를 캐싱하고 다양한 스타일을 적용하여 이점을 얻을 수있는 방법이 없음을 의미합니까? 인라인은 캐시가 잘되지 않는 것 같지만 다른 방법은 이미지의 여러 버전을 생성해야하므로 캐시로 인한 이점이 없습니다.
msg45f

또 다른 방법은 SVG를 각 버전마다 다른 색상으로 배경 이미지 데이터 URI로 인코딩하고 gzip을 사용하여 중복으로 인한 파일 크기를 줄이는 것입니다.
Ruskin

1
제 경우에는 SVG에서 요소 스타일을 재정의하고 싶었습니다. 요소 스타일의 우선 순위가 더 높았 기 때문에 내 CSS가 작동하지 않았습니다. 가장 간단한 해결책은 SVG의 CSS 스타일에! important를 추가하는 것입니다. 그런 다음 모든 것이 잘되었습니다. ! important를 피하려면 요소 스타일을 CSS로 이동해야합니다.
David Gausmann

URL에서 svg 내부에 스타일 시트를로드 할 수없는 것이 부끄러운
clayRay

1
@clayRay SVG2가 완성되면 w3.org/TR/SVG2/styling.html#LinkElement
RGB

51

한 가지 (중요한)주의 사항으로 원하는 작업을 수행 할 수 있습니다. 심볼 내의 경로는 외부 CSS를 통해 독립적으로 스타일을 지정할 수 없습니다.이 방법으로 전체 심볼에 대한 속성 만 설정할 수 있습니다. 따라서 심볼에 두 개의 경로가 있고 다른 채우기 색상을 갖기를 원하면 작동하지 않지만 모든 경로를 동일하게하려면 작동해야합니다.

HTML 파일에서 다음과 같은 것을 원합니다.

<style>
  .fill-red { fill: red; }
  .fill-blue { fill: blue; }
</style>

<a href="//www.example.com/">
  <svg class="fill-red">
    <use xlink:href="images/icons.svg#example"></use>
  </svg>
</a>

그리고 외부 SVG 파일에서 다음과 같은 것을 원합니다.

<svg xmlns="http://www.w3.org/2000/svg">
   <symbol id="example" viewBox="0 0 256 256">
    <path d="M120.... />
  </symbol>
</svg>

온 클래스를 스왑 svg에서 (당신의 HTML에) 태그 fill-redfill-blue 와 TA-다 ... 당신은 빨간색 대신 파란색있다.

인라인 CSS가 우선하므로 특정 경로에서 일부 인라인 CSS와 외부 CSS를 혼합하고 일치시킴으로써 외부 CSS와 별도로 경로를 대상으로 지정할 수있는 한계를 부분적으로 피할 수 있습니다. 이 접근 방식은 외부 CSS를 통해 배경 색상을 변경하고 싶지만 아이콘 자체는 ​​항상 흰색 (또는 그 반대) 인 색상 배경에 흰색 아이콘과 같은 작업을 수행하는 경우에 효과적입니다. 따라서 이전과 동일한 HTML과이 svg 코드와 같은 것을 사용하면 빨간색 배경과 흰색 전경 경로가 표시됩니다.

<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="example" viewBox="0 0 256 256">
    <path class="background" d="M120..." />
    <path class="icon" style="fill: white;" d="M20..." />
  </symbol>
</svg>

좋은 대답 .. 나는 경고가 정말로 있어야한다고 생각한다 : 브라우저 지원, 그래도! 좋은 참고 (caniuse보다 더 많은 세부 사항) : css-tricks.com/svg-fragment-identifiers-work
ptim

이것이 해결책입니다! 실제로 전체 svg 콘텐츠를 symbol요소 로 래핑 할 필요가 없습니다 . 즉 id, svg 요소에를 줄 수 있습니다 .` <svg id = example "xmlns ="w3.org/2000/svg " viewBox ="0 0256256 "> <path class ="background "d ="M120 ... "/> <path class ="icon "style ="fill : white; "d ="M20 ... "/> </ svg >`
SimoneMSR

12

다음을 사용하여 SVG 파일에 외부 CSS 파일 링크를 포함 할 수 있습니다.

<link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="mystyles.css" type="text/css"/>

태그를 여는 후에 다음을 입력해야합니다.

<svg>
  <link xmlns="http://www.w3.org/1999/xhtml" rel="stylesheet" href="mystyles.css" type="text/css"/>
  <g>
    <path d=.../>
  </g>
</svg>

SVG 파일을 수정해야하기 때문에 완벽한 솔루션은 아니지만 한 번만 수정하면 모든 SVG 파일에 대해 하나의 CSS 파일에서 모든 스타일 변경을 수행 할 수 있습니다.


1
와우, 작동하지만 1 개의 찬성 만 ...이 솔루션이 모든 상황에 적합합니까? 너무 간단합니다. 왜 이것이 정답이 아닌가?
Bruno Vincent

요점은 스타일 정의를 중앙 집중화하는 것입니다. 스타일을 지정할 SVG가 10 개 있다고 가정 해 보겠습니다. 이제 CSS에 대한 참조를 영향을 받아야하는 모든 SVG에 복사해야합니다. CSS의 파일 이름 / 위치가 변경되면 10 개의 SVG로 업데이트해야합니다. CSS 클래스는 실제 CSS 파일에 대한 참조보다 훨씬 더 상징적으로 느껴집니다.
Frans

<img> 태그를 통해로드 된 svg는 외부 콘텐츠 (예 : 스타일 시트)를로드 하지 않습니다 .
Moose Morals

7

JavaScript에서 스타일 요소를 동적으로 만들고 SVG 요소에 추가하여 SVG 스타일을 지정할 수 있습니다. Hacky,하지만 작동합니다.

<object id="dynamic-svg" type="image/svg+xml" data="your-svg.svg">
    Your browser does not support SVG
</object>
<script>
    var svgHolder = document.querySelector('object#dynamic-svg');
    svgHolder.onload = function () {
        var svgDocument = svgHolder.contentDocument;
        var style = svgDocument.createElementNS("http://www.w3.org/2000/svg", "style");

        // Now (ab)use the @import directive to load make the browser load our css
        style.textContent = '@import url("/css/your-dynamic-css.css");';

        var svgElem = svgDocument.querySelector('svg');
        svgElem.insertBefore(style, svgElem.firstChild);
    };
</script>

원한다면 PHP에서 동적으로 JavaScript를 생성 할 수 있습니다. JavaScript에서 이것이 가능하다는 사실은 수많은 가능성을 열어줍니다.


헤이 나는 실제로 당신의 솔루션을 좋아하고 작동하지만 OS 과정을 기꺼이 도와주고 싶다면 내 상황에서 채택해야합니다. <defs> 안에 스타일 태그가 있습니다. 수동으로 삭제할 수 있고이 코드를 실행하여 만들 수 있습니다. 스타일, 내가 defs를 삭제 한 다음 요소를 다시 생성하거나 업데이트 할 수있는 방법이 있습니까? 또한 URL에 오류가 있습니다. URL이 정의되지 않았습니다. 도와주세요. 감사합니다
Kamel Mili

6

취할 수있는 한 가지 접근 방식은 CSS 필터를 사용하여 브라우저에서 SVG 그래픽의 모양을 변경하는 것입니다.

예를 들어 SVG 코드 내에 빨간색 채우기 색상을 사용하는 SVG 그래픽이있는 경우 180 도의 색조 회전 설정을 사용하여 보라색으로 바꿀 수 있습니다.

#theIdOfTheImgTagWithTheSVGInIt {
    filter: hue-rotate(180deg);
    -webkit-filter: hue-rotate(180deg);
    -moz-filter: hue-rotate(180deg);
    -o-filter: hue-rotate(180deg);
    -ms-filter: hue-rotate(180deg);
}

원하는 색상을 찾으려면 다른 색조 회전 설정을 시험해보십시오.

명확하게 말하면 위의 CSS는 HTML 문서에 적용된 CSS에 포함됩니다. SVG 코드의 스타일이 아니라 HTML 코드에서 img 태그의 스타일을 지정합니다.

그리고 이것은 검정, 흰색 또는 회색으로 채워진 그래픽에서는 작동하지 않습니다. 해당 색상의 색조를 회전하려면 실제 색상이 있어야합니다.


4

외부 CSS 스타일 시트로 동적 스타일을 갖는 매우 빠른 솔루션입니다. <object>태그를 하여 svg를 포함 입니다.

이 예제는 루트에 클래스를 추가합니다. <svg> 상위 요소를 클릭 태그에 .

file.svg :

<?xml-stylesheet type="text/css" href="../svg.css"?>
 <svg xmlns="http://www.w3.org/2000/svg" viewBox="">
  <g>
   <path/>
  </g>
 </svg>

html :

<a class="parent">
  <object data="file.svg"></object>
</a>

Jquery :

$(function() {
  $(document).on('click', '.parent', function(){
    $(this).find('object').contents().find('svg').attr("class","selected");
  }
});

클릭 부모 요소 :

 <svg xmlns="http://www.w3.org/2000/svg" viewBox="" class="selected">

그러면 CSS를 관리 할 수 ​​있습니다.

svg.css :

path {
 fill:none;
 stroke:#000;
 stroke-miterlimit:1.41;
 stroke-width:0.7px;
}

.selected path {
 fill:none;
 stroke:rgb(64, 136, 209);
 stroke-miterlimit:1.41;
 stroke-width:0.7px;
}

작동하지 않는 것 같습니다. 작동하는 예제를 추가 할 수 있습니까?
Jeanluca Scaljeri

4

먼저 외부 svg 이미지를 인라인하여 수행 할 수 있어야합니다. 아래 코드는 Jess Frazelle의 모든 SVG 이미지를 인라인 SVG교체 한 것입니다.

$('img.svg').each(function(){
  var $img = $(this);
  var imgID = $img.attr('id');
  var imgClass = $img.attr('class');
  var imgURL = $img.attr('src');
  $.get(imgURL, function(data) {
    // Get the SVG tag, ignore the rest
    var $svg = $(data).find('svg');
    // Add replaced image's ID to the new SVG
    if (typeof imgID !== 'undefined') {
      $svg = $svg.attr('id', imgID);
    }
    // Add replaced image's classes to the new SVG
    if (typeof imgClass !== 'undefined') {
      $svg = $svg.attr('class', imgClass+' replaced-svg');
    }
    // Remove any invalid XML tags as per http:validator.w3.org
    $svg = $svg.removeAttr('xmlns:a');
    // Replace image with new SVG
    $img.replaceWith($svg);
  });
});

3
이것은 html과 동일한 도메인에서 호스팅되는 이미지가 있거나 이미지 서버에 특별히 구성된 교차 도메인 정책이있는 경우에만 작동합니다. $ .get은 ajax를 사용하고 유효한 액세스 허용 헤더가없는 경우 외부 서버에서 이미지를로드하지 못합니다
user151496

이것은 전설적입니다
Tino Costa 'El

2

<image>태그에 사용되는 경우 SVG는 개인 정보 보호를 위해 단일 파일에 포함되어야합니다. 이 버그질라 버그 에는 이것이 왜 그런지에 대한 자세한 내용이 있습니다. 안타깝게도 an과 같은 다른 태그를 사용할 수 없습니다 <iframe>. 링크로 작동하지 않으므로 CSS를<style> 파일 자체 태그에 .

이를 수행하는 한 가지 다른 방법은 기본 html 파일에 SVG 데이터를 포함하는 것입니다.

<a href='http://youtube.com/...' target='_blank'>
  <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
    <g>
        <path d="M28.44......./>
    </g>
  </svg>
</a>

HTML <link>태그를 사용하여 외부 CSS 파일로 스타일을 지정할 수 있습니다.


2
파일 내에 스타일을 넣을 수 없습니다. 실제로 사용자가 내 사이트에 대해 선택한 색 구성표에 따라 이러한 이미지의 색상을 변경하겠습니다. 내 현재 구현은 기본 스타일을 덮어 쓰는 메인 페이지에 스타일 시트를 추가하는 것입니다. 포함 된 SVG 그래픽에 영향을주기 위해 해당 파일에 색상 변경 사항을 적용하고 싶었습니다. 하지만 SVG 파일 내에서 스타일 시트에 연결해야하기 때문에 작동하지 않습니다 (자바 스크립트를 사용하여 모든 SVG 파일에 해당 링크를 추가하는 방법이없는 경우). 분명히 외부 SVG 파일, 외부 CSS, 링크 및 도구 설명을 허용하는 방법이 있습니다.
Jordan H

1
브라우저의 보안 모델로 인해 원하는 작업을 수행 할 수 없습니다. 이미지로 사용되는 경우 javascript를 사용하여 SVG를 조작 할 수 없습니다. SVG를 애니메이션 png 또는 gif 파일과 같은 이미지로 사용할 때 모두 하나의 파일에 있으며 스크립팅 액세스가없는 것으로 생각하십시오.
Robert Longson 2013-08-25

1

"실제로 사용자가 내 사이트에 대해 선택한 색 구성표에 따라 이러한 이미지의 색상을 변경하겠습니다." - 요르단 시간 전

이를 위해 PHP를 사용하는 것이 좋습니다. 아이콘 글꼴없이이 작업을 수행하는 더 좋은 방법은 없으며, 사용하지 않으려면 다음을 시도해 볼 수 있습니다.

<?php

    header('Content-Type: image/svg+xml');
    echo '<?xml version="1.0" encoding="utf-8"?>';
    $color = $_GET['color'];

?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
    <g>
        <path fill="<?php echo $color; ?>" d="M28.44..."/>
    </g>
</svg>

나중에이 filename.php?color=#ffffff파일을 사용하여 원하는 색상으로 svg 파일을 가져올 수 있습니다 .


6
이 코드는 사용자 입력을 확인하지 않습니다. 어떤 것이 든 색상으로 제공 될 수 있으며 SVG는 매우 흥미로운 방식으로 렌더링 될 수 있습니다. 영향을 주는지는 확실하지 않지만 항상 사용자 입력을 확인 하는 습관을 만들어야합니다 . 다음과 같은 것이 도움이 될 것입니다 : if (!preg_match('/^[#][0-9a-f]{6}$/i', $_GET['color'])) die('Oops!');(시작 PHP 블록 어딘가에 넣으십시오).
johndodo dec.

1

나를 위해 작동하는 것 : @import 규칙이있는 스타일 태그

<defs>
    <style type="text/css">
        @import url("svg-common.css");
    </style>
</defs>

1

나는 그것의 오래된 게시물을 알고 있지만이 문제를 해결하기 위해 ... 당신은 잘못된 장소에서 수업을 사용하고 있습니다 : D

우선 사용할 수 있습니다.

svg { fill: red; }

당신의 main.css 이 빨간색 얻을 수 있습니다. 이것은 효과가 있습니다. 특정 경로를 얻기 위해 노드 선택기를 적절하게 사용할 수도 있습니다.

두 번째로 클래스를 img-Tag로 디클레어했습니다.

<img class='socIcon'....

실제로 SVG 내부에서 declair해야합니다. 다른 경로가 있다면 물론 더 많은 것을 정의 할 수 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="stylesheets/main.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
<g>
    <path class="myClassForMyPath" d="M28.44......./>
</g>
</svg>

지금 당신은 당신의 색상을 변경할 수 있습니다 main.css같은

.myClassForMyPath {
    fill: yellow;
}

이것을 시도했지만 다른 많은 답변이 이미 말한 것처럼 작동하지 않습니다. SVG 내부의 클래스에는 스타일을 적용 할 수 없습니다.
Frans

@Frans 파일로 svg를 포함하고 있습니까? 아니면 위의 예제와 같이 svg 소스가 있습니까? 이것은 svg를 사용하는 방법에 따라 다릅니다. img를 포함하면 작동하지 않습니다.
Dwza

정확히 HTML에서 SVG를 인라인하는 경우에만 작동합니다. 그러나 그것은 당신의 모범이하는 것이 아닙니다. 인라인이 아닌 외부 SVG를 사용합니다. HTML에서 CSS로 외부 SVG를 스타일링하는 방법이없는 것 같습니다.
Frans

내 예를 올바르게 시도 했습니까? 내 말은, 외부의 CSS 파일을 포함 했습니까? <?xml-stylesheet href="stylesheets/main.css" type="text/css"?>
Dwza

좋아, 이제 SVG 내부<?xml-stylesheet ... ?>선언 있습니다. 그게 효과가있을 것 같아요. <link rel="stylesheet" ... >SVG 내부를 권장하는 다른 답변과 유사합니다 . 또한 동일한 문제가 있습니다 (스타일 시트를 가리 키도록 모든 SVG를 업데이트해야하며 스타일 시트의 이름이나 위치가 변경되면 모든 SVG를 다시 변경해야 함).
Frans

1
  1. 외부 스타일

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">

  <style>
	@import url(main.css);
  </style>

  <g>
    <path d="M28.44......./>
  </g>
</svg>

  1. 내부 스타일 용

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">

  <style>
	    .socIcon g {fill:red;}
  </style>

  <g>
    <path d="M28.44......./>
  </g>
</svg>

참고 : <img>태그 안에 SVG를 포함하면 외부 스타일이 작동하지 않습니다 . <div>태그 내에서 완벽하게 작동합니다.


0

@leo는 angularJS 버전입니다. 다시 한 번 감사드립니다.

G.directive ( 'imgInlineSvg', function () {

return {
    restrict : 'C',
    scope : true,
    link : function ( scope, elem, attrs ) {

        if ( attrs.src ) {

            $ ( attrs ).each ( function () {
                var imgID    = attrs.class;
                var imgClass = attrs.class;
                var imgURL   = attrs.src;

                $.get ( imgURL, function ( data ) {

                    var $svg = $ ( data ).find ( 'svg' );
                    if ( typeof imgID !== 'undefined' ) {
                        $svg = $svg.attr ( 'id', imgID );
                    }

                    if ( typeof imgClass !== 'undefined' ) {
                        $svg = $svg.attr ( 'class', imgClass + ' replaced-svg' );
                    }

                    $svg = $svg.removeAttr ( 'xmlns:a' );

                    elem.replaceWith ( $svg );

                } );

            } );
        }

    }

}

} );

-1

이 방법은 svg가 웹 브라우저 내에서 표시되는 경우 작동하지만이 코드가 서버에 업로드되고 svg 아이콘의 클래스가 배경 이미지 인 것처럼 코딩되는 즉시 색상이 손실되고 기본 색상으로 돌아갑니다. . 색상에 대한 svg 클래스와 svg의 표시 및 위치에 대한 최상위 레이어 클래스가 모두 동일한 디렉토리에 매핑되어 있어도 색상을 외부 스타일 시트에서 변경할 수없는 것처럼 보입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.