28

I'm working on a music related website, and frequently use the HTML special characters for sharps (♯) and flats(♭) to keep things pretty, e.g.:

♯
♭

However, I've noticed that in some browsers (IE6, Safari for PC) those characters aren't supported. I've created a conditional javascript that serves up plain, supported characters in place of the special ones ( G# for G♯ and Bb for B♭ ). But I'm having a hard time figuring out how to detect which browsers lack those characters.

I know I could test for the browser (e.g. ie6), but I was hoping to do things right and test for character support itself.

Does anyone know of a good way to do this using either javascript, jQuery, or rails? (The page is served by a rails app, so the request object and any other Rails magic is on the the table.

4
  • I ended up going with Mike Samuel's excellent solution, though I think those indicating formatting issues may have something there -- I did attempt all solutions, but that doesn't mean I haven't missed anything. Anyone undergoing a similar issue should, as the others have suggested: 1. ensure their page has proper character encoding, 2. see the linked answer referenced by Matt Ball. I have a sneaking suspicion 99% of the time his might be the better solution than a javascript hack. Commented Jan 8, 2011 at 20:04
  • I suspect that this is a font issue. The chosen font does not contain the graphemes for the code points you want. Many modern browsers can compensate for this using font substitution (picking the grapheme out of another font). Mike Samuel's solution is clever, but might not work if fixed-width fonts get involved. Unfortunately, I don't have any better solutions. Commented Jan 9, 2011 at 10:56
  • @McDowell - Hm... I looked over this list of fonts and didn't see any web-safe fonts that might be on systems with ie6. So I simply tried 'sans serif' without success. Am I missing something here? What's a good choice? Commented Jan 9, 2011 at 18:28
  • Microsoft seems to claim that Arial Unicode MS works, but it doesn’t for me (or possibly my version of Windows XP doesn’t include it). Commented Jun 8, 2011 at 13:31

4 Answers 4

25

If you create two SPANs, one containing the character you want, and the other containing an unprintable character U+FFFD (�) is a good one, then you can test whether they have the same width.

<div style="visibility:hidden">
  <span id="char-to-check">&#9839;</span>
  <span id="not-renderable">&#xfffd;</span>
</div>
<script>
  alert(document.getElementById('char-to-check').offsetWidth ===
        document.getElementById('not-renderable').offsetWidth
        ? 'not supported' : 'supported');
</script>

You should make sure that the DIV is not styled using a fixed font.

Sign up to request clarification or add additional context in comments.

13 Comments

very clever! and so fast that I have to wait four more minutes to mark your answer as accepted, which I will.
I had previously tried adding the special character as a class on a throwaway div, and then testing for the class, but without any luck. This is a very elegant piece of code -- thank you!
@Pirripli, thanks. I'd make sure it actually works on the browsers you're worried about before marking it accepted. Matt Ball may be right.
The problem with this method is that &#xfffd; displays with a width and other valid characters have that same width such as &#x2588;
This method is based on the implicit assumption that a character that is missing in fonts is rendered the same as U+FFFD. This is not reliable, and browsers are known to use other renderings.
|
1

Rather than mucking around with JavaScript, what you should be doing instead is using css's unicode-range:

@font-face {
  font-family: 'MyWebFont'; /* Define the custom font name */
  src:  local("Segoe UI Symbol"),
        local("Symbola"),
        url('myfont.woff2') format('woff2'),
        url('myfont.woff') format('woff'); /* Define where the font can be downloaded */
  unicode-range: U+266F, U+266D; /* Define the available characters */
}

body {
  font-family: 'MyWebFont', Arial;
}
&#9839;
&#9837;
Normal text

In the local blocks, define fonts that people might have installed locally and contain the symbols you want (like Window's Segoe UI Symbol). Then define a web font (I suggest Symbola) containing the symbol you want to show.

The unicode-range directive tells supporting browsers (IE9 and up) not to download the font unless the specified symbols are present on the page (You can find their unicode number by searching Unicode-Tables.)

If they have the font already, they won't download it. If the symbol(s) aren't present on the page and your browser isn't older than dirt, the font won't be downloaded. It'll only be downloaded when it is needed.

(If you still want to support old IE, use fontsquirrel to generate your initial @font-face statement, then add the local and unicode-range parts yourself.

Comments

0

"Browser support" is not the problem here. You should be serving your files as UTF-8*, and use the appropriate characters rather than the HTML entities.

  • Unicode sharp symbol: ♯ (U+266F)
  • Unicode flat symbol: ♭ (U+266D)

You should also make sure to save your files in UTF-8 (and not, say, ASCII or ISO-8859-1).

See also: the must-be-mentioned Joel on Software: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!).


*I'm not a Rails guy, but I think it does this by default.

9 Comments

Hm... I believe I'm already doing this. I have a meta tag: <meta charset="utf-8">. Is there something special I should be doing other than copying and pasting the actual symbol into my markup? I've just done this, tested it on ie6, and found little square boxes. Do you know that ie6 supports those two symbols?
@Pirripli: see this answer. It may just be a font problem, but inserting the symbol into the markup is definitely the way to go. Are you sure you're saving the file as UTF-8?
Very interesting, definitely worth a read, but I wasn't able to turn this page's insights into sharp symbols... I first tried changing the class of the div in question to use Arial, then just plain sans-serif, without success. It's very possible I'm missing something here, but for the moment, I think I'm going to use Mike Samuel's suggestion. I'll let you know if I have success later, but at this point I think the types of users still on ie6 won't mind seeing # for ♯. ;)
@Pirripli: it's good that you understand that the JS approach is more of a hack. IMO, the best solution is to simply stop supporting IE6. That said - you did mention that Safari on Windows also had issues...
HA! I love ie6nomore.com and will consider using their code to prompt users in the right direction. I have noticed, however, even as I wrestle daily with ie6 (it's my least favorite part of any design project) I find that attempting to make things work for ie6 often makes me code better, relying on simpler HTML, fewer box model hacks (e.g. negative margins, etc...) and makes me generally think about pages more holistically rather than just a collection of DIVs and CSS. Don't get me wrong, I still hate it. But I think of it more as a bastard track coach.
|
-3

Add this to your HTML

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 

</head>

And check to see if IE and Safari render the page right.

1 Comment

Nope, no luck. I already had <meta charset="utf-8">, but I tried adding your attributes to no avail... thanks for the idea, though! I wish that were it... ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.