14

I have an interactive SVG - displayed at full window size. I want to add some buttons to it. Is it possible to add normal <button> elements inside <svg> tag?
I think not, but I'm asking if there is something similar for SVG.
From some drawing I get bad results like this:
https://jsfiddle.net/pvxr6g8k/1/

<svg version="1.1" id="svg9723" height="768" width="1268">
<g style="fill:#e6e6e6" id="g3332-7" transform="matrix(0.27404175,0,0,-0.447665,86.580009,508.16151)">
      <g style="fill:#e6e6e6" clip-path="url(#clipPath3336-0-0)" id="g3334-7">
        <g style="fill:#e6e6e6" transform="translate(992.5469,164.3086)" id="g3340-6">
          <path inkscape:connector-curvature="0" id="path3342-2" style="fill:#e6e6e6;stroke:#241a5d;stroke-width:4.48957968;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1" d="m 0,0 c -6.937,0 -12.58,5.645 -12.58,12.58 l 0,63.277 c 0,6.937 5.643,12.581 12.58,12.581 l 279.488,0 c 6.936,0 12.58,-5.644 12.58,-12.581 l 0,-63.277 C 292.068,5.645 286.424,0 279.488,0 L 0,0 Z"></path>
        </g>
      </g>
    </g>
    <text transform="scale(0.9324557,1.072437)" id="text3390-1" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:11.87269115px;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, Bold';writing-mode:lr-tb;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" x="413.18262" y="390.15326">
      <tspan style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:'Arial Bold'" y="390.15326" x="413.18262" id="tspan3392-0" sodipodi:role="line">BUTTON</tspan>
    </text>
    </svg>

The problem is not the visual appearance, but the structure, which not allow me to bind event or interact with it using JS. Not to mention the visual click effect of button "press" is harder to achieve like that.

So what is the solution for buttons in interactive SVG? Any good element like button in HTML?

I don't have to embed html button, any good button replacement would be fine

user3599803
  • 6,435
  • 17
  • 69
  • 130

5 Answers5

16

<button> is an HTML element, and therefore can't go (directly) in an SVG element.

However, you can consider using

<foreignObject position attributes>
    <html:button>Button1</html:button>
</foreignObject>

Just make sure you properly declare the namespace, for instance on your root <svg> element, with xmlns:html="http://www.w3.org/1999/xhtml"

This works in most browsers. Internet Explorer doesn't support it, but Microsoft Edge does.

Alternatively, you could just draw your own button-like <rect> and attach a click event handler to it, that'll work just fine too.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • 2
    That seems good. Simple question - why is xmlns.is important, does the browser dont know html already? Does it make a request to this w3 page? – user3599803 Oct 08 '16 at 06:11
  • 1
    If your SVG is actually embedded in an HTML5 document then you don't need it, but if it's a standalone SVG file then you need to specify namespaces so the browser knows where everything is coming from. – Niet the Dark Absol Oct 08 '16 at 10:05
3

You can insert at least a link (and style it afterwards like a button). I put the link with Illustrator in the SVG. Maybe a button is possible too. But you can see working links on our site http://www.kleinefische.com

In the svg it looks like:

<a xlink:href="http://www.kleinefische.com" >
   <polygon fill="none" points="162,263.3 251.6,256 252.7,273.3 163,280.5"/>
   <text transform="matrix(0.9967 -8.087198e-02 8.087198e-02 0.9967 162.7812 272.6545)" 
    fill="#FFFFFF" font-family="'TradeGothicLT-Bold'" font-size="12.9937">
      /AGENTUR
   </text>
</a>
Alex78191
  • 2,383
  • 2
  • 17
  • 24
1

You can use <foreignObject> for that. SVG allows inclusion of elements from foreign namespaces anywhere with the SVG content. In general, the SVG user agent will include the unknown elements in the DOM but will otherwise ignore unknown elements. foreignObject

Ashok kumar
  • 544
  • 1
  • 5
  • 21
0

You could add an onclick property to your svg object, something like:

onclick='window.location =("http://...");'

piem
  • 1
  • 4
-7

You could try out D3JS.

See documentation here on handling mouse events: https://github.com/d3/d3-selection/blob/master/README.md#handling-events

And an example: Unable to get click event in D3 JavaScript library

Community
  • 1
  • 1
rumski20
  • 361
  • 4
  • 13