This works:
<img src="img/home/icon.svg" alt="one" class="trysvg">
This doesn't work:
<svg>
<use xlink:href="img/home/icon.svg" class="trysvg"></use>
</svg>
CSS:
.trysvg {
//position: relative;
//display: block;
//color:black;
height: 20rem;
width: 20rem;
}
When checking dev tools and trying it with use svg it shows shadow-root (closed). Tried to search, but couldn't come up with any solution. SVG icon is from reliable source - downloaded, so there shouldn't be a problem with svg code. Any ideas?
edit: I also tried to put class on the < svg class... >, was still not working and also put class on < svg class... > + < use class.. > and still nothing.
edit2: when I use href instead of xlink href the problem remains..
SVG 1.1 does not permit <use> elements to point to an entire file. SVG 2 does permit this but no browser has got round to implementing that part of the SVG 2 specification yet.
If you want to use a <use> element and have it work with today's browsers, you'd need to put an id on the <svg> root element and have a fragment identifier that references that id.
Related
.i image,
.i path,
.i {
fill: red;
stroke: red;
margin-top: 5px;
}
<svg class="i">
<image class="i" xlink:href="https://nextgenthemes.com/wp-content/bubble.svg" height="100%" width="100%"/>
</svg>
It does work if I use the <use> element and reference a symbol from a svg definitions file.
jsbin
The SVG <image> element does not accept fill as an attribute. So it would not accept the CSS fill equivalent.
W3C SVG <image> element: http://www.w3.org/TR/SVG11/struct.html#ImageElement
Attribute definitions for the SVG <image> element :
x = The x-axis coordinate of one corner of the rectangular region into which the referenced document is placed.
If the attribute is not specified, the effect is as if a value of '0' were specified.
Animatable: yes.
y = The y-axis coordinate of one corner of the rectangular region into which the referenced document is placed.
If the attribute is not specified, the effect is as if a value of '0' were specified.
Animatable: yes.
width = The width of the rectangular region into which the referenced document is placed.
A negative value is an error (see Error processing). A value of zero disables rendering of the element.
Animatable: yes.
height = The height of the rectangular region into which the referenced document is placed.
A negative value is an error (see Error processing). A value of zero disables rendering of the element.
Animatable: yes.
xlink:href = A IRI reference.
Animatable: yes.
If it works with the SVG <use> element than use it!
What you want is not possible, for two different reasons.
SVGs loaded via HTML <img> or background-image, or via an SVG <image> can be considered as being rendered to a static form whose contents are not styleable by the parent. Think of it as having been converted to a bitmap.
CSS rules do not apply across document boundaries. You cannot have rules in one document (the HTML) that style elements in another document (in this case the SVG bubble.svg).
I'm attempting to move from font icons (icomoon.io) to SVG sprites. Is it possible to use SVG sprites without needing < svg > markup for each icon instance?
What I really liked about the font icons was that I didn't have to clutter my HTML with any additional elements to get the icon to display. I usually just targeted a simple class on whatever element I wanted the icon to display and then used pseudo selectors to display the icon, e.g.:
<h1 class="news">News</h1>
h1.user:before {
font-family: 'icons';
content: '\news';
}
That made a lot of sense to me, and all of my icons were easily managed almost completely in CSS. I rarely had to touch my HTML as long as my markup contained appropriate classes.
I've since switched my build system to Grunt and thought I'd give SVG sprites a try. Almost every1 article2 I3 can4 find5 on the subject says you need to add an additional SVG element to your markup wherever you want each instance to display, e.g.:
<h1>
<svg class="icon">
<use xlink:href="#icon-news">
</svg>
News
</h1>
That seems like a step backwards to me, at least in the management of markup. To me, an icon is usually presentation that should be separate from document structure. Are we doing it this way simply because of the state of SVG support in browsers?
Ideally, I'd love to be able to do something like this:
<h1 class="news">News</h1>
h1.news:before {
display: inline-block;
width: px;
height: px;
background: url(icons.svg#news) no-repeat;
}
This post seems to be closer to what I'm looking for, but I'm not sure of browser support and how to do it automatically in a build system like Grunt.
SVGs can be loaded as files exactly the same way as other images using <img> tags or CSS background, and can be used as sprites exactly the same way too. The only difference is that you have to specify the size you want it (because it's scalable, so the browser doesn't automatically know how big it is like it does with PNGs).
Depending on how you want to use the image, loading them this way may or may not be suitable as some SVG features aren't available, but it can be done.
I have many icons svg, I could use them as fonts if that is helpful and I would like to use ng-click(basically any kinda of click you know) the way that when i click on svg1 and svg2 wont be clicked. Till now i have tried allot of icons and many ways of doing it without success. I have upload to codepen small example, each region of that country have it's own svg which cover other svg's and make click on them impossible. Basic use of svg is below:
<svg>
<use xlink:href="#icon-region"></use>
</svg>
Since all <svg> elements in your page are absolute positioned and have both width and height of 100%, it's possible to only catch elements from the last element. That behavior comes from the way elements are rendered, within layers, like the example bellow:
+-<svg>--+
|+-<svg>--+
||+-<svg>--+
||| |
+|| |
+| |
+--------+
If all those elements have the same width, height and position you can only catch events from the last one, on the top of all.
To avoid this behavior you can do the following, with CSS:
.regionPosition {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
pointer-events: none;
}
.regionPosition > * {
pointer-events: all;
}
This way you disable the event listening from <svg> elements – with regionPosition class – and catch only the events from their immediate children.
Since you're using <use> inside your SVG to get the actually graphics, you can't rely only on Angular to bind the event, because the elements are not yet there when you load the script. You'll need to attach the event listener to the document and then check the target before call the function you want. This can be easily done with jQuery, as follows:
jQuery(document).on('click', '.regionPosition > *', function () {
// Call your function.
});
I changed your code a bit to show how to do it, here: http://codepen.io/anon/pen/waLwrm. I'm using a simple window.console.log() call to just log the clicked element. You can change it to another logic in your final code.
Reference:
jQuery hover problem due to z-index
Please have a look at this Pen:
http://codepen.io/troywarr/pen/VYmbaa
What I'm doing here is:
defining an SVG symbol (<symbol>)
defining an SVG linear gradient (<linearGradient>)
using the <use> element to reference the SVG symbol I've created
in the CSS, defining two classes:
external, which references the linear gradient defined in this external .svg file (right click and view source)
internal, which references the linear gradient defined in the local HTML (which is, I believe, effectively identical to the one in the external file)
Because I've applied the internal class to the <svg> element at the bottom of the HTML example, the gradient is applied, rendering a blue gradient checkmark. That's what I'm after.
But, if you switch the internal class to external in the HTML example, the checkmark is no longer visible:
http://codepen.io/troywarr/pen/vEymKX
When I watch Chrome Inspector's "Network" tab, I don't see the browser trying to load the SVG file at all. Is there a problem with my syntax, or is something else going on here?
It at least looks like I'm doing this right, based on a few references I've found:
http://www.w3.org/TR/SVG/painting.html#SpecifyingPaint
http://www.w3.org/TR/SVG/linking.html#IRIReference
https://stackoverflow.com/a/7118142/167911
But, nothing I've tried so far has allowed me to reference a linear gradient defined in an external .svg file.
Thanks for any help!
After more research, it looks like this is a browser support issue. See:
https://code.google.com/p/chromium/issues/detail?id=109212
https://bugs.webkit.org/show_bug.cgi?id=105904
Sadly, I'd come across this question before posting mine, and had thought that surely, in 5-1/2 years, browser support would have caught up - but that doesn't appear to be the case.
As of 2015, apparently Firefox and Opera are the only two browsers to support this in any substantial way.
Back to the drawing board...
You can use svg4everybody with polyfill: true option, it will insert all external symbols instead of use tags. But it will cause the second svg loading.
So you can download svg using an ajax request and then insert it on the page hiding with the styles.
<script>var ajax=new XMLHttpRequest;ajax.open("GET","/img/svg-sprite.svg",!0),ajax.send(),ajax.onload=function(a){var b=document.createElement("div");b.classList.add("hidden"),b.innerHTML=ajax.responseText,document.body.insertBefore(b,document.body.childNodes[0])};</script>
In this case:
/img/svg-sprite.svg — is your svg path.
.hidden class styles:
.hidden {
position: absolute !important;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(1px, 1px, 1px, 1px);
}
And your code might look like this:
<svg><use xlink:href="#logo"></use></svg>
Are there situations where an SVG <text> element's dominant-baseline style will be ignored?
I have two <text> labels in two different parts of my SVG. The dominant-baseline: central applied to one works without issue (for example, when I open it up in Chrome's web inspector and change the value, the element moves around as I would expect it to), but it does not seem to affect the other (ex, changing the style's value from the web inspector doesn't change the position of the element).
Is there any reason this could be?
Here is a screenshot of the relevant code:
(I'll post a fiddle demonstrating the problem if I can figure out how to reproduce it)
The culprit was an errant display: inline that the .label was inheriting from its HTML counterpart.
The fix:
svg.label {
display: block;
}