Coder Social home page Coder Social logo

Comments (12)

DouglasHeriot avatar DouglasHeriot commented on July 18, 2024

Hmm… I was just reading those blog posts and about to implement exactly the same thing. But with your example page I see the same bug you’re seeing. (also on 10.10.5 with Safari 8.0.8).

from fontfaceobserver.

bramstein avatar bramstein commented on July 18, 2024

Thanks for writing this very detailed post. I've experienced similar issues on Safari 8 (though not on Safari 7). Having steps to reproduce this issue is great! I'll try to find some time to look into this early next week. Last time I looked at it, I thought Safari was doing some pre-rendering using a cached version of the site, but I could be wrong about that.

from fontfaceobserver.

dwighthouse avatar dwighthouse commented on July 18, 2024

I continue to research. It turns out that it's not just fonts, but all of page rendering. If I replace my new style to change the background color, rather than the font, that background color also does not appear upon reload, even though the class is in play. Something to do with the promises or the timing of the application of that style in Safari is to blame somehow. I am now working on a minimal code example to demonstrate the issue.

from fontfaceobserver.

dwighthouse avatar dwighthouse commented on July 18, 2024

I've done some refactoring and found some very interesting things. First, here's a minimal HTML page that demonstrates the issue:
http://exp.dwighthouse.com/FontFailureSafari/MinimalSvgSample1/index.html

What I found was that the issue is somehow related to the fontfaceobserver and the usage of svg remote masks on the page. Check the source code for more details, but...

  • Local SVG elements using the use tag are fine
  • Remote SVG elements using the use tag are fine
  • Local SVG masks are fine
  • Remote SVG masks cause the error behavior (just one anywhere on the page causes issues)

I also found that if I refused to hide the remote SVG symbol/defs set using position absolute or fixed, the issue would also resolve, but I think it's a red herring that's just causing the whole page to rerender, which we know fixes the problem anyway (resizing the window also causes the issue to go away).

I personally have not used grunt or google closure compiler before (I'm a gulp+browserify guy), and my attempts to compile a non-compressed build of fontfaceobserver have failed so far. @bramstein, can you provide the compiled source of your library without compressing it? This will allow me to dive into what your library is doing relative to this problem.

from fontfaceobserver.

bramstein avatar bramstein commented on July 18, 2024

These two files are what pass for a non-compressed version in Closure compiler:

promise.debug.txt

fontfaceobserver.debug.txt

The first one is a polyfill for the Promises spec and the other is FontFaceObserver.

from fontfaceobserver.

dwighthouse avatar dwighthouse commented on July 18, 2024

More research.

I thought perhaps the issue was related to some kind of race condition in which Safari's rendering system was sensitive to switching styles at the moment a font is loaded and parsed. However, adding a setTimeout before adding the changing class had no effect, even after a whole second.

I thought perhaps it was related where the class is applied (perhaps applying a class to the html or body tag is special). However, applying the style to a containing div resulted in the same effect.

Perhaps it was related to how the font is being set in terms of the cascade. So I added a span element to contain the text of the div that set its font to the custom one. This resulted in slightly better likelihood of the correct behavior, but the wrong behavior still occurs sometimes.

I went an implemented my OWN font ready detector based on the resize event technique found here:
http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/ I got better results with far less code, but I still get bad behavior. Now, a typical reload results in the green background (correct), but invisible text (incorrect).

I tried setting the font directly in the style attribute of the tag that would use it, no luck.

Since I know the font is loaded, I tried removing the fallback font from the font family listing, both in the css class, and when directly styling the tag, didn't work.

Instead of changing the style or setting a global class, I tried injecting a stylesheet to the end of body after detecting the font. Same effect.

I think I've thoroughly proven that this is a render bug with Safari, something in its vector rendering and page re-render pipeline.

from fontfaceobserver.

dwighthouse avatar dwighthouse commented on July 18, 2024

Still no luck on the Safari bug. I am able to work around it by using position:relative on the reference svg and the setting its height to 0 so it doesn't effect layout.

I've been further developing my alternative font load detector, trying to make it small. As of now, it has the same features as fontfaceobserver, with the exception of promises, albeit with a different api. It uses callbacks instead of promises, so you'd have to hook up a chain of callbacks or something to observe the load-ready of multiple fonts. It sits at only 544 bytes gzipped. I plan to release it later.

from fontfaceobserver.

bramstein avatar bramstein commented on July 18, 2024

I came to the same conclusion; it's some weird bug in Safari. It's unfortunate the rendering pipeline is not reliable.

Looking forward to your alternative font loader. For the record, the 2.x release of Font Face Observer will most likely also drop promises.

from fontfaceobserver.

dwighthouse avatar dwighthouse commented on July 18, 2024

Using position: absolute, position: fixed, or display: none is an issue with webkit when referencing remote SVGs. Since SVG by default display: inline, this bug can be fixed by setting it to display: block and setting its height to 0.

My alternate method is already on github, but it still needs a bit of work. There's one known issue, and it doesn't correctly detect fonts on < IE9. I have a working version that does work on IE6 and I believe it will work on all browsers, though I haven't tested them yet. That code, along with the fix will be early next month (due to a trip and the inability to test IE browsers until I get back).

Here's what I have as of now:
https://github.com/dwighthouse/onfontready

from fontfaceobserver.

bramstein avatar bramstein commented on July 18, 2024

@dwighthouse Interesting approach. So basically that creates a tiny Document and attaches a resize listener to it? Is that more efficient than scroll events? Also, does it fire in inactive windows?

from fontfaceobserver.

dwighthouse avatar dwighthouse commented on July 18, 2024

@bramstein It's far less efficient than a scroll event, due to the memory costs of an iframe. However, this doesn't really matter, because it sets up and then shuts down immediately during the page load. It's in and out very quickly, so it doesn't matter very much.

The IE6 version has to use a table to associate the width of some text to the width of an iframe, IE6 ignores the bounding box of an absolutely positioned inline-block when positioning an absolutely positioned element inside it.

There was another approach I found that uses a timeout poll and a custom font that created a ridiculously large space character, so when the custom font loads, the space character is guaranteed to shrink. https://gist.github.com/jonathantneal/8252231

I do not know if my technique works in an inactive window, but I don't see a reason why it wouldn't any more than a scroll event wouldn't. I'll have to test it.

from fontfaceobserver.

bramstein avatar bramstein commented on July 18, 2024

I think we concluded that this is a Safari bug and unrelated to Font Face Observer, so I'm closing this issue. Thanks for the research you've done @dwighthouse!

from fontfaceobserver.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.