Is an SVG image purely vectorial or can we combine bitmap images into an SVG image ?
How about transforms applied on the bitmap images (perspective, mappings, etc.) ?
Edit: Images may be included in an SVG by link reference. See http://www.w3.org/TR/SVG/struct.html#ImageElement. My question was in fact if bitmap images may be included inside the svg so that the svg image would be self contained. Otherwise, whenever the svg image is displayed the link must be followed and the image downloaded. Apparently .svg files are simply xml files.
Yes, you can reference any image from the image element. And you can use data URIs to make the SVG self-contained. An example:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
...
<image
width="100" height="100"
xlink:href="data:image/png;base64,IMAGE_DATA"
/>
...
</svg>
The svg element attribute xmlns:xlink declares xlink as a namespace prefix and says where the definition is. That then allows the SVG reader to know what xlink:href means.
The IMAGE_DATA is where you'd add the image data as base64-encoded text. Vector graphics editors that support SVG usually have an option for saving with images embedded. Otherwise there are plenty of tools around for encoding a byte stream to and from base64.
Here's a full example from the SVG testsuite.
I posted a fiddle here, showing data, remote and local images embedded in SVG, inside an HTML page:
http://jsfiddle.net/MxHPq/
<!DOCTYPE html>
<html>
<head>
<title>SVG embedded bitmaps in HTML</title>
<style>
body{
background-color:#999;
color:#666;
padding:10px;
}
h1{
font-weight:normal;
font-size:24px;
margin-top:20px;
color:#000;
}
h2{
font-weight:normal;
font-size:20px;
margin-top:20px;
}
p{
color:#FFF;
}
svg{
margin:20px;
display:block;
height:100px;
}
</style>
</head>
<body>
<h1>SVG embedded bitmaps in HTML</h1>
<p>The trick appears to be ensuring the image has the correct width and height atttributes</p>
<h2>Example 1: Embedded data</h2>
<svg id="example1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="0" y="0" width="5" height="5" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="/>
</svg>
<h2>Example 2: Remote image</h2>
<svg id="example2" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="0" y="0" width="275" height="95" xlink:href="http://www.google.co.uk/images/srpr/logo3w.png" />
</svg>
<h2>Example 3: Local image</h2>
<svg id="example3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="0" y="0" width="136" height="23" xlink:href="/img/logo.png" />
</svg>
</body>
</html>
You could use a Data URI to supply the image data, for example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image width="20" height="20" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="/>
</svg>
The image will go through all normal svg transformations.
But this technique has disadvantages, for example the image will not be cached by the browser
You can use a data: URL to embed a Base64 encoded version of an image. But it's not very efficient and wouldn't recommend embedding large images. Any reason linking to another file is not feasible?
If you want to use that image multiple times inside SVG (Ref.):
<image id="img" xlink:href="data:image/png;base64,BASE64_DATA" />
<use href="#img" />
<use href="#img" />
It is also possible to include bitmaps. I think you also can use transformations on that.
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?
Clarification
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.
No, not currently
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.
A non-spec-compliant hack: the use tag
For 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:
It is clutter to paste it into the HTML (my actual use case may be 300 lines of SVG)
If it were a separate file, I could re-use it in other HTML documents
I could edit it with SVG-specific syntax highlighting
It could be requested and cached separately from the HTML document
... basically all the other reasons we normally put CSS and images in separate files instead of inline in HTML. :)
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.
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
Demo
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.
Demo
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/