Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Active firing too early on WebKit browsers #26

Closed
tandara98 opened this issue Jan 30, 2011 · 26 comments
Closed

Active firing too early on WebKit browsers #26

tandara98 opened this issue Jan 30, 2011 · 26 comments

Comments

@tandara98
Copy link

On WebKit browsers (Chrome and Safari) under Windows when using custom module Webfont loader fires fontactive and active (the same holds for the wf-active class) before fonts become displayed and the page is laid out using loaded font metrics.

@seanami
Copy link
Contributor

seanami commented Jan 31, 2011

Do you have a sample page or test page that demonstrates this issue in action?

@tandara98
Copy link
Author

Ok, here is the definitive proof that fontactive is fired much earlier than it really should:

http://coocootz.hostzi.com/webfonts/debugger.html

I've inserted a listener component that checks every 50 milliseconds if the width of the menu element has changed. It is obvious that fontactive is fired before the font is loaded.

Moreover, by investigating page loading process using chrome developer tools, I figured out that fontactive is fired immediately after the request for the font file is sent, without waiting for the file to finish downloading.

@tandara98
Copy link
Author

Test shows that the width of the element applying a webfont is changed twice on webkit browsers! Webfont loader registers the first such change and fires active state. Apparently, that is the moment when the request for the font file is sent to the server. Font file is loaded and active only after the second width change.

@tandara98
Copy link
Author

I've experimented with font stacks, and this is what I've found out about the behavior of webkit browsers...

Both Chrome and Safari start by applying the first fallback font from the font stack.

Then, on the first width change, when apparently the request for the font file has been sent, they change the font differently. Safari's behavior is consistent and it changes the font to its own default font which is not in the font stack. This is apparently the font which would be used if there is no fallback font specified in the font stack (i.e. 'standard font' as specified in the browser preferences). On the other hand, if there is a generic family in the font stack (like "serif", "sans-serif", etc.), Chrome chooses to change the font to that one. If not, it behaves like Safari: it changes the font to the same default font as Safari.

Finally, on the second width change, they change the font to the one which just finished loading.

@seanami
Copy link
Contributor

seanami commented Feb 9, 2011

Interesting. Do you see the same problem if you load fonts from Google, Typekit, or one of the other modules, or is this only a problem with custom fonts?

(Also, your test case page appears to be down for "administrative review". Not sure what that means.)

@tandara98
Copy link
Author

I've tried loading fonts from Google, and there is no difference in behavior. I guess it is just the way webkit browsers handle the process of webfont loading: while the font file is being loaded, they switch to their own alternative.

(Sorry for the inconvenience with the web page accessibility. I think the problem arose because I turned off the automatic inclusion of the analytics code to my pages. It should not happen again.)

@jakearchibald
Copy link

I also get this issue, here's a test page http://fonttest.theteamdigital.com/render-pattern/webfontloader.php

The first paragraph should hide until the font has loaded. The third should show until the font has loaded.

In Chrome the 3rd paragraph hides while the font loads as the 'active' class is added too early. Compare to Firefox where it works as expected.

@jeffmarshall
Copy link

Same deal for me. I'll try to come up with a legit example later.

@seanami
Copy link
Contributor

seanami commented Jun 27, 2011

Alright, finally ran into this one myself through a different avenue and tracked it down. It looks like Webkit browsers will briefly change the width of a web font before it actually renders (and even when the font is invalid and won't render) for a single check cycle. Something to do with how they render the fonts.

The solution I found is to wait for the font to render at a consistent width for two checks. I have a pull request out for this now, but I think it should address this issue as well: #32

@mahemoff
Copy link

Seen this too. When used with canvas, it doesn't just create a delay/flash, it means the text never gets written.

Demo:
http://jsfiddle.net/mqnuP/

@seanami
Copy link
Contributor

seanami commented Aug 22, 2011

This pull request is now merged into the latest version of the library, so if you're using the latest version, you should no longer see this issue.

@seanami seanami closed this as completed Aug 22, 2011
@jeffmarshall
Copy link

Thanks <3

@benface
Copy link

benface commented Sep 18, 2011

I still have this issue, even with the latest version.

@seanami
Copy link
Contributor

seanami commented Sep 19, 2011

benoitr007: Do you have a simple test case that demonstrates the problem you're having? If not, can you make one?

@benface
Copy link

benface commented Sep 19, 2011

I just made one: http://www.benetonfilms.com/temp/webfont_loader_sample.html

But I also noticed the results are not always the same. In fact, it seems pretty random. Keep refreshing in Chrome, sometimes you will get this:

Document ready. DIV width = 193
Fonts loaded. DIV width = 171

The values should be the other way around, shouldn't they? For some reason, in FF, I get 193 and 202, respectively. Is it just me or something odd is going on?

Thanks!

@mahemoff
Copy link

You'll probably get more consistent results in Chrome if you use a new
incognito window (suppresses the existing cache). I got the same as you
twice just now, doing that.

On Mon, Sep 19, 2011 at 6:18 PM, benoitr007 <
[email protected]>wrote:

I just made one:
http://www.benetonfilms.com/temp/webfont_loader_sample.html

But I also noticed the results are not always the same. In fact, it seems
pretty random. Keep refreshing in Chrome, sometimes you will get this:

Document ready. DIV width = 193
Fonts loaded. DIV width = 171

The values should be the other way around, shouldn't they? For some reason,
in FF, I get 193 and 202, respectively. Is it just me or something odd is
going on?

Thanks!

Reply to this email directly or view it on GitHub:
#26 (comment)

@benface
Copy link

benface commented Sep 19, 2011

The problem is I am using the active event to calculate a few things based on the width of DIV's that contain text, so I really need them to return the correct value, which is not the case right now.

@mahemoff
Copy link

Me too.

My workaround for this is to start polling the metrics, with the first poll
immediately after the active event fires.

On Mon, Sep 19, 2011 at 6:24 PM, benoitr007 <
[email protected]>wrote:

The problem is I am using the active event to calculate a few things based
on the width of DIV's that contain text, so I really need them to return the
correct value, which is not the case right now.

Reply to this email directly or view it on GitHub:
#26 (comment)

@zachleat
Copy link

I think this issue should probably be reopened.

When the request is made to a font that does not yet exist in cache, the way WebKit handles FOUT hits (makes the text invisible while it's loading) and the text is still invisible when the active event is fired.

Try this test case in a fresh Chrome incognito mode: http://jsfiddle.net/9rJAj/2/

This is causing an issue with BigText where the text sizes incorrectly when the font is loaded using WebFont loader. See live at http://chrisnager.com/

@seanami
Copy link
Contributor

seanami commented Nov 28, 2011

There's currently a fix that should address this that we're working on in #38. The issue is due to an unfortunately web font loading behavior in Webkit-based browsers. I don't think we need to reopen this since we already have that pull open.

@zachleat
Copy link

Cool, thanks!

@zachleat
Copy link

Just FYI I checked the jsfiddle linked above and it's still broken. Should this be reopened?

@seanami
Copy link
Contributor

seanami commented Mar 15, 2012

The fix that went in was only for using Webfontloader with Google's service. Other services unfortunately still exhibit this behavior. We're going to have to totally rethink our font loading strategy in order to get around this webkit behavior, and so progress on this issue is currently on the backburner.

We already have another issue at #43 that documents this problem, so I don't think we should reopen this one as well.

@vfragosop
Copy link

One idea that may work is to create an Image() element and append the font url to its src. That way its possible to know when it failed loading and when its loaded (since browsers will not be able to render the image, but the font will be cached). The only problem is that I don't know if there's anyway to acquire @font-face declarations src attribute.

@waynehoover
Copy link

there is FOUT in chrome 24, check the fiddle for confirmation: http://jsfiddle.net/9rJAj/2/

@seanami
Copy link
Contributor

seanami commented Nov 20, 2012

Hi @waynehoover, I just checked your Fiddle, and I don't think it actually demonstrates what you want. A better way to test is to use the provided font event CSS classnames to hide the element until the fonts are done loading. I updated the fiddle to do that, and I don't see any FOUT: http://jsfiddle.net/9rJAj/9/

FOUT is not hidden by default when using webfontloader, but it does give you the tools to manage it yourself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants