Safari’s problem with @font-face

@font-face is definitely a huge string to the CSS author’s bow, in fact, it’s like a freekin’ flamin’ arrow, but watch out, Safari isn’t very nice to slow connections.

I recently peaked my total broadband usage and as a slap me down, my ISP, Plusnet, put me on about a 6Kb connection. Which sucks. Web pages are slow, email is slow: it’s slow.

Anyway, I’m doing a talk at Standards.next this weekend on HTML 5 JavaScript APIs (slides will be available here too if you can’t make it), and upon visiting the site in Safari – I got to see pretty much a blank page.

This was the sequence of events I saw in Safari as the browser downloaded the @font-face fonts:

Safari showing @font-face progressively loading, but the text is completely invisible until the font is downloaded

I’ve run the same test against Opera 10b and Firefox 3.5b and both render the text out, and only once the font has been downloaded, do they then re-render the text, here’s Opera (I also captured Firefox, but the heading is clearer in Opera for this example):

Opera rendering @font-face after showing the default font

I’m not sure if that first screen is the FOUC bug – I didn’t think it was…

The real issue for me, is the simple fact the text is missing. It’s not that unique that I’m on a slow connection. It’s slow when I’m using my 3G dongle. It’s slow when my laptop is tethered to my iPhone. The more we use mobile telephony to do wireless connectivity, the more we’re going to see slow download speeds (certainly for the next few years). We need to keep in mind those slow connections are out there as real users, and not just some family farm in the middle of The States somewhere.

Oh, and Webkit should fix that bug!

20 Responses to “Safari’s problem with @font-face”

  1. I wonder if this is actually an issue w/the way Safari does font rendering and not Webkit. What type of font rendering do you have Safari set to? I know Safari for Windows has a couple of options, one is to use Windows Standard (which I believe Safari doesn’t try to smoothly render the text.)

    Since Safari has a special font rendering engine, it just wouldn’t surprise me it’s related to that. Just speculation on my part…

  2. I agree, it’s a problem, but it’s also somewhat philosophical. Some people would rather not show the un-styled text while the font loads and some would. Also, along the lines of rhetorical niceties, it would rock if we could just embed a select character set (ie. if H3s only use caps of a certain font). Anyway, your best bet is to hide big portions of content until the window loaded event-

  3. This is WebKit behavior, it’s rendering the page by using the font metrics of a default font but without actually displaying any text until the downloadable font is loaded. This avoids the “flash” of text displayed in the fallback font when loaded under higher-speed connections. Firefox and Opera are displaying with the fallback font, the thought being that it’s important to display *something* and not just blank pages.

  4. It’s not a bug, it’s a feature!
    If you use a special font, those fallback fonts might break the layout and annoy users who already started reading and suddenly see an unexpected text reflow.

  5. @Ralf – I pray you’re kidding, right? Blank, unreadable content is never a feature.

    @John – I’d argue as a user on a slow connection, that the flash of text is required. At least with Firefox and Opera I could decide whether I wanted to continue on reading the page rather than questioning whether something had broken in my browser (I initially thought there some kind of memory corruption – as the old days of PCs fonts wouldn’t render when there wasn’t enough memory – obviously not the case!).

  6. You make some great points, as always, Remy but users are users be they on the family farm or in Brighton. Increased support for @font-face will encourage designers to send more bits coming over the wire for more sites, placing more users in a situation similar to yours.

  7. Actually, during the development of this design, I found that Webkit actually has the least (serious) @font-face bugs of all three supporting renderers [1], of which Opera sadly has the most serious bugs which are the hardest to work around without impacting others. I’ve heard back from them though, and they are working on them :)

    Check out the @font-face part of the (heavily commented) css file for more comments:
    http://standards-next.org/wp-content/themes/default/style.css
    ..once I have time, I’ll be publishing them on my own journal.

    I’m not quite sure what the ideal situation would be…maybe you’d want the browser to render the fallback font in the space the downloaded font will take up before changing over? (Minimizing re-flow issues) Of course, this might be paradoxical – I don’t know where the “space this font takes up”-info is stored in the font files.

    [1] Not counting IE’s EOT support.

  8. Also, webkit doesn’t get the reflow[1] right on multi-col; see the “Opera” link in Bruce’s box. Gecko is far stronger in that department.

    [1] It’s my guess it’s the reflow causing problems.

  9. >>>@Ralf – I pray you’re kidding, right? Blank, unreadable content is never a feature.

    If the the webdesigners wants a special webfont, why should there be Verdana flashing up for a couple of seconds?
    An image will also be missing as long as it is loading. No one expects to see a generic placeholder sunset picture until the real image is downloaded …

    Personally, I think it also really depends on the font (it’s design and download size).
    That’s why I recommended to Mozilla to give the web designers the choice (through CSS) whether or not a fallback font will be shown during download.

  10. One thing that was suggested at @media 2009 this last week was perhaps progressive loading of the font, similarly to how gifs can be progressively loaded. This way the key character set can come down with the appropriate kerning first, then the rest of the characters.

    I doubt if this solution exists or whether it’s even feasible. It could even have some prioritisation built in to how it’s served up – i.e. Japanese web sites need Japanese characters first.

    In terms of a solution that’s doable for today, I’m not totally sure, but my feelings are that blank content is the worth state to start with. I’d rather see reflow or a “flash of unfonted content” than not be able to get the content – but everyone who I’ve spoken to about this agrees, albeit begrudgingly over the “flashing” part!

  11. I should also add that the Standards.next design loads in 1.1 mb of fonts (The full Fontin Sans family, plus Regular and Bold versions of the gigantic Gentium font) as we’re just showing off the @font-face capabilities. In a production environment you might end up including just Fontin Sans Regular & Bold which add up to a much more reasonable 50 kb.

    Also, some kinks in @font-face support for “font-weight/style/variant” need to be worked out (in all browsers really). If they were, you could add in the regular font (used for body text) first and have that load earlier.

  12. @Ralf Herrmann

    The flash sucks but it should *not* be under designer control, a user on a slow connection like the one noted here should always have the option to see something. A more interesting approach would be to use the Safari approach for a few seconds, then use the fallback font if the downloaded one doesn’t download.

    @Remy
    Progressive rendering techniques have been proposed in the past but I don’t think this is going to work well in general. The flash is caused by the time it takes to figure out which fonts need to be downloaded and then initiating the download. The latency is the problem, not the size of the font unless the connection is slow.

  13. @Ralf – the flash does suck for designers, but the web is not about design, it’s about content. If I’m on a slow connect, say like 3G – which is increasingly likely giving the move towards our mobile web – and I can’t get the content it’s a show stopper.

    Images should have alt text which means that if the images take a long time to come down, you’ve got something else to go by – which rings true for text.

    Perhaps an alternative, default font-face – which is what’s happening by default in Opera & Firefox, which from a content point of view, is spot on.

  14. If only Safari would render text with a default font when you stop loading, if the fonts have not been downloaded yet – problem solved.

  15. I’ve also noticed using Firefox when I reload the page the titles using @font-face show the secondary choice font first then change into the desired @font-face font. It’s only for a half second or so but still not what I want happening.

    Anyone know of a solution?

  16. The page is no longer up, but from screenshots and personal experience, I bet the total page size was massive.

    I agree that providing a fallback would be nice. But in the meantime, this is not much different from posting 600k of images and being upset that the page loads without images at first.

    Wanting browser makers to force a flicker of unstyled content on everyone doesn’t strike me as the best solution. If you are concerned about mobile users, keep page sizes small. If you don’t want to keep page sizes small, write some code that waits for the fonts to download before swapping out the page.

    Fittingly, the page that’s talking about the future of the web has been redesigned to rely less on flashy features and more on … rendering well on mobile devices with slow connections. That’s future thinking I can get behind :)

  17. [...] June, Remy Sharp documented the how a browser progressively renders a page using @font-face. Things work differently between browsers [...]

  18. @Jon Bell – I don’t agree:

    But in the meantime, this is not much different from posting 600k of images and being upset that the page loads without images at first

    Simple because images have alt text – which we can see if the image is waiting to load. Where there’s no alt text, then the point is that the image has not affect on the content, like if I was talking about the science behind hair loss and having a side picture of a bald chap. It doesn’t add content, so I might justify not having an alt text. The point being is that without the picture I can still access the content.

    In this instance, without the font – I can’t access the content – at all.

    A great example of that is Henri Sivonen’s about page for the HTML5 validator: http://about.validator.nu – my connection is frequently throttled to 5kbps (because Plusnet suck) and the entire page sits there blank in Safari for a good minute or so because it’s downloading a bunch of fonts.

    It’s just text – I should be able to access it!

  19. We both agree it’s just text, and that you should be able to access it on any connection. I think we only differ in two ways:

    * If mobile browsers are important (they are), and are slower (they are) then I argue that “cutting edge mobile sites” shouldn’t use embedded fonts at all.

    * If a browser is going to use embedded fonts, having the entire page jump and re-orient itself when the secondary fonts are loaded is preferable in some cases, but I don’t think it’s a good default. The browser should default the way it currently does, and if a person wants to show ugly, out of place, layout altering alt text first and swap it out, that’s great. Write it that way yourself.

    But back to my original point — the best default is no embedded font at all if you have a sizable mobile audience.

  20. Firstoff: I’ve put an archived version of the page up, minus the old SVG Opera work-arounds. http://james.gameover.com/zen/examples/standards-next/

    @ Jon Bell
    The page (html+css) itself is actually 56 kb in total, but the download-able fonts total 1.2 mb (including EOT versions for IE). This on purpose. Because as you note, having such a large download impacts visitors enormously.
    Visitors using Safari (or Chrome) more than others, given their preference for waiting to display any text.

Leave a Reply
Not required

CODE: Please escape code and wrap in <pre><code>, doing so will automatically syntax highlight