Workaround for the Safari FOUC bug
The Safari browser occasionally exhibits the dreaded Flash of Unstyled Content (FOUC) bug, in which the webpage is unstyled black-on-white text for a second or two before the styles kick in. This happens because Safari loads CSS and JavaScript in parallel - if the JavaScript accesses certain properties, it triggers a page render in Safari, even if the CSS hasn't fully loaded. Hence, the Flash of Unstyled Content. (Firefox does not suffer from this because it loads CSS and JavaScript in series rather than in parallel).
A workaround is to hide the body before the CSS files have loaded, and show the body afterwards:
body { display: none; }
body { display: block; }
Save these lines as safari-fouc-workaround-1.css and safari-fouc-workaround-2.css, respectively. Then place the following at the top of the <head> section, before your CSS declarations:
<link rel="stylesheet" type="text/css" media="screen" href="/safari-fouc-workaround-1.css" />
And after your CSS declarations, at the bottom of the <head> section, put:
<link rel="stylesheet" type="text/css" media="screen" href="/safari-fouc-workaround-2.css" />
(Even better, add these lines only if you detect that the browser is Safari.)
A workaround is to hide the body before the CSS files have loaded, and show the body afterwards:
body { display: none; }
body { display: block; }
Save these lines as safari-fouc-workaround-1.css and safari-fouc-workaround-2.css, respectively. Then place the following at the top of the <head> section, before your CSS declarations:
<link rel="stylesheet" type="text/css" media="screen" href="/safari-fouc-workaround-1.css" />
And after your CSS declarations, at the bottom of the <head> section, put:
<link rel="stylesheet" type="text/css" media="screen" href="/safari-fouc-workaround-2.css" />
(Even better, add these lines only if you detect that the browser is Safari.)
Update: The best way to implement this workaround is as follows:
Put the following in <head>:
Put the following in <head>:
<?phpand the following at the end of your main CSS file:
if (strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== FALSE) { ?>
<!-- First part of FOUC workaround -->
<style type="text/css">body { display: none; }</style>
<?php
}
/* Second part of FOUC workaround */
body { display: block; }
31 Comments:
Update: To save an HTTP request, the first statement can be done inline rather than in a separate file.
<style type="text/css">body { display: none; }</style>
By Jonathan, at 2/26/2007 11:49 a.m.
This didn't work for me at first but when I created two inline styles and put one in the header just after the "title" tag and the other just BEFORE the "/html" tag (closing html tag) then everything worked; I no longer get the 'flash'.
Yours a fairly elegant solution that I've spent much time looking for. Thanks.
By Anonymous, at 4/12/2007 9:48 a.m.
Hey Varen - super!
By Jonathan, at 4/12/2007 8:38 p.m.
Actually I am finding that, rather than putting "body { display: block; }" in a separate file, it is better to put it at the end of your main css file. This will ensure that, in Safari, the page will not display anything until the main css file finishes loading.
By Jonathan, at 5/02/2007 6:44 p.m.
Here's the PHP code for what goes at the top:
if (mb_strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== FALSE) { ?>
<style type="text/css">body { display: none; }</style>
<?php
}
By Jonathan, at 5/03/2007 11:49 p.m.
Hi Jonathan, I also found that using your snippet of php in the header to set display none for safari and just having body { display:block; } at the end of my master stylesheet was the only was to stop the fouc, great fix thanks man!
By Anonymous, at 12/08/2007 8:57 p.m.
Cool!
By Jonathan, at 12/08/2007 9:18 p.m.
Thanks Jonathan and Varen.
I tried Varen's adaptation and this worked beautifully!
By Anonymous, at 5/10/2008 10:07 a.m.
Glad you found it useful!
By Jonathan, at 5/10/2008 10:10 a.m.
that is like my nightmares ended...
that works nice in IE too!!!
thanks a lot!
By Anonymous, at 9/12/2008 6:43 a.m.
You're welcome, Jean!
By Jonathan, at 9/13/2008 7:22 p.m.
Hey Jonathan! First thank you for this workaround. I have tried your code but it doesn't work for me. I'm using Safari 4.0 and when i'm previewing my site in safari i see this white flash between pages. Can you some how show me an example of some code with your implemented workaround or just point me a link.I'll be very thankful.
By IronSpider Clothing and Design, at 6/27/2009 11:24 a.m.
Hi Antoniya—We’re using it for Ning sites, e.g., http://accp.ning.com/.
What’s the URL of your site?
By Jonathan, at 6/27/2009 12:32 p.m.
some how i cant find the snippet on your page (i'm not the best web master heheh). my site is http://ironspiderart.com/demo/index.html and if you can offer me some solution it will be great. thank you in advance
By IronSpider Clothing and Design, at 6/27/2009 1:13 p.m.
Actually it’s weird—I see the “body { display: none; }” and “body { display: block; }” when I do View Source on Chrome but not on Safari 3.2.1 for Windows. Do you see the two lines when you do View Source?
By Jonathan, at 6/27/2009 1:24 p.m.
no nothing here my page is clear . i was trying and maybe the site needs time to refresh but now is without any workaround. im using safari 4.0 with mac
By IronSpider Clothing and Design, at 6/27/2009 1:30 p.m.
k—make sure those two lines appear on Safari, and hopefully the Flash Of Unstyled Content will go away.
By Jonathan, at 6/27/2009 6:36 p.m.
i think i'm inserting them not on the right place and i'm not shure if i have to insert the php code also. is there a chance that you can insert this lines in my website code and send them back to me??
i'll really appreciate this . i hope i'm not causing you extra job :)
By IronSpider Clothing and Design, at 6/27/2009 7:30 p.m.
Will do.
By Jonathan, at 6/27/2009 9:37 p.m.
I used this work around perviously for version 2 + 3 of safari and it worked well. However the FOUC bug does not seem to like this fix when using Safari 4. The exact same pages now show the FOUC behavior in Safari 4.
Any other suggestions? Thanks
By Anonymous, at 7/17/2009 3:56 p.m.
Alas!
By Jonathan, at 7/17/2009 7:39 p.m.
It's exactly what i was looking for the last 8 hours but when i red to the bottom of the thread I realized that it doesn't work anymore for Safari 4. Let me know if see or come up with any other solution for it? I would greatly appreciate it.
By Anonymous, at 7/21/2009 10:07 a.m.
CAVEAT: Putting the second inline style tag between the closing body and html tags will lead to invalid (X)HTML. Nothing should go between these tags.
By Anonymous, at 8/06/2009 1:56 p.m.
Just fixed my problem with the white flash which is seen just before loading a page with a dark background.
In the opening html tag add the background color you want.
(Turn the symbols >< around, I couldn't post these lines otherwise because of the html tags)
>html style="background-color:#000000;"<
so this works for me in a standard opening html tag:
>html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" style="background-color:#000000;"<
By Peter, at 10/15/2009 3:18 a.m.
Nice one, Peter!
By Jonathan, at 10/15/2009 8:00 p.m.
This comment has been removed by the author.
By Madeck, at 3/27/2010 4:35 p.m.
The FOUC also appears on Chrome, so having the php condition is probably not the best solution.
Anyway, as some people pointed out, it seems the trick is not working anymore...
[EDIT]
However, it seems that having body, html instead of only body does the trick!
By Madeck, at 3/27/2010 4:39 p.m.
Ah, interesting.
By Jonathan, at 3/27/2010 6:02 p.m.
Cheers... this saved me some time!
By james, at 4/20/2010 12:42 p.m.
Actually I am finding that, rather than putting "body { display: block; }" in a separate file, it is better to put it at the end of your main css file.
Desert Safari
By Unknown, at 12/25/2012 2:17 a.m.
1. I would not do this hack in 2014. If you are doing the hack, I would recommend removing it.
2. Put js scripts at the bottom of your page, not at the top. The running of the js scripts will block the rest of the page from rendering.
By Jonathan, at 8/06/2014 7:48 p.m.
Post a Comment
<< Home