Reputation: 125902
I have an SVG file that I want to use in a web page. I want the image to appear multiple times, but to apply different CSS styles to each one.
Is this possible?
When I say "apply different CSS styles", I mean that I want to style the SVG contents (stroke, color, radius, etc), not just the width of an <img>
or something.
Also, I don't consider "copy and paste the SVG contents" to be "re-using" it. I want to create a file like logo.svg
and reference it from the HTML.
Upvotes: 33
Views: 21342
Reputation: 3523
Yes, it can be easily done using SVG injection, and it should work on all Browsers that support SVG.
With SVGInject your HTML may look like this:
<html>
<head>
<script src="svg-inject.min.js"></script>
<style>
.redImage {
/* Your CSS for the red image here */
}
.greenImage {
/* Your CSS for the green image here */
}
<style>
</head>
<body>
<img class="redImage" src="image.svg" onload="SVGInject(this)" />
<img class="greenImage" src="image.svg" onload="SVGInject(this)" />
</body>
</html>
The onload="SVGInject(this)"
triggers the injection after the SVG is loaded and replaces the <img>
element with the SVG markup from the specified SVG file.
Upvotes: 5
Reputation: 125902
Styling the contents (stroke, fill, etc) of an SVG from a containing HTML document is currently not supported.
@RobertLongson was kind enough to point me to the SVG Parameters spec, which could provide a partial solution. It is not implemented in any browser, but can be used with a Javascript shim. However, when I emailed the SVG working group with a question about it, I was told:
The SVG Parameters doc is currently out-of-date. The plan at the moment is to integrate it with CSS Custom Properties and var(); the spec will then become an alternative way to define a custom property.
And
SVG <img>s are actually in a separate document entirely; it's basically the same as an <iframe>, just locked down more strictly. We don't allow direct selection across document boundaries for a combination of security, sanity, and performance reasons.
That said, it seems reasonable for the Parameters spec to define a way to take values from the referencing environment, so you'd set the property on the <img> itself and it would transfer through to the contained document at the document's request.
use
tagFor the record, the following seemed to accomplish my stated goals (technique borrowed from CSS-Tricks), but @RobertLongson let me know that it only worked in Firefox (I think I was using version 31) because Firefox was not compliant with the spec.
<!DOCTYPE html>
<html>
<head>
<title>SVG Reuse Demo</title>
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html" />
<style type="text/css">
.circle .uno { stroke: orange; stroke-width: 5px; }
.circle-1 .uno { fill: blue; }
.circle-2 .uno { fill: red; }
.circle-3 .uno { fill: green; }
</style>
</head>
<body>
<!-- Single definition of SVG -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="disc" viewbox="0 0 100 100">
<circle class="uno" cx="50" cy="50" r="40">
</symbol>
</svg>
<!-- Re-use; each is styled differently (see above) -->
<svg class="circle circle-1">
<use xlink:href="#disc">
</svg>
<svg class="circle circle-2">
<use xlink:href="#disc">
</svg>
<svg class="circle circle-3">
<use xlink:href="#disc">
</svg>
</body>
</html>
Even if it were standard, this technique would be less than ideal; the ideal solution would allow using an SVG defined in an external file, like circles.svg
.
This is because:
Upvotes: 15
Reputation: 11506
html
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 65.326 612 502.174" enable-background="new 0 65.326 612 502.174" xml:space="preserve" class="logo">
<path class="kiwi" d="M210.333,65.331C104.367,66.105-12.349,150.637,1.056,276.449c4.303,40.393,18.533,63.704,52.171,79.03
c36.307,16.544,57.022,54.556,50.406,112.954c-9.935,4.88-17.405,11.031-19.132,20.015c7.531-0.17,14.943-0.312,22.59,4.341
c20.333,12.375,31.296,27.363,42.979,51.72c1.714,3.572,8.192,2.849,8.312-3.078c0.17-8.467-1.856-17.454-5.226-26.933
c-2.955-8.313,3.059-7.985,6.917-6.106c6.399,3.115,16.334,9.43,30.39,13.098c5.392,1.407,5.995-3.877,5.224-6.991
c-1.864-7.522-11.009-10.862-24.519-19.229c-4.82-2.984-0.927-9.736,5.168-8.351l20.234,2.415c3.359,0.763,4.555-6.114,0.882-7.875
c-14.198-6.804-28.897-10.098-53.864-7.799c-11.617-29.265-29.811-61.617-15.674-81.681c12.639-17.938,31.216-20.74,39.147,43.489
c-5.002,3.107-11.215,5.031-11.332,13.024c7.201-2.845,11.207-1.399,14.791,0c17.912,6.998,35.462,21.826,52.982,37.309
c3.739,3.303,8.413-1.718,6.991-6.034c-2.138-6.494-8.053-10.659-14.791-20.016c-3.239-4.495,5.03-7.045,10.886-6.876
c13.849,0.396,22.886,8.268,35.177,11.218c4.483,1.076,9.741-1.964,6.917-6.917c-3.472-6.085-13.015-9.124-19.18-13.413
c-4.357-3.029-3.025-7.132,2.697-6.602c3.905,0.361,8.478,2.271,13.908,1.767c9.946-0.925,7.717-7.169-0.883-9.566
c-19.036-5.304-39.891-6.311-61.665-5.225c-43.837-8.358-31.554-84.887,0-90.363c29.571-5.132,62.966-13.339,99.928-32.156
c32.668-5.429,64.835-12.446,92.939-33.85c48.106-14.469,111.903,16.113,204.241,149.695c3.926,5.681,15.819,9.94,9.524-6.351
c-15.893-41.125-68.176-93.328-92.13-132.085c-24.581-39.774-14.34-61.243-39.957-91.247
c-21.326-24.978-47.502-25.803-77.339-17.365c-23.461,6.634-39.234-7.117-52.98-31.273C318.42,87.525,265.838,64.927,210.333,65.331
z M445.731,203.01c6.12,0,11.112,4.919,11.112,11.038c0,6.119-4.994,11.111-11.112,11.111s-11.038-4.994-11.038-11.111
C434.693,207.929,439.613,203.01,445.731,203.01z" />
</svg>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 65.326 612 502.174" enable-background="new 0 65.326 612 502.174" xml:space="preserve" class="logo">
<path class="kiwi" d="M210.333,65.331C104.367,66.105-12.349,150.637,1.056,276.449c4.303,40.393,18.533,63.704,52.171,79.03
c36.307,16.544,57.022,54.556,50.406,112.954c-9.935,4.88-17.405,11.031-19.132,20.015c7.531-0.17,14.943-0.312,22.59,4.341
c20.333,12.375,31.296,27.363,42.979,51.72c1.714,3.572,8.192,2.849,8.312-3.078c0.17-8.467-1.856-17.454-5.226-26.933
c-2.955-8.313,3.059-7.985,6.917-6.106c6.399,3.115,16.334,9.43,30.39,13.098c5.392,1.407,5.995-3.877,5.224-6.991
c-1.864-7.522-11.009-10.862-24.519-19.229c-4.82-2.984-0.927-9.736,5.168-8.351l20.234,2.415c3.359,0.763,4.555-6.114,0.882-7.875
c-14.198-6.804-28.897-10.098-53.864-7.799c-11.617-29.265-29.811-61.617-15.674-81.681c12.639-17.938,31.216-20.74,39.147,43.489
c-5.002,3.107-11.215,5.031-11.332,13.024c7.201-2.845,11.207-1.399,14.791,0c17.912,6.998,35.462,21.826,52.982,37.309
c3.739,3.303,8.413-1.718,6.991-6.034c-2.138-6.494-8.053-10.659-14.791-20.016c-3.239-4.495,5.03-7.045,10.886-6.876
c13.849,0.396,22.886,8.268,35.177,11.218c4.483,1.076,9.741-1.964,6.917-6.917c-3.472-6.085-13.015-9.124-19.18-13.413
c-4.357-3.029-3.025-7.132,2.697-6.602c3.905,0.361,8.478,2.271,13.908,1.767c9.946-0.925,7.717-7.169-0.883-9.566
c-19.036-5.304-39.891-6.311-61.665-5.225c-43.837-8.358-31.554-84.887,0-90.363c29.571-5.132,62.966-13.339,99.928-32.156
c32.668-5.429,64.835-12.446,92.939-33.85c48.106-14.469,111.903,16.113,204.241,149.695c3.926,5.681,15.819,9.94,9.524-6.351
c-15.893-41.125-68.176-93.328-92.13-132.085c-24.581-39.774-14.34-61.243-39.957-91.247
c-21.326-24.978-47.502-25.803-77.339-17.365c-23.461,6.634-39.234-7.117-52.98-31.273C318.42,87.525,265.838,64.927,210.333,65.331
z M445.731,203.01c6.12,0,11.112,4.919,11.112,11.038c0,6.119-4.994,11.111-11.112,11.111s-11.038-4.994-11.038-11.111
C434.693,207.929,439.613,203.01,445.731,203.01z" />
</svg>
css
#Layer_1 {
width: 200px;
}
#Layer_2 {
width: 100px;
}
body {
padding: 20px;
}
You can use it this way if you don't want to use the whole values of svg
multiple times.
html
<img class="papa" src="http://s.cdpn.io/3/kiwi.svg">
<img class="mama" src="http://s.cdpn.io/3/kiwi.svg">
<img class="baby" src="http://s.cdpn.io/3/kiwi.svg">
css
.papa {
width: 250px;
}
.mama {
width: 100px;
}
.baby {
width: 50px;
}
source : http://css-tricks.com/using-svg/
Upvotes: -2
Reputation: 71150
Yes, absolutely!
If each occurrence is unique, simply apply an id
attribute to the svg
then reference it and its children with the id prefixing any selectors, e.g
<svg id='myimage ... />
Then in your css:
#myimage line{...}
Would for example apply styles to the line
elements within the myimage
svg.
I'd also recommend having a look at the MDN article on CSS selectors
Upvotes: 3