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.
An ability to define code in one location and reuse it in another helps you make your code more modular, maintainable, and readable. SVG provides that ability through elements that define the code and elements that reference it for reuse.
There are many Scalable Vector Graphics (SVG), but only certain attributes can be applied as CSS to SVG. Presentation attributes are used to style SVG elements and can be used as CSS properties. Some of these attributes are SVG-only while others are already shared in CSS, such as font-size or opacity .
The SVG <use> element can reuse an SVG shape from elsewhere in the SVG document, including <g> elements and <symbol> elements. The reused shape can be defined inside the <defs> element (which makes the shape invisible until used) or outside.
The SVG format allows for the nesting of SVG graphics. It is possible for an “<svg>” elements, to be placed within another “<svg>” element.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With