0

Hi I'm pretty new to js and I don't understand very well how svg is supposed to work.

I have generated a svg file I want to use in the webpage. The file is quite big and I don't want to paste it inline, because I want to be able to replace it with another one. I also need to have access to it's elements so, AFAIK, the only option is to load it as <object> instead of as <img>

However I'm finding a lot of caveats when I load it in this way.

One of them is the drawing order when I want to add more svg layers over the object.

If I write the elements in this order

blue circle svg
object
green circle svg

I see the blue circle over the object and the green circle NEXT to the object (as if it was pushed by the object). I would expect to see the first element I drew in the background and the last one on the front.

<svg width="500" height="500" xmlns="http://www.w3.org/2000/svg">
<circle id = "AGV01R" cx = "140" cy="100" r = "20" fill = "blue"></circle>
</svg>

<object type = "image/svg+xml" data="http://upload.wikimedia.org/wikipedia/commons/5/57/Weakness_of_Turing_test_1.svg" class="plano" id="plano"></object>

<svg width="500" height="500" xmlns="http://www.w3.org/2000/svg">
<circle id = "AGV02R" cx = "140" cy="100" r = "15" fill = "green"></circle>
</svg>

http://codepen.io/mrcasty/pen/egXaBj

Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
javanoob
  • 163
  • 1
  • 1
  • 10
  • I would appreciate any alternative to use objects when I want to get access to the internals of an embeded svg – javanoob Feb 15 '17 at 23:25
  • I provided [this answer](http://stackoverflow.com/a/35788464/5218951) to a different question about how to apply styles to external svg elements, but the principle applies here I believe. You can inline an external svg element as described in that answer and then manipulate it in whatever way you want (e.g. using JavaScript to add blue and green circles above and below, etc.) after inlining. – Andrew Willems Feb 16 '17 at 01:53

1 Answers1

0

If you want to position three HTML elements so they are stacked on top (over) one another, the best solution is to wrap them in a container that is also "positioned". By that I mean it has a position property in its style.

Normally people will use position: relative, because that doesn't affect the normal flow position of the container element.

.container {
  position: relative;
}

.container svg,
.container object {
    position:absolute;
}
<div class="container">

  <svg width="500" height="500" xmlns="http://www.w3.org/2000/svg">
    <circle id = "AGV01R" cx = "140" cy="100" r = "20" fill = "blue"></circle>
  </svg>

  <object type = "image/svg+xml" data="http://upload.wikimedia.org/wikipedia/commons/5/57/Weakness_of_Turing_test_1.svg" class="plano" id="plano">
</object>

  <svg width="500" height="500" xmlns="http://www.w3.org/2000/svg">
    <circle id = "AGV02R" cx = "140" cy="100" r = "15" fill = "green"></circle>
  </svg>
  
</div>

As to your other question. If you want to manipulate the DOM of an SVG you have to either inline it, or use <object>. There is no other choice.

What some people do is use a script that runs on page load that loads external files and automatically inlines them. As suggested by @andrew-willems:

Include SVG files with HTML, and still be able to apply styles to them?

Community
  • 1
  • 1
Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • Thanks, the object position absolute works great even if I don't use a div. However, I understand why it fixes the positions, but I don't understand why it fixes the drawing order as well. Why in my codepen the blue circled was drawn in front of the object and not behind it? – javanoob Feb 16 '17 at 09:01
  • Non-positioned elements are drawn before positioned ones. So the `` is drawn before the two `` elements. – Paul LeBeau Feb 16 '17 at 10:26
  • Ultimately, in the [CSS specification](https://www.w3.org/TR/CSS2/visuren.html#z-index). But it is the sort of esoteric detail you pick up with experience. – Paul LeBeau Feb 17 '17 at 06:58