Last week I was tearing my hair out trying to track down why the latest version of this site was rendering so badly in legacy versions of Internet Explorer.
It was particularly annoying because I’m such a strong believer in progressive enhancement. I try to build my projects with the basics first, then layer on the more sophisticated bits. That usually makes legacy browser support easier, if not trivial. The fancy stuff typically doesn’t render or get in the way, and foundation-level content still works in the accounting department’s crusty old browser of choice. But not this time.
Specifically, jQuery was going a little nuts trying to traverse the DOM in IE8 or older, returning weirdly inconsistent results. Here’s a sampling of some queries and their pass/fail results:
$('div[role="contentinfo"] nav')= failed
After doing a few reductions I found the issue, and it wasn’t at all what I expected: inline SVG. Specifically, there are two components of inline SVG that seem to scramble legacy IE’s brain:
- The XML namespace attribute: Removing the
svgelements (or simply setting its value to “ ”) returns sanity to the DOM. Interestingly, related attributes such as
xmlns:xlinkdon’t have a similar negative impact. Only the default namespace attribute causes this behavior.
- Self-closing elements inside inline SVG: The presence of self-closing child elements in inline SVG (like
<path />) consistently triggers this issue in IE8 and lower. This one also has an easy fix. Simply change self-closing child elements in your SVG to have a separate closing tag. So instead of
<circle />, use
Update: Both Fixes Work
I’ve updated this post to reflect feedback I’ve received since it was initially published. Tab Atkins responded on Twitter to point out that xml attributes should be ignored by the HTML5 parsing algorithm in modern browsers, so they can be safely removed. That means both methods are viable options for bulletproofing your inline SVG, allowing it to degrade gracefully in older versions of Internet Explorer.