Jak stylizować SVG z zewnętrznym CSS?

Mam kilka grafik SVG, które chciałbym zmodyfikować za pomocą zewnętrznych arkuszy stylów - nie bezpośrednio w każdym pliku SVG. Nie umieszczam grafiki w linii, ale przechowuję je w folderze obrazów i wskazuję na nie.

Zaimplementowałem je w ten sposób, aby umożliwić działanie podpowiedzi, a także owinąłem każde w znacznik <a>, Aby zezwolić na link.

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

A oto kod grafiki 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>

Umieszczam następujące elementy w moim zewnętrznym CSS plik (main.css):

.socIcon g {fill:red;}

Jednak nie ma to wpływu na grafikę. Też próbowałem .socIcon g path {} i .socIcon path {}.

Coś jest nie tak, może moja implementacja nie pozwala na zewnętrzne modyfikacje CSS, lub przegapiłem krok? Będę wdzięczny za pomoc! Potrzebuję tylko możliwości modyfikowania kolorów grafiki SVG za pomocą mojego zewnętrznego arkusza stylów, ale nie mogę stracić możliwości podpowiedzi i łącza. (Może jednak będę w stanie żyć bez podpowiedzi. Dzięki!

Author: Jordan H, 2013-08-25

14 answers

Twój główny.plik css będzie miał wpływ na zawartość SVG tylko wtedy, gdy plik SVG jest zawarty w wierszu HTML:

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>

Jeśli chcesz zachować SVG w plikach, CSS musi być zdefiniowany wewnątrz pliku SVG.

Możesz to zrobić za pomocą znacznika stylu:

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>

Możesz użyć narzędzia na serwerze strona, aby zaktualizować znacznik stylu w zależności od aktywnego stylu. W ruby można to osiągnąć za pomocą Nokogiri. SVG to tylko XML. Istnieje więc prawdopodobnie wiele dostępnych bibliotek XML, które prawdopodobnie mogą to osiągnąć.

Jeśli nie jesteś w stanie tego zrobić, będziesz musiał użyć ich tak, jakby były PNG; tworząc zestaw dla każdego stylu i zapisując ich style w linii.

 97
Author: RGB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-30 13:41:57

Możesz robić, co chcesz, z jednym (ważnym) zastrzeżeniem: ścieżki w Twoim symbolu nie mogą być stylizowane niezależnie za pomocą zewnętrznego CSS - możesz ustawić właściwości tylko dla całego symbolu za pomocą tej metody. Jeśli w symbolu są dwie ścieżki i chcesz, aby miały różne kolory wypełnienia, nie będzie to działać, ale jeśli chcesz, aby wszystkie ścieżki były takie same, powinno to działać.

W pliku html chcesz coś takiego:

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

I w zewnętrznym pliku SVG, który chcesz coś takiego:

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

Zamień klasę na znacznik svg (w Twoim html) z fill-red na fill-blue i ta-da... masz niebieski zamiast czerwonego.

Możesz częściowo obejść ograniczenie możliwości kierowania ścieżek oddzielnie za pomocą zewnętrznego CSS, mieszając i dopasowując zewnętrzny CSS z niektórymi CSS in-line na określonych ścieżkach, ponieważ CSS in-line będzie miał pierwszeństwo. Takie podejście zadziała, jeśli robisz coś w rodzaju białej ikony na kolorowym tle, gdzie chcesz zmienić kolor tła za pomocą zewnętrznego CSS, ale sama ikona jest zawsze biała (lub odwrotnie). Tak więc, z tym samym HTML co wcześniej i czymś takim jak ten kod svg, otrzymasz czerwone tło i białą ścieżkę pierwszoplanową:

<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>
 52
Author: Adam Korman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-13 20:18:17

Możesz umieścić w plikach SVG link do zewnętrznego pliku css używając:

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

Musisz umieścić to po otwarciu tagu:

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

Nie jest to idealne rozwiązanie, ponieważ musisz zmodyfikować pliki svg, ale modyfikujesz je raz, a wszystkie zmiany stylizacji można zrobić w jednym pliku css dla wszystkich plików svg.

 16
Author: Jacek Mamot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-28 21:25:58

Można stylizować SVG, dynamicznie tworząc element stylu w JavaScript i dołączając go do elementu SVG. Hacky, ale działa.

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

Możesz generować JavaScript dynamicznie w PHP, jeśli chcesz - fakt, że jest to możliwe w JavaScript otwiera niezliczone możliwości.

 7
Author: Pete,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-24 12:55:44

Jednym z możliwych sposobów jest użycie filtrów CSS do zmiany wyglądu grafiki SVG w przeglądarce.

Na przykład, jeśli masz grafikę SVG, która używa koloru wypełnienia Czerwonego w kodzie SVG, możesz obrócić ją na kolor fioletowy z ustawieniem obrotu o 180 stopni:

#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);
}

Eksperymentuj z innymi ustawieniami odcień-rotate, aby znaleźć kolory, które chcesz.

Aby było jasne, powyższy CSS przechodzi do CSS, który jest stosowany do dokumentu HTML. Wpisujesz tag img w kodzie HTML, nie stylizując kodu SVG.

I zauważ, że to nie będzie działać z grafiką, która ma wypełnienie czarne, białe lub szare. Musisz mieć tam rzeczywisty kolor, aby obrócić odcień tego koloru.

 6
Author: Simon White,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-13 14:30:10

Powinno być to możliwe przez wpięcie zewnętrznych obrazów svg. Poniższy kod pochodzi z Zastąp wszystkie obrazy SVG inline SVG autorstwa Jess frazelle.

$('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);
  });
});
 5
Author: Leo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-22 06:52:02

Bardzo szybkie rozwiązanie, aby mieć dynamiczny styl z zewnętrznym arkuszem stylów css, w przypadku, gdy używasz znacznika <object> do osadzenia svg.

Ten przykład doda klasę do znacznika głównego <svg> Po kliknięciu elementu nadrzędnego.

Plik.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");
  }
});

Po kliknięciu elementu nadrzędnego:

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

Następnie możesz zarządzać swoim 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;
}
 4
Author: vhanahrni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-13 12:20:57

W przypadku użycia w znaczniku <image> SVG musi być zawarty w jednym pliku ze względów prywatności. Ten błąd bugzilla zawiera więcej szczegółów na temat tego, dlaczego tak jest. Niestety nie możesz użyć innego znacznika, takiego jak <iframe>, ponieważ nie będzie on działał jako łącze, więc będziesz musiał osadzić CSS w znaczniku <style> wewnątrz samego pliku.

Innym sposobem na to jest posiadanie danych SVG w głównym pliku html, tj.

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

Możesz stylizować to za pomocą zewnętrznego pliku CSS za pomocą znacznik HTML <link>.

 2
Author: Robert Longson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-26 06:24:28
  1. dla stylów zewnętrznych

<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. Dla Stylów Wewnętrznych

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

Uwaga: Style zewnętrzne nie będą działać, jeśli umieścisz SVG wewnątrz znacznika <img>. Doskonale sprawdzi się wewnątrz <div> tag

 2
Author: Yuvraj Patil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-04 09:35:21

"mam zamiar zmienić kolory tych obrazów w zależności od tego, jaki schemat kolorów użytkownik wybrał dla mojej strony." - Jordania 10 godziny temu

Proponuję użyć do tego PHP. Nie ma lepszego sposobu, aby to zrobić bez czcionek ikon, a jeśli nie będziesz ich używać, możesz spróbować tego: {]}

<?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>

I później możesz użyć tego pliku jako filename.php?color=#ffffff, Aby uzyskać plik svg w żądanym kolorze.

 1
Author: SeinopSys,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:14

Co u mnie działa: znacznik stylu z regułą @ import

<defs>
    <style type="text/css">
        @import url("svg-common.css");
    </style>
</defs>
 1
Author: Fordi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-08 18:36:00

Wiem, że to stary post, ale żeby rozwiązać ten problem... po prostu korzystasz z zajęć w złym miejscu: D

Po pierwsze możesz użyć

svg { fill: red; }

W Twoim main.css aby było czerwone. To ma skutek. Prawdopodobnie możesz również użyć selektorów węzłów, aby uzyskać określone ścieżki.

Druga rzecz to to, że zdeklasowałeś klasę na img-Tag.

<img class='socIcon'....

Powinieneś usunąć to wewnątrz SVG. jeśli masz różne ścieżki, możesz zdefiniować więcej oczywiście.

<?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>

Teraz możesz zmienić kolor w swoim main.css Jak

.myClassForMyPath {
    fill: yellow;
}
 1
Author: Dwza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-20 07:10:06

@leo tutaj jest wersja angularJS, dzięki jeszcze raz

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 );

                } );

            } );
        }

    }

}

} );
 0
Author: Tino Costa 'El Nino',
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-20 21:31:44

Ta metoda będzie działać, jeśli svg jest wyświetlany w przeglądarce internetowej, ale gdy tylko ten kod zostanie przesłany do serwera sever, a klasa ikony svg zostanie zakodowana tak, jakby była obrazem tła, kolor zostanie utracony i powróci do domyślnego koloru. Wygląda na to, że koloru nie można zmienić z zewnętrznego arkusza stylów, mimo że zarówno Klasa svg dla koloru, jak i klasa warstwy wierzchniej dla wyświetlania i pozycji svg są mapowane do tego samego katalogu.

 -2
Author: HTMLGUY1999,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-06 12:11:31