Jak zastosować styl do osadzonego SVG?

107

Gdy plik SVG jest bezpośrednio zawarty w dokumencie za pomocą <svg>znacznika, możesz zastosować style CSS do pliku SVG za pośrednictwem arkusza stylów dokumentu. Jednak próbuję zastosować styl do pliku SVG, który jest osadzony (za pomocą <object>tagu).

Czy można użyć czegoś takiego jak poniższy kod?

object svg { 
    fill: #fff; 
}
Joshua Sortino
źródło
1
Wymyśliłem lekki sposób na zrobienie tego, który świetnie sprawdziłby się w tym, co próbujesz zrobić. Zobacz te pytania i odpowiedzi: stackoverflow.com/questions/11978995/…
Drew Baker
Oto odpowiedź, która faktycznie wykonuje zadanie (od Manipulowania właściwościami stylu zewnętrznego pliku SVG za pomocą CSS ).
Fabien Snauwaert

Odpowiedzi:

108

Krótka odpowiedź: nie, ponieważ style nie mają zastosowania poza granicami dokumentu.

Jednakże, ponieważ masz <object>tag, możesz wstawić arkusz stylów do dokumentu svg za pomocą skryptu.

Coś takiego i zauważ, że ten kod zakłada, że ​​plik <object>został w pełni załadowany:

var svgDoc = yourObjectElement.contentDocument;
var styleElement = svgDoc.createElementNS("http://www.w3.org/2000/svg", "style");
styleElement.textContent = "svg { fill: #fff }"; // add whatever you need here
svgDoc.getElementById("where-to-insert").appendChild(styleElement);

Możliwe jest również wstawienie <link>elementu odwołującego się do zewnętrznego arkusza stylów:

var svgDoc = yourObjectElement.contentDocument;
var linkElm = svgDoc.createElementNS("http://www.w3.org/1999/xhtml", "link");
linkElm.setAttribute("href", "my-style.css");
linkElm.setAttribute("type", "text/css");
linkElm.setAttribute("rel", "stylesheet");
svgDoc.getElementById("where-to-insert").appendChild(linkElm);

Jeszcze inną opcją jest użycie pierwszej metody, aby wstawić element stylu, a następnie dodać regułę @import, np styleElement.textContent = "@import url(my-style.css)".

Oczywiście możesz również bezpośrednio linkować do arkusza stylów z pliku svg, bez wykonywania jakichkolwiek skryptów. Powinno działać jedno z poniższych:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="my-style.css" type="text/css"?>
<svg xmlns="http://www.w3.org/2000/svg">
  ... rest of document here ...
</svg>

lub:

<svg xmlns="http://www.w3.org/2000/svg">
  <defs>
    <link href="my-style.css" type="text/css" rel="stylesheet" 
          xmlns="http://www.w3.org/1999/xhtml"/>
  </defs>
  ... rest of document here ...
</svg>

Aktualizacja 2015: możesz użyć wtyczki jquery-svg do zastosowania skryptów js i stylów css do osadzonego SVG.

Erik Dahlström
źródło
Czy to jest metoda łączenia zewnętrznego arkusza stylów? Jeśli nie, czy to możliwe?
Joshua Sortino
Powyższe wstawia element stylu do pliku svg. Tak, możliwe jest również wstawienie elementu link xhtml w celu połączenia z zewnętrznym arkuszem stylów lub ewentualnie instrukcją przetwarzania arkusza stylów xml (patrz w3.org/Style/styling-XML.html ).
Erik Dahlström
To niesamowite, Erik! Jednak nie udało mi się zmusić tej sztuczki do działania w Chrome bez dołączenia svgweb: code.google.com/p/svgweb ... Masz jakiś pomysł, co robię źle?
Matt WD,
1
@ MattW-D: prawdopodobnie powinieneś po prostu otworzyć nowe pytanie. Svgweb nie jest potrzebny w Chrome.
Erik Dahlström
Dziękuję Erik, naprawdę walczył, próbując zmusić font-face do pracy w svg przez css, łącząc css z svg działał jako pierwsza próba i cudownie między przeglądarkami!
Dave
10

Możesz to zrobić bez javsscrpt, umieszczając blok stylu ze stylami w samym pliku SVG.

<style type="text/css">
 path,
 circle,
 polygon { 
    fill: #fff; 
  }
</style>
R Reveley
źródło
3

Jeśli jedynym powodem używania znacznika do umieszczania SVG jest to, że nie chcesz zaśmiecać swojego kodu źródłowego znacznikami z SVG, powinieneś przyjrzeć się wtryskiwaczom SVG, takim jak SVGInject .

Wstrzykiwanie SVG wykorzystuje JavaScript do wstawiania pliku SVG w tekście do dokumentu HTML. Pozwala to na czysty kod źródłowy HTML, jednocześnie umożliwiając w pełni stylizowanie SVG za pomocą CSS. Podstawowy przykład wygląda następująco:

<html>
<head>
  <script src="svg-inject.min.js"></script>
</head>
<body>
  <img src="image.svg" onload="SVGInject(this)" />
</body>
</html>
Waruyama
źródło
Niesamowite! Dzięki za zgrabne narzędzie.
Deleplace