I am using the Google Webfont Loader to get my webfonts loaded with a callback and it is working fine.
Although, when a couple of components: Google +1 button, Twitter Search Widget and the Add This button is loaded, they add a new stylesheet to the DOM and makes the browser render the site again. This is causing the font-face to disappear and then show for each new stylesheet added to the dom.
I could hide the font entirely until the components are loaded but they tend to be pretty slow so that would leave me with a pretty bad user experience. About 1 sec of a headline-less site.
Andy tips on how to force font-face to not redraw or how to block dynamically loaded CSS from within Google, Twitter and FBs embed scripts?
Update: Demo here http://kristoferforsell.com/dev/fontexample/
This is currently an inherent issue with browsers and the #font-face property. The blink occurs when the font is loaded and the page updates to reflect the font. If you wish to remove the "blink" entirely, the only sure fire way is to include the font as a data URI in the style sheet. Of course, using the standard "safe" fonts will also remove the blink.
Data URIs allow you to actually embed the code for the font in the stylesheet so there's no blink when the page refreshes to show the desired font. Using data URIs, will obviously increase the file size (kb) of any style sheet.
An online converter to get base64 code can be found here
Usage for #font-face would be like so.....
#font-face {
font-family: "My Font";
src: url("data:font/opentype;base64,[ the base64 code here ]");
}
Not sure if it would fix your issue but you could use css to set the visibility of the elements to hidden until the font is loaded. Google's API provides wf-loading and wf-active classes which are added to the body to address this issue.
I always set up a separate stylesheet just for the #font-face rule, and within that put in the following rules, where replace is the class of the element that's being replaced, for you that would just be the p tag.
.wf-loading .replace { visibility: hidden;}
Yours would be
.wf-loading p { visibility: hidden;}
Then as soon as the webfont is loaded, JS puts the wf-active class on the body, and your text shows up. Let me know how that goes and if you have any issues then just drop me a line. It might also be worth doing some searching for "flash of unstyled content" or "flash of unstyled text" as this is a well known and well documented bug.
I can suggest a simple and dirty trick I have used myself to solve issues like this. If you implement this, from the user's side the effect will be that the entire page will load at once (with the correct Web Fonts), but after a delay. Once loaded, nothing will flicker or change.
Wrap your entire page contents in a div and set its visibility to hidden. Then use js to turn on the visibility once the whole page (stylesheets and all) is loaded.
Here's the code:
<head>
<script>
function show()
{document.getElementById('wrapper').style.visibility='visible';}
</script>
</head>
<body onload="show()">
<div id="wrapper">
...your entire page contents...
</div>
</body>
The onload ensures that the visibility is switched on only after the entire body has loaded. Although I haven't used Web Fonts, I use this trick to fade in the entire contents of this website with no changing or updating afterwards. But yes, there will be a delay before the entire page comes into view.
EDIT: I added Google Web Fonts to the site I linked. Still works fine. No font-face flickering.
This is a shot in the dark, as I've not tested it:
Could you create another html page with only those social networking buttons, and then load that into an iframe? Then only set the src to the iframe once the document is fully loaded, so it doesn't hold anything up.
In html:
<iframe id="socialMedia"></iframe>
In script:
$(document).ready(function() {
$('#socialMedia').src = "http://mysite.com/mysocialmediastrip.html";
});
Where mysocialmediastrip.html contains all the social media buttons. Setting the src will cause that iframe to reload and pull in that content, but IIRC, the rest of the page will be left alone -- all of the button rendering will have been done in mysocialmediastrip.html, not in your main page.
I totally understand what you are saying about the delay process, waiting while window loads before you actually show your goods. Abhranil provided a good solution but you can take his solution further. You can use jQuery's ajax to load your specific page content that's using the special font type. Why? because ajax comes with a special function called beforeSend(). Within the beforeSend function(), you can load a very cool gift animation that will display on your screen, before your main content is ready to viewed.
Use that moment to show some creativity towards your audience, before the main event!
The best and most simple answer is adding font-display: block when specifying a font face
#font-face {
font-display: block; /* Fix flickering */
}
You should also preload the font in the html file
<head>
<link rel="preload" as="font" href="/path_to_your_font.ttf">
<-- repeat for all typeface -->
</head>
Related
Here is my issue.
I am analyzing my page with Google Page Speed Insights.
An it's telling me to remove my css link in the head (above floating line) because its blocking my page load.
Right now I have a simple link in the head of my document:
<link rel="stylesheet" media="all" href="http://mydomain.we/css/my.css" />
</head>
I have try to place the link line at the bottom of the document. just before the end of the page.
<link rel="stylesheet" media="all" href="http://mydomain.we/css/my.css" />
</body>
Ran Insight again.
There is 2 tabs for Insight result. By placing the css link at the en of the document I score 100% on the mobile tab. However I still get the same message on the computer part as if no mater where I place it is still getting loaded above the floating line. I don't understand because I can see the page being loaded without the css for a fraction of second.
So I'm wondering what would be the best way to load my css?
Should I place a style tag in the header?
Should I add a style tag on the elements? <-- I would rather not.
So whats the best way to load my css?
Thanks.
IMHO, Insight will always consider loading external CSS file as less efficient, because, from Google Developers - OptimizeCSSDelivery
Optimize CSS Delivery
This rule triggers when PageSpeed Insights detects that a page includes render blocking external stylesheets, which delay the time to first render.
This might be true for small CSS code, but for large ones this is not true, another disadvantage of doing this is if you decided to change something in your CSS, then you'll need to go to every single page and do the change instead of changing it one time.
Beside, external CSS files could be cached unlike inline code, also considering the webpage size will increase or each page because you included it inline in every page.
Should i add a style tag on the elements? <-- I would rather not
Never!, this will give you hard time in maintaining and generalizing your CSS, and will have the top priority so you'd bang your head against the wall wondering why changing the CSS in external file or in the head section is not taking effect.
It may be the media=all causing it because that is used to recognized all media, where as media=screen is for desktops. I would try first using media=screen and if that doesn't work try getting rid of the media tag all together.
Possible duplicate: "Eliminate render-blocking CSS in above-the-fold content"
You should be fine keeping your CSS as it is. I've never seen it suggested to link a CSS file anywhere besides the head. Google Page Insights standards doesn't mean it's the best and most optimal way, every website is different.
The fastest way would be to use <style>...</style> or even inline CSS. But that does not mean it's the best practice. If it's just a few lines of CSS, you could opt for the <style> method, but I wouldn't go out of your way if it's not appropriate just to get a perfect Google Page Insights score.
The solution for this would be first identify and separate the CSS that is used for initial page display and move it to separate file.
Load this initial css file in the head section and move the remaining css to the bottom of the page.
I want to prevent an specific background-image being displayed on a page, possibly using jquery. However, the page and DOM is loaded before the JS is activated.
What I want to do is the following:
.pagelayout-login #page{
background: none;
}
I have tried the same in JQuery using:
$(document).ready(function(){
$(".pagelayout-login #page").css("background","none");
});
However, both modify the stylesheet after the image has been loaded and displayed.
If I add "run_at : "document_start" inside my content scripts, the CSS get's overridden by the page's CSS.
Is there a way to prevent the background from being displayed before it starts loading?
you can add the CSS at the beginning :
chrome.tabs.insertCSS(tab.id, {code:'my css code', allFrames:false, runAt:"document_start"});
or add a script at the end like this :
chrome.tabs.executeScript(tab.id, {code:'my script code', allFrames:false, runAt:"document_end"});
with the CSS, you need to be the first, because it's a "Cascading Style".
with the script, it must be the last change.
You can try to add !important to your CSS.
I'd think this would be a lot easier the moment you remove the $(document).ready, everything inside that function runs after the page has completed loading.
Since this is in a Chrome extension, don't be afraid to use !important to ensure that your CSS overrides the page's CSS even if you "run_at : "document_start":
.pagelayout-login #page{
background: none !important;
}
This may or may not prevent the image from loading since it's still being referenced by the page's CSS, but it will at least prevent it from displaying right away. You will need to conduct your own tests to determine if Chrome will still attempt to request the image during page load in spite of this.
I have done a bit of a web development faux pas by not starting with a functioning page and then building js functionality on top. The site I am redeveloping is an old site which has lots of pretty jquery animations.
I have gone to great trouble to ensure all page loads can be handled with or without ajax but I have just realised this is entirely pointless since the initial page load produces several elements which load with properties of display:none; or opacity:0; and are animated to be visible on doc ready
I would very much like to rectify this but there are several reasons I did it in the first place:
1: to hide a flash of unstyled menu before a jquery plugin kicks in. (I will replace this with a non js menu and animate into the jquery menu to solve this)
2: The other reason is that I like the initial animation on page load and would ideally like to keep it. But this presents a problem since I would like to have the bulk of the page invisible for js users and visible for non js users on load but how can I ensure that my elements css properties are changed BEFORE the page is rendered - I have tried doing this with jquery but by the time the jquery library has loaded (without caching) my page has already rendered so the content is flashed up before being hidden and animated back in?
This block will be visible only for users with JS turned off.
<noscript>html code here</noscript>
You can add some styles like this:
<noscript>
<style>
#content{
background: red;
}
</style>
</noscript>
You can add the following in your <head>:
<script>document.documentElement.className+='js'</script>
Then you can style javascript-enabled browsers differently using the js class on the html element, f.ex:
html .animate{opacity:1} /* all browsers */
html.js .animate{opacity:0} /* js-enabled browsers */
The class is added already in the head, so there is no flicker in the rest of the DOM.
You can also use the noscript tag, but personally I think this is cleaner because you can administrate the styles in a single stylesheet.
I have written a Firefox extension which alters the look and feel of Facebook. For this I used JS code to inject CSS styles to override FB defined values. But for some url patterns I don't want to force my styles. The issue here is the FB doesn't seem to load the full page but parts of page (but somehow the url in address changes).
This means when the new page loads my old styles will still remain applied and I want to restore them to their original values. How should I do that?
You should inject all your custom CSS styles into one <style> element, and then remove this <style> element (using JavaScript) when a new page is loaded on which you don't want your custom CSS.
Here's an example using jQuery: http://jsfiddle.net/thirtydot/BAPZF/
I'm learning Javascript and CSS and have run into an issue where my CSS styles aren't being applied to markup that I'm dynamically generated from XML and writing to document after the page has loaded. I can only assume that the styles aren't being applied because I'm modifying the document after it's already been loaded. Is this correct? If this isn't the case, do you have any ideas as to why the styles aren't being applied?
This javascript code...
$(function()
{
//Dynamically generate markup
strMarkup = GenerateMarkupFromXML();
//Display the dynamically generated markup
document.write(strMarkup);
});
dynamically generates this simple markup...
<div id="accordion"><h3>Title1</h3><h3>Title2</h3></div>
but these styles don't ever seem to be applied and the <h3> tags just get displayed with the default browser style...
h3
{
background-color:#ccc;
color:#003300;
font-size:1.1em;
}
I should also note that when I paste the dynamically generated markup directly into the body, the styles are applied correctly.
Thanks in advance for all your help!
Yes... the styles will be applied to any dynamically added markup.
The document.write() portion of your code may be causing problems here. In general, you should only use document.write() inline as the document is loaded and parsed. If you call it on DomReady as you seem to be doing it will overwrite your entire page, which I guess is what's causing the problem. I haven't tested though.
I'm not that familiar with jQuery, but instead of the document.write() line try doing something along the lines of (untested):
$('body').append('<div id="accordion"><h3>Title1/h3><h3>Title2</h3></div>');
Yes, css applied automatically. Your example don't work because document.write is evil )
It rewrites whole document with your custom styles, I suggest. If you want to use document.write call it in appropriate section of document, not in head. Example:
<head>
<style>
h3
{
background-color:#ccc;
color:#003300;
font-size:1.1em;
}
</style>
</head>
<body>
<script>
document.write('<div id="accordion"><h3>Title1</h3><h3>Title2</h3></div>');
</script>
</body>
Yes, CSS styles are applied to markup that is added after the page loads.
It could be that you aren't actually generating the same code that you think you are. Try selecting the generated code and doing "View Selection Source" in Firefox. This shows you the generated source (i.e. not just the static content that was served when the page was loaded).
Edit
I think there is a problem with using document.write() in the document ready function.. seems to be causing some kind of infinite loop (for me in Firefox, the browser keeps spinning the loading icon on the tab, even though the file is on my local machine). The $('body').append(strMarkup); solution posted by Andy works, though, as does $('body').html(strMarkup);;