How to use link to SVG file inside image element? - html

I try to add my SVG on this way:
<svg>
<image class="logo" src="facebook.svg"/>
</svg>
Why it doesn't work? The way to this SVG file is correct.
Of course, I could add my SVG with img or background and it would be easier. But I think it's option is the best, because I need to change the color of my SVG image.

Yes, you can use SVG-file inside image tag in SVG! But this tag does not have src attribute. This attribute is from HTML img tag.
Inside image tag you have to use href attribute or also xlink:href attribute (but it is deprecated since SVG 2) for this purpose.
<svg width="50" height="150">
<image href="https://developer.mozilla.org/static/platforms/mobile.d9737f9e22aa.svg" width="50" height="150"/>
</svg>

<svg width="200" height="200">
<image href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png" height="200" width="200"/>
</svg>

Related

It is possible to put an image into a SVG image? [duplicate]

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.

Why doesn't :hover work inside of a <symbol> in SVG? (In Chrome) [duplicate]

This question already has answers here:
SVG USE element and :hover style
(3 answers)
Closed 2 years ago.
It's strange that I couldn't find anyone else reporting this problem; that makes me think perhaps I am doing something wrong.
I have a <style> tag within an SVG that contains a :hover pseudo-class, it works properly when the SVG is directly embedded into the HTML, but when I put it within a symbol and reference it with a <use> tag, the styles inside the <style> tag are not applied.
SVG Directly-embedded:
<svg width="400" height="110">
<style>
#myRect:hover {
fill: red;
}
</style>
<rect id="myRect" width="300" height="100" />
</svg>
Defined in a symbol, and referenced via the <use> tag.
<svg style="display: none">
<symbol id="rectangle">
<style>
#myRect:hover {
fill: red;
}
</style>
<rect id="myRect" width="300" height="100" />
</symbol>
</svg>
<svg width="400" height="110">
<use href="#rectangle"></use>
</svg>
Why is this happening?! Seems like a weird behavior, am I missing something?!
UPDATE: As Temani Afif mentioned in the comments, this problem exists only in Chrome, Firefox seems to work as expected. (Haven't tested on any other browsers)
This is actually an interesting case, and while Temani Afif gave the right solution, I think it is worth a few more words in a separate answer.
First off, the question is not where the <style> tag sits. It could really be anywhere. The real question is raised by the :hover selector.
<svg style="display: none">
<symbol id="rectangle">
<style>
#myRect {
fill: blue;
}
#myRect:hover {
fill: red;
}
</style>
<rect id="myRect" width="300" height="100" />
</symbol>
</svg>
<svg width="400" height="110">
<use href="#rectangle"></use>
</svg>
The previous SVG 1.1 spec had a short paragraph that said "CSS2 selectors cannot be applied to the (conceptually) cloned DOM tree", but the SVG 2 spec dropped that sentence.
It now has a lot to say about how style inheritance works for <use> elements. but all of it concerns the question: "If there are style rules for the corresponding element (the <symbol>), how are they applied to the shadow instance (what is inside the <use>)?"
But one question I really could find no answer to is: If a pseudo-class state applies to a shadow host, can the shadow instance elements also have that state? Or, to state it more clearly: If a pointer hovers over a <use> element, does it also hover over the elements inside the shadow tree?
There are no obvious answers in CSS Selectors or CSS Scoping, to name the other two relevant specs. And while Temani Afif alludes to the second one (and what was proposed when ::shadow was removed), this is not the same: nobody tries to select into the shadow tree, it is just that the rule selects a corresponding element.
That is where Firefox answers "yes" and Chrome answers "no". Which one is the bug? Interestingly, I could not find a bug report in either of the bug trackers.
An alternative using CSS variables that can cross the shadow with inheritance:
use[href*="rectangle"]:hover {
--f:red;
}
<svg style="display: none">
<symbol id="rectangle">
<rect style="fill:var(--f)" width="300" height="100" />
</symbol>
</svg>
<svg width="400" height="110">
<use href="#rectangle"></use>
</svg>
Works without inline style:
use[href*="rectangle"]:hover {
--f:red;
}
<svg style="display: none">
<symbol id="rectangle">
<style>
rect {
fill:var(--f);
}
</style>
<rect width="300" height="100" />
</symbol>
</svg>
<svg width="400" height="110">
<use href="#rectangle"></use>
</svg>

Render a Video inside an SVG element to ByPass Object-Fit Polyfills for Video Elements

I've seen a way of using SVG to center an <image> in the same way object-fit works. Because the <image> is part of an <svg> tag it means browser support is a whole lot better, and it removes the need for a polyfill for certain browsers. Basically it centers the image using xMidYmid in the preserveAspectRatio attribute and then you add the slice value as part of this attribute to make the image cover the container. It's brilliant.
I would like to use this method on <video> elements, because, for whatever reason, Microsoft have decided not to implement object-fit on video or canvas elements (?). I'm hopeful the technique will transfer OK, the problem I'm having is <video> elements only render inside an SVG tag when they are within a ` tag, because there is no native svg video element, like there is with .
Does anyone know how to make the inner <foreignObject> element and its child <video> element inherit the preserveAspectRatio attribute values from the <svg> tag? Or indeed how to set these attributes directly on the <foreignObject> tag?
I'd love it if there is a way of doing this.
Codepen
Here is a Codepen that shows the <image> and <video> tags and you can see the problem I have on the video one. https://codepen.io/pauljohnknight/pen/GyXLrK
HTML / SVG
<!-- THIS IS THE IMAGE THAT WORKS OK-->
<svg width="400px" height="400px" viewBox="0 0 579 375" preserveAspectRatio="xMidYMid slice">
<image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/9674/photo-1501366062246-723b4d3e4eb6.jpg" x="0" y="0" width="100%" height="100%"></image>
</svg>
<!-- THIS IS THE VIDEO THAT ISN'T PlAYING BALL -->
<svg width="400" height="400" viewBox="0 0 579 375" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
<foreignObject width="100%" height="100%">
<video autoplay loop x="0" y="0" width="400" height="400">
<source src="https://s3.eu-west-2.amazonaws.com/bakerboxvideos/handwriting2.mp4" type="video/mp4">
</video>
</foreignObject>
</svg>
CSS
body {
display: flex;
padding: 100px;
justify-content: center;
}
svg {
margin: 20px;
border: 5px solid;
box-sizing: border-box;
}

Linking an SVG polygon to an anchor

I'm trying to do something seemingly relatively simple, but after much googling and finicking , I can't seem to make it work.
I have an svg polygon that I'm using to clip an image into a triangle.
Currently it's inside a bootstrap column, (with an a tag in it) that links to an anchor point.
The issue with this, is that the div(square) all links to the anchor.
However, I have a bunch of these triangles adjoining, so I need the area that links to the anchor to be restricted to only what's inside the polygon clip path.
I have tried:
Moving the a tag inside the clippath tag
moving the a tag inside the polygon (as an href)
making the href in this format for svg xlink:href="#portfolioModal3"
I suspect it's some permutation of the third option that accomplishes my goal.
<div class="col-sm-4 portfolio-item dontwantpadding">
<a href="#portfolioModal3" class="portfolio-link" data-toggle="modal">
<div class='tri-up'>
<svg width="100%" height="100%" viewBox="0 0 100 87">
<clipPath id="clipTriangleUp">
<polygon points="0 87,100 87,50 0"/>
</clipPath>
<image clip-path="url(#clipTriangleUp)" preserveAspectRatio="none" width="100%" height="100%" xlink:href="http://placehold.it/1749x1510"/>
</svg>
</div>
</a>
</div>
I plan on making the svg paths transition to circles from triangles, so something that will adapt to a circle svg path is ideal.
Any help is much appreciated!
SVGs can have <a> elements. Try putting your link inside your SVG.
<div class="col-sm-4 portfolio-item dontwantpadding">
<div class='tri-up'>
<svg width="100%" height="100%" viewBox="0 0 100 87">
<clipPath id="clipTriangleUp">
<polygon points="0 87,100 87,50 0"/>
</clipPath>
<a id="svgtriangle"
xlink:href="#portfolioModal3" class="portfolio-link" data-toggle="modal">
<image clip-path="url(#clipTriangleUp)" preserveAspectRatio="none"
width="100%" height="100%"
xlink:href="http://placehold.it/1749x1510"/>
</a>
</svg>
</div>
</div>
Hopefully you won't have any issue with Bootstrap finding the data-toggle.
Update
Okay, so it seems Bootstrap won't find your modal "open" link automatically, so you need to add a click handler to the triangle and open the modal yourself.
var triangle = document.getElementById("svgtriangle");
triangle.addEventListener('click', function(evt) {
$('#myModal').modal('show');
});
Demo fiddle here
Try moving the a tag inside and directly surrounding the image only.
<a><img src="foo" /></a>

How to remove the top border of an embedded SVG element

This is a part of my HTML I have embedded the SVG element.
<div>
<embed id="svgsource" type="image/svg+xml" src="/CXF/2012-01-27---11-35-47/6.svg">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="900px" height="751px" onload="init()" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
</embed>
</div>
But when you go to this page, you notice a visible line on top of the SVG element, as if it has set a top border:
is there any way to get rid of that?
Why do you have an inline <svg> element inside the <embed>? Have you tried removing that part?
Maybe the svg you reference has a rectangle to serve as a border? In that case you'll need to change the "/CXF/2012-01-27---11-35-47/6.svg" file itself.