If you encountered the error "Attribute only valid on v:image" in IE, and would like to find the root cause, you are in luck!
First, here are some characteristics of the bug:
- It happens only in quirks mode - which means IE7 and below, but could also happen in newer IEs if the web page explicitly turns on EmulateIE7 mode by using the meta tag
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
- It is associated with VML, which is Microsoft's old vector graphics markup engine, and which is no longer supported starting IE 10. This makes sense because VML only works in quirks mode.
The Bug
Let's see an example page
<html xmlns:v>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<style>v\: * { behavior:url(#default#VML); display:inline-block }</style>
</head>
<body>
<v:image src="x.gif" id="image" style="top:1px; left:1px; width:200px; height:200px"/>
<v:rect id="rect" style="width:100pt;height:80pt;" strokecolor="red" strokeweight="2pt"/>
</body>
</html>
To test, render this page in IE7 or below or an emulated IE7. This renders an image <image>
as well as a rectangle <rect>
. The bug is triggered when access to the src
property of the element rect
is attempted:
> rect.src // throws "Attribute only valid on v:image"
Okay, this is not the bug, it actually even makes sense that a rect shouldn't have a src
property. The bug is that once this error occurs for any VML element, any property access for any VML element is poisoned with this same error message:
> rect.id // throws "Attribute only valid on v:image"
> rect.nodeType // throws "Attribute only valid on v:image"
> rect.nodeName // throws "Attribute only valid on v:image"
> image.id // throws "Attribute only valid on v:image"
> image.nodeName // throws "Attribute only valid on v:image"
Amusingly, however, sanity can be restored if you now access a VML image element's src
property
> image.src // returns 'x.gif'
> rect.id // returns 'rect' again, as it should
One More Thing
Actually, this bug is even more disastrous - it persists across page refreshes. If the VML system is in the poisoned state, refreshing the page, or even navigating to another page won't help. The poisoned state will only go away if one of the following happens
- The
src
property of a VML image element as accessed, as previously described. - Restarted the browser.
The implication of this is that, your site - if implemented using VML - could exhibit this error even if it was another site that put the engine into the poisoned state.