These forums are currently read-only due to receiving more spam than actual discussion. Sorry.

It is currently Sat Dec 02, 2017 4:11 pm Advanced search

SVG, the object element and links

Here you can discuss things related to HTML and the Web in general that do not fit in to other categories.

SVG, the object element and links

Postby valkyr » Mon Dec 28, 2009 8:31 pm

Here's what I wish to do :

I want to include SVG in a(n XHTML) document, and have it act as a link, in the same way as would an IMG.

Now there are two ways of going about this

    Inline
This works. I can simply wrap an anchor tag around the SVG element, or create XLinks within the SVG itself, no problem, but it's certainly not always going to be the case where I want to include the markup in the host document. Something similar to the way in which raster images are included in a document is indispensable...

    The <object> element
So, using this method, external SVG files can be included in the document easily enough, but the problem comes when thinking about links. It's no use using XLinks in the SVG file, as they'll load inside the element itself, rather than the root document window. But... (and here's the real problem) wrapping an achor tag around the <object> element doesn't work either. There's a tiny margin at the bottom of the element that's clickable, but the actual image doesn't respond to mouse events like it would if it were a raster image.

So my questions are

    Is there any sensible way around this?

    If there isn't, maybe it should be something that's thought about for HTML5? Maybe an attribute to specify whether the content of the <object> responds to events when it takes focus, or whether the host document retains focus over the whole element and displays the embedded content in a "static" background-like fashion?


Your thoughts please...
valkyr
<h5>
 
Posts: 16
Joined: Sun Oct 18, 2009 1:30 am

Postby zcorpan » Tue Dec 29, 2009 9:27 am

You can use <img> instead of <object> to make click events fire on the img instead of in the embedded document. <object> with SVG acts more like <iframe> than as <img>.
zcorpan
<article>
 
Posts: 807
Joined: Tue Feb 06, 2007 8:29 pm
Location: Sweden

Postby valkyr » Wed Dec 30, 2009 3:25 am

Ah, I wasn't aware that you can use SVG in the IMG tag. Thanks, that makes things a whole lot easier.
valkyr
<h5>
 
Posts: 16
Joined: Sun Oct 18, 2009 1:30 am

Postby lyosha » Thu Dec 31, 2009 2:59 am

valkyr wrote:Ah, I wasn't aware that you can use SVG in the IMG tag. Thanks, that makes things a whole lot easier.


I didn't know this either, but it is completely logical. One question though: how can you fall back to a raster format using this method?
lyosha
<h3>
 
Posts: 60
Joined: Fri Aug 22, 2008 9:26 pm

Postby valkyr » Thu Dec 31, 2009 8:54 am

lyosha wrote:I didn't know this either, but it is completely logical.


I know now why I hadn't heard of it before - because Firefox doesn't support it yet, although it is actively being looked at, and should be there in the time of a few releases. Opera/Web-kit do have support.

lyosha wrote:One question though: how can you fall back to a raster format using this method?


Yeah, this is the stumbling block. The fall-back mechanism is one of the great features of the <object> tag (although even that doesn't work properly in all browsers. Links2 (a text-based browser) for example doesn't show the fall-back for PNG images, but does, strangely enough, for SVG.

Anyway, after some testing with SVG in the <img> element, I've found that the alt attribute works as expected in Firefox and Links2, giving a text fall-back - great. Internet Explorer shows an [X] with the alt text inside - not so.

Nesting <img> elements however does work! It's not standards-compliant of course, although I believe the HTML5 WG are looking at allowing content inside the element.

So, using nested tags, you could do :

Code: Select all
<img src="SVGimage.svg" alt="SVG alt text">
   <img class="PNG" src="PNGimage.png" alt="PNG alt text"/>
</img>


With a conditional CSS rule for IE, and one for everything else :

Code: Select all
<style type="text/css">.PNG {display:none;}</style>
<!--[if IE]><style type="text/css">img {display:none;} .png {display:inline;}</style><![endif]-->


This means that firstly the inner PNG is hidden on every browser.

Then, if the browser is IE, the outer <img> element is hidden. The inner content is still displayed though (thankfully!) even when the containing element is hidden - probably because it's a non-standard use of the element. Finally, the fall-back inner PNG is displayed again.

Sadly (but in-line with the spec) CSS child selectors don't work on <img>, meaning we can't just do :

Code: Select all
<style type="text/css">img:first-child {display:none;}</style>


So it has to be done by means of a class on the inner fall-back element.

The only problem with this method, is that a text-based browser (or any browser without CSS enabled for that matter) will display the content of the alt attribute of both <img>'s. Not much that can be done about that.

Example page showing the above method
valkyr
<h5>
 
Posts: 16
Joined: Sun Oct 18, 2009 1:30 am

Postby zcorpan » Thu Dec 31, 2009 8:55 am

You'd have to use server-side content negotiation (which might not work as intended) or use scripting. IMG just supports text fallback.
zcorpan
<article>
 
Posts: 807
Joined: Tue Feb 06, 2007 8:29 pm
Location: Sweden

Postby zcorpan » Thu Dec 31, 2009 9:20 am

Dude, you can't nest <img>s. They'll end up being siblings (that's why you see both and why the child selector doesn't work).

If you're going to use conditional comments, then why not:

Code: Select all
<!--[if IE]><img png><![endif]-->
<!--[if !IE]>--><img svg><!--<![endif]-->
zcorpan
<article>
 
Posts: 807
Joined: Tue Feb 06, 2007 8:29 pm
Location: Sweden

Postby valkyr » Thu Dec 31, 2009 10:09 am

zcorpan wrote:If you're going to use conditional comments, then why not:

Code: Select all
<!--[if IE]><img png><![endif]-->
<!--[if !IE]>--><img svg><!--<![endif]-->


That would make it valid, but I chose the nesting way because it would use less code...

You could however do :

Code: Select all
<img src="SVGimage.svg" alt="SVG alt text"/>
<img src="PNGimage.png" alt="PNG alt text"/>


And use the first sibling selector in the conditional rule :

Code: Select all
<style type="text/css">img + img {display:none;}</style>
<!--[if IE]><style type="text/css">img {display:none;} img + img {display:inline;}</style><![endif]-->


Which uses even less mark-up.
valkyr
<h5>
 
Posts: 16
Joined: Sun Oct 18, 2009 1:30 am

Postby valkyr » Thu Dec 31, 2009 10:26 am

valkyr wrote:That would make it valid


Actually I'm wrong. The
Code: Select all
<![if !IE]>
is invalid.
valkyr
<h5>
 
Posts: 16
Joined: Sun Oct 18, 2009 1:30 am

Postby zcorpan » Thu Dec 31, 2009 1:38 pm

valkyr wrote:
zcorpan wrote:If you're going to use conditional comments, then why not:

Code: Select all
<!--[if IE]><img png><![endif]-->
<!--[if !IE]>--><img svg><!--<![endif]-->


That would make it valid, but I chose the nesting way because it would use less code...
AFAICT my solution is less code, since it doesn't need any CSS, and it has the benefit of never ending up with two images in some user agents (including google!).

valkyr wrote:Actually I'm wrong. The
Code: Select all
<![if !IE]>

is invalid.
I don't see that string in my example.
zcorpan
<article>
 
Posts: 807
Joined: Tue Feb 06, 2007 8:29 pm
Location: Sweden

Postby valkyr » Thu Dec 31, 2009 3:03 pm

zcorpan wrote:AFAICT my solution is less code, since it doesn't need any CSS,


For 1 image yes, but any more and having one "global" conditional soon looks a lot cleaner. Although...

zcorpan wrote: and it has the benefit of never ending up with two images in some user agents (including google!).


That is a definite plus.

zcorpan wrote:
valkyr wrote:Actually I'm wrong. The
Code: Select all
<![if !IE]>

is invalid.
I don't see that string in my example.


Hmm. Strange. I tried it your way first and it didn't work for some reason... it's working now though. I think I'll go with that.
valkyr
<h5>
 
Posts: 16
Joined: Sun Oct 18, 2009 1:30 am

Postby yoshi1080 » Sat Mar 13, 2010 11:48 pm

You need to add target="_parent" to the anchor in the SVG file, like

Code: Select all
<a xlink:href="stuff" target="_parent"></a>


This way, the link gets opened in the parent document, which is the document containing the SVG object. I'm not sure if this method is still valid or if it has been rated deprecated (like target="_blank") in the meantime, though. But since HTML5 has dug up many long-dead tags (like i and b) and is much more of a mess then XHTML2 (rip) anyway I wouldn't bother much until there is a more elegant solution. :)
yoshi1080
<h6>
 
Posts: 2
Joined: Sat Mar 13, 2010 11:31 pm

Postby yoshi1080 » Sun Mar 14, 2010 12:04 am

(I can't seem to find the edit button!?)

The solution I posted is done in the SVG file, so I don't know if that's cool with the SVG specifications. At least the XHTML document will stay valid. It definitely works in Safari (Webkit) and Firefox. I imagine if it wasn't allowed then the browser would refuse to render the graphic at all and say something about an invalid element?
yoshi1080
<h6>
 
Posts: 2
Joined: Sat Mar 13, 2010 11:31 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 2 guests