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; }
Update: To save an HTTP request, the first statement can be done inline rather than in a separate file.
ReplyDelete<style type="text/css">body { display: none; }</style>
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'.
ReplyDeleteYours a fairly elegant solution that I've spent much time looking for. Thanks.
Hey Varen - super!
ReplyDeleteActually 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.
ReplyDeleteHere's the PHP code for what goes at the top:
ReplyDeleteif (mb_strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== FALSE) { ?>
<style type="text/css">body { display: none; }</style>
<?php
}
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!
ReplyDeleteCool!
ReplyDeleteThanks Jonathan and Varen.
ReplyDeleteI tried Varen's adaptation and this worked beautifully!
Glad you found it useful!
ReplyDeletethat is like my nightmares ended...
ReplyDeletethat works nice in IE too!!!
thanks a lot!
You're welcome, Jean!
ReplyDeleteHey 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.
ReplyDeleteHi Antoniya—We’re using it for Ning sites, e.g., http://accp.ning.com/.
ReplyDeleteWhat’s the URL of your site?
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
ReplyDeleteActually 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?
ReplyDeleteno 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
ReplyDeletek—make sure those two lines appear on Safari, and hopefully the Flash Of Unstyled Content will go away.
ReplyDeletei 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??
ReplyDeletei'll really appreciate this . i hope i'm not causing you extra job :)
Will do.
ReplyDeleteI 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.
ReplyDeleteAny other suggestions? Thanks
Alas!
ReplyDeleteIt'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.
ReplyDeleteCAVEAT: 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.
ReplyDeleteJust fixed my problem with the white flash which is seen just before loading a page with a dark background.
ReplyDeleteIn 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;"<
Nice one, Peter!
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThe FOUC also appears on Chrome, so having the php condition is probably not the best solution.
ReplyDeleteAnyway, 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!
Ah, interesting.
ReplyDeleteCheers... this saved me some time!
ReplyDeleteActually 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.
ReplyDeleteDesert Safari
1. I would not do this hack in 2014. If you are doing the hack, I would recommend removing it.
ReplyDelete2. 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.