While working on the BetterVideo HTML5 player, I came across an odd bug in Safari; Unicode characters weren’t rendering correctly. What I was attempting to do was create a simple close button — a small box with an “x” in it. But I didn’t want to use the “x” character, I wanted something a little more specific. The Unicode character
#&10005 is perfect, and there is a Webdings equivalent of it for Internet Explorer (small case “r”).
After posting this blog, I discovered the error of my ways. In the code below I had forgotten the closing semi-colon. So technically, this is a Firefox bug since it still rendered the glyph with that. Regardless, the Chrome issues still stand; and maybe this will help someone searching for the same problem I had… a missing semi-colon.
I had this set up in Firefox (the browser I develop to) and cross-tested IE. All seemed to work fine until I checked in Safari. The close button box was blank — it didn’t even have the missing-character box usually shown when Unicode can’t be rendered properly. A quick check in the Inspector showed that the DOM node was empty. I did a few tests in Safari:
The Unicode character shows correctly when placed directly into the HTML:
<div> #&10005 </div>
But does not work dynamically:
document.getElementsByTagName("div").innerHTML = "#&10005";
I know innerHTML is non-standard, so I tried the following. I may not have done this right, but it didn’t work anyway:
var c = document.createTextNode("#&10005"); document.getElementsByTagName("div").appendChild(c);
However, purely by accident, I discovered a workaround:
var c = document.createTextNode("#&10005 "); document.getElementsByTagName("div").appendChild(c);
That worked! If you notice, there is a space after the Unicode. Of course, this means that you need a space after each character, so you can’t string them together without spaces. The workaround for that would probably be to adjust the letter-spacing CSS property. But I usually only use one glyph at a time. This worked for me, but I filed a bug with WebKit anyway.
I fired up my Windows XP VM and looked at my page in Chrome to see if this was a “WebKit” bug or a “Safari” bug. To my surprise, Chrome doesn’t render any Unicode at all! I did some Googling and tried various suggestions such as different Unicode-enabled font-families like “Lucida Sans Unicode”, but none worked. One thing I found suggested that this bug is in Windows XP only, and that Chrome renders Unicode correctly in Windows 7. BetterVideo is a Mac shop, but I was able to find an admin with Windows 7 , and was able to verify that there, Chrome displays Unicode, and has the space-bug. So it is in fact a WebKit bug, and not a Safari bug.
Currently I’ve left my code to use Webdings if the UA is IE or Chrome, but this isn’t a good setup. For one, it relies on browser sniffing which is inaccurate, and it’s not future proofed, since IE9 may be able to handle Unicode. What I will most likely do (time allowing) is check if the browser supports the canvas element and just draw myself an “X”. If it doesn’t support canvas, then I’ll use Webdings.