How to "use" local "defs" in SVG - html

I have multiple SVG pictures embedded into single HTML page.
Every SVG has own defs section that I am referencing to in my use elements.
It looks like I can't define element with the same id inside multiple defs and reference to it.
Second SVG use will pick the definition form the first SVG defs section, and ignore the local redefinition.
Does anybody know how I can reference to the LOCAL defs section?
The same story in Chrome and Firefox.
See the example below:
<html><head></head><body>
<svg height="50" width="50">
<defs>
<rect id="mybox" height="40" width="40" style="fill:#00F;"></rect>
</defs>
<use xlink:href="#mybox"/>
</svg>
<svg height="50" width="50">
<defs>
<rect id="mybox" height="20" width="20" style="fill:#F00;"></rect>
</defs>
<use xlink:href="#mybox"/>
</svg>
</body></html>

An SVG file with multiple identical IDs is invalid per http://www.w3.org/TR/SVG/struct.html#IDAttribute
Your options are either make all the IDs unique or move the SVG into separate files and reference them via <object> or <iframe> tags.

I created a tool to randomize definition id's to avoid this issue with inline svg's referencing the same #id, hopefully it will be useful for someone else. http://hugozap.com/randomize_svg_def_ids.html

One way to solve this is using svgo
svgo --enable=prefixIds *.svg
svgo can be installed via npm and is available as a library as well

Related

Relative path in SVG to embed <image> when loaded from HTML [duplicate]

This question already has an answer here:
How many levels of recursion does SVG support?
(1 answer)
Closed 1 year ago.
i have created an SVG which has an image embedded.
I did this because i want the descriptions to be scalable.
The problem is, when i load the SVG only in chrome, the image is displayed.
When the svg is embedded in an img tag in the html though, i dont see the image.
When i write the svg code in the html file on the other hand the image is displayed.
I think the problem might be a pathing issue but im not sure as i dont get any errors displayed.
The SVG and IMG are in the same folder.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1189.851"
height="539.932">
<image overflow="visible" width="1190" height="540" href="/pics/mashup/e-55211-10-piww-000.png"
transform="translate(0 -.034) scale(.9999)"/>
<g stroke="#1D1D1B" stroke-width="4.693" stroke-miterlimit="10">
<path fill="#FFF" d="M998.689 395.155l-10.44 21.628-67.39-33.204 10.454-21.633z"/>
<path fill="#FFF" d="M911.808 448.549l-22.247-8.621 26.866-70.699 22.247 8.625zM889.081
449.676h23.832v36.11h-23.832z"/>
<path fill="#FFF" d="M920.424 447.646c-2.273 10.825-12.828 17.741-23.553 15.44-10.729-2.301-17.576-12.942-
15.299-23.79 2.283-10.839 12.828-17.75 23.563-15.45 10.715 2.305 17.572 12.952 15.289 23.8zM1012.159
414.767c-4.812 9.959-16.71 14.093-26.559 9.24-9.863-4.854-13.955-16.857-9.148-26.825 4.804-9.959 16.696-
14.089 26.555-9.239 9.858 4.857 13.951 16.861 9.152 26.824zM946.415 380.806c-3.928 10.345-15.413 15.514-
25.66 11.55-10.229-3.969-15.34-15.577-11.417-25.917 3.933-10.34 15.422-15.514 25.656-11.545 10.248 3.968
15.362 15.564 11.421 25.912z"/>
<path fill="none" stroke-linecap="round" d="M980.243 420.437c-6.976 7.153-6.77 18.754.453 25.931M1009.065
446.372c6.972-7.159 6.774-18.75-.444-25.94"/>
</g>
I tried both and they dont work when loaded from an img tag, but do work when opened in browser or inspecting the element:
href="/pics/mashup/e-55211-10-piww-000.png"
href="e-55211-10-piww-000.png"
Thats how i want it to work.
<li class="c-linkedarea" data-content="img2 img" data-display="flex">
<img src="/pics/mashup/e-55211-10-piww-000.svg" alt="Microwall VPN Funktionsgrafik">
</li>
Thanks in advance
The solution to your question has been perfectly addressed by Erik Dahlström in his post here
Here is what CSS tricks has to say about it:
If “inline” SVG just isn’t your jam (remember it does have some legit drawbacks like being hard to cache), you can link to an SVG file and retain the ability to affect its parts with CSS by using .
Basically, you need to put your svg source inside the html <object> element like below:
<object data="pathToYourSVG.svg" type="image/svg+xml">
<img src="backUpImgFileIfSVGDoesNotWork.jpg" />
</object>

Is it possible to make the img tag display svg images that cointain addresses inside it? [duplicate]

This question already has an answer here:
How many levels of recursion does SVG support?
(1 answer)
Closed 2 years ago.
I have created the following SVG file:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="150" height="150">
<rect
x="5"
y="5"
width="140"
height="140"
style="fill:white;stroke:black;stroke-width:1"
id="rect2"
/>
<image
y="50"
x="80"
id="image76"
xlink:href='https://image.flaticon.com/icons/svg/46/46441.svg'
preserveAspectRatio="none"
height="60"
width="60"
/>
<image
y="50"
x="10"
id="image76"
xlink:href='https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Android_robot.png/646px-Android_robot.png'
preserveAspectRatio="none"
height="60"
width="60"
/>
</svg>
I've managed to display it using the object tag like the following and it works fine:
<object type="image/svg+xml" data="image.svg"></object>
The result is like this:
However, when I try to use the img tag I have the following result:
<img src="image.svg"/>
When I try to display this svg file with the img tag, the images that are inside it disappear. I know it happens because I'm using addresses like https://image.flaticon.com/icons/svg/46/46441.svg and https://upload.wikimedia.org/wikipedia/commons/thumb/6/66/Android_robot.png/646px-Android_robot.png for my images instead of writing a base64 image inside this svg. But because it's possible with the object tag I'm curious to know if it's also possible with the img tag. Is it possible to make the img tag open svg files like this one? Or is it a limitation of the img tag?
No documents loaded in <img> can not request any external resource, can not execute scripts, can not receive any user event.
For your bitmap image, you'd have to embedded it as a data: URI in the svg itself.

How to <use> the <svg> element correctly for loading external sources?

I've followed many guides to adding external SVGs to a page... like this one : http://wearejh.com/design/inline-svg-use-element/
The code is like this:
<svg>
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/5/53/Skull_and_crossbones.svg"></use>
</svg>
It just does not load, example here: http://jsbin.com/cipacitovo/edit?html,output
What am I doing wrong?
Per the SVG specification
Unlike ‘image’, the ‘use’ element cannot reference entire files.
You need to add a fragment identifier to the URL to indicate which item within the image you are trying to display.
Why dont you use svg in img tag.Because you are not generating anything instead you are loading.
Check the example
You forgot to add xmlns:xlink="http://www.w3.org/1999/xlink" in <svg>.
This is how it should be:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="https://upload.wikimedia.org/wikipedia/commons/5/53/Skull_and_crossbones.svg"></use>
</svg>

SVG Pattern Doesn't Show on Page

I am completely clueless, what is going wrong with my svg pattern. I defined it in the def section of the svg and then tried to reference it. But it doesn't show up once I include the svg in an img-tag. If I open it on itself in the browser everything is good though.
See the following examples:
http://kijani.co/img/sketch/index.html
http://kijani.co/img/sketch/livingroom.svg
And my code:
<defs>
<pattern id="paper" patternUnits="userSpaceOnUse" width="200" height="200">
<image xlink:href="http://kijani.co/img/pattern/paper.jpg" width="200" height="200"/>
</pattern>
</defs>
<g id="background">
<path id="paper" fill="url(#paper)" d="..."/>
</g>
This might be a really stupid question, but I am fairly new to svg and couldn't find a solution anywhere so far.
This is svg's referencing mode probrem.
Using img element to display svg image is restrected for refering outer resources.
So you should use object element to display svg image, or embed pattern image into svg by data scheme format.

Embed group from svg file into html

I want to embed a group from an SVG file, that can be identified with an id. My naive approaches were:
1. embed
<embed src="cards/svg-cards.svg#joker_red"
id="embsvg"
width="300" height="220" type="image/svg+xml"
pluginspage="http://www.adobe.com/svg/viewer/install/"
viewBox="0 0 100 100"
/>
2. image
<image id="i" x="10" y="20" width="80" height="80"
xlink:href="cards/svg-cards.svg#joker_red" />
3. object
<object data="cards/svg-cards.svg#red_joker"></object>
and I tried some more silly variants including the USE element and javascript.
The svg document was taken from here: Sourceforge
I found it out myself.
The important piece was, to give all visible elements a class attribute, say class="card" and specify 'svg .card { display: none }' as a style. That will make everything disappear. Then only the item that is selected via # behind the svg file name is actually displayed.
It doesn't really matter if the part to be displayed is a group or svg element.
Robert's posted code did it this way, but it was not obvious to me how important the class was.