Como aplicar um estilo a um SVG incorporado?

107

Quando um SVG é incluído diretamente em um documento usando a <svg>tag, você pode aplicar estilos CSS ao SVG por meio da folha de estilo do documento. No entanto, estou tentando aplicar um estilo a um SVG que está incorporado (usando a <object>tag).

É possível usar algo como o código a seguir?

object svg { 
    fill: #fff; 
}
Joshua Sortino
fonte
1
Eu vim com uma maneira leve de fazer isso que funcionaria muito bem para o que você está tentando fazer. Veja estas perguntas e respostas: stackoverflow.com/questions/11978995/…
Drew Baker
Aqui está uma resposta que realmente dá conta do
recado

Respostas:

108

Resposta curta: não, pois os estilos não se aplicam aos limites do documento.

No entanto, uma vez que você tem um <object> tag, pode inserir a folha de estilo no documento SVG usando o script.

Algo parecido com isso, e observe que este código assume que o <object>foi totalmente carregado:

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

Também é possível inserir um <link>elemento para fazer referência a uma folha de estilo externa:

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

Outra opção é usar o primeiro método, para inserir um elemento de estilo e, em seguida, adicionar uma regra @import, por exemplo styleElement.textContent = "@import url(my-style.css)".

Claro que você também pode criar um link direto para a folha de estilo do arquivo svg, sem fazer nenhum script. Qualquer um dos seguintes deve funcionar:

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

ou:

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

Atualização 2015: você pode usar o plugin jquery-svg para aplicar scripts js e estilos css a um SVG incorporado.

Erik Dahlström
fonte
Este é um método para vincular uma folha de estilo externa? Se não, isso é possível?
Joshua Sortino
O exemplo acima insere um elemento de estilo no svg. Sim, é possível inserir um elemento de link xhtml também para vincular a uma folha de estilo externa, ou possivelmente uma instrução de processamento de folha de estilo xml (consulte w3.org/Style/styling-XML.html ).
Erik Dahlström
Isso é incrível Erik! No entanto, não consegui fazer esse truque funcionar no Chrome sem incluir svgweb: code.google.com/p/svgweb ... Alguma ideia do que estou fazendo de errado?
Matt WD
1
@ MattW-D: você provavelmente deveria apenas abrir uma nova pergunta para isso. Svgweb não é necessário no cromo.
Erik Dahlström
Obrigado Erik, estava realmente lutando para fazer o font-face funcionar em svg através do css, ligando o css ao svg que funcionou na primeira tentativa e miraculosamente no navegador cruzado!
Dave
10

Você pode fazer isso sem javsscrpt, colocando um bloco de estilo com seus estilos dentro do próprio arquivo SVG.

<style type="text/css">
 path,
 circle,
 polygon { 
    fill: #fff; 
  }
</style>
R Reveley
fonte
3

Se a única razão para usar a tag para incluir o SVG é que você não deseja sobrecarregar seu código-fonte com a marcação do SVG, você deve dar uma olhada em injetores SVG como o SVGInject .

A injeção de SVG usa Javascript para injetar um arquivo SVG embutido em seu documento HTML. Isso permite um código-fonte HTML limpo enquanto torna os SVGs totalmente estilizáveis ​​com CSS. Um exemplo básico se parece com este:

<html>
<head>
  <script src="svg-inject.min.js"></script>
</head>
<body>
  <img src="image.svg" onload="SVGInject(this)" />
</body>
</html>
Waruyama
fonte
Impressionante! Obrigado pela ferramenta bacana.
Deleplace