When using #font-face in css, the browser loads my page's text before the font, which results in the font jumping from one style to another (from Arial to myfont). When using condensed fonts, for example, the problem is very pronounced visually.
I only want to display the one font that I have chosen with #font-face. What is the best way to do this?
It's called FOUT the best way to handle it in my experience is by using Google's font loader:
https://developers.google.com/webfonts/docs/webfont_loader
Essentially what you do is let the page load normally (during which the body is hidden or styled font blocks are hidden, your choice), once they are loaded a class is added to the body of the page, this triggers the display of the styled fonts.
The script adds these classes so you can style appropriately:
.wf-inactive - failed to load
.wf-loading - during load
.wf-active - loaded fine
The only downfall is that it requires Javascript..
This is a pretty well-known issue in some browsers (Firefox 3.5/3.6, IE 7-9). WebINK has a JavaScript file available which will allow you to work around the problem.
This is known as a Flash Of Unstyled Text and is due, as you mentioned, to the font files loading in tandem with the rest of the page, whose text will be styled with default or fallback fonts until the new font face is loaded and can be applied.
It appears that the best way to minimize the occurrence of this effect is to minimize the time the client spends loading your custom fonts. Two measures you can take to accomplish this are compressing your font files via gZip and specifying your font files for long-term caching by a viewer's browser for subsequent views via a far-future expires header.
If the FOUT is still pretty jarring for your users, you can specify a similarly-shaped font which is likely to be installed on most viewers' machines as a fallback to keep your page size relatively consistent as the custom font loads. For example, for your condensed font, most viewers already have Impact as an available font, or Arial Narrow, both of which adhere to a 'condensed' style.
And if all else fails, you can always style the entire text of your document with color: rgba(0,0,0,0) and use JavaScript to remove that rule at the end of a timer.
Related
FOUT in SPAs using FEFs. That's a lot of odd acronyms. :)
But it's still an issue.
I have a dynamic component which loads a bunch of components which are meant to look in a very specific way. Each would have its own css, and critically, its own specific fonts.
The fonts are the issue here.
What ways are there to avoid this FOUT in this case?
This is my current research on the topic:
Browsers have a mechanism to hide text it detects is styled with a custom font until the font has loaded.
This does not work in vue, because the text isn't loaded yet either for the browser to detect, so when JS puts the text, this browser mechanism isn't triggered.
Might be fixable via SSR, static DOM - browser can now detect. Still might not want - FOIT (Flash of invisible text) arguably worse (no content vs bad content).
This does nothing for dynamic components
CSS is consolidated unless async component.
You do get all CSS imports, but not all fonts until they are used on the page. I.e. it makes a network request for the css import, but not the fonts, until something on the page gets styled with this font. At least it's... quic. :D
WebFontLoader?
A js library by google/typekit, companion to google web fonts.
Possibly can be used to delay component loading until the font has loaded using its events?
Requires things outside the component to know about the font.
No obvious way to reach down and pull out CSS.
Depending on how many fonts you're loading and the size there are a few things you could do.
Call the fonts in the base HTML file (separate from your other CSS) so the browser is aware of them. Then create a hidden div in the parent component with CSS calling the font for the child. This will cause the browser to request the font before the child component is loaded.
Load all fonts separately in the HTML with rel='preload' or rel='prefetch'. I would do this at the bottom of the HTML so you don't block other content.
Load your fonts in the created lifecycle hook using the CSS Font Loading API. I'm not sure how this will work with Google Fonts vs self-hosting.
Create CSS transitions when loading content like a half-second fade to mask the FOUT. This is obviously not a solution but never underestimate the power of smoke and mirrors to influence the way your app feels.
Also, you should try to make use of the font-display (docs) CSS property. This won't solve the problem but it will make the results more predictable.
font-display is a new CSS property that allows developers to control how fonts are rendered depending on if they load quickly enough. There's been a few articles on it:
Controlling Font Performance with font-display - Google Developers
font-display for the Masses
None of them mention icon fonts. The specification does have an example that mentions icon fonts for the block value, but to me it doesn't make sense to use that:
'block'
Gives the font face a short block period (3s is recommended in most cases) and an infinite swap period.
If I understand the specification correctly, this means if the icons haven't loaded after the "short block period", the fallback font will be used, resulting in random letters appearing in their place.
If I use the optional value, the random letters will never appear but neither will the icons if they haven't loaded in the "extremely small block period".
There doesn't appear to be a value for giving an infinite block period without swap (so it would show invisible text until and unless the font loads). Is there a reason behind this and is there a workaround?
font-display: block;
As you commented, block still has a swap period; so it's still rendered until it's loaded.
Quoting Chris Coyier:
Wanna hear something quite unfortunate? We already mentioned font-display: block;. Wouldn't you think it, uh, well, blocked the rendering of text until the custom font loads? It doesn't. It's still got a swap period. It would be the perfect thing for something like icon fonts where the icon (probably) has no meaning unless the custom font loads. Alas, there is no font-display solution for that.
Considering alternatives:
I've also been there. If you have the chance, you might need to switch to SVG for icons. It has a few advantages over font-icons: SVG is better at pretty much everything than icon fonts.
Even Zach Leatherman, web fonts expert, has opinions about it on his very famous Comprehensive Guide to Font Loading Strategies.
This guide is not intended for use with font icons, which have different loading priorities and use cases. Also, SVG is probably a better long term choice.
How does the font-family property work in CSS? Why is more than one font used? Isn't only one font used at a time by the browser?
The font-family property holds several font names to provide a "fallback" system.
The browser tries each font family in the order that they are listed; if the browser does not support the first font, it tries the next font, and so on, down the list. That's why it's important that at least the last font in the list be a generic font family that is guaranteed to be universally available. There is no guarantee that the fonts you have loaded on your computer when you design the web page will be loaded on your visitor's computers—fonts are generally handled client-side, rather than server-side.
A common declaration might look like this:
font-family:Georgia,"Times New Roman",serif;
The "Georgia" font will be used if it is available. If not, the browser will attempt to fall back to "Times New Roman". If it can't find that font either, it will use a generic serif font.
For more technical information, I suggest reading the Fonts specification from the W3C.
To expand on what cody said:
When you look at a web page through a browser, your browser looks at the css and sees what fonts to use. Then it checks this list against the list of fonts that your computer has installed; the first one that matches is the one that gets used. Fonts are client-side, not server-side, and if you don't have the font that the css specifies, your browser falls back either to the next font specified or a default font.
I wanna create special font containing only icons. and for each letter will be diffirent icon.
I want to embed this font in css.
and use like this
if i need some icon:
<a class="icon">f</a>
and css
<link href='http://fonts.mysite.com/css?family=MyFontWithIcons' rel='stylesheet' type='text/css'>
which contains:
#media screen {
#font-face {
font-family: 'MyFontWithIcons';
font-style: normal;
font-weight: normal;
src: local('MyFontWithIcons'), url('http://fonts.mysite.com/font?MyFontWithIcons') format('truetype');
}
}
and to show icons with icon class:
.icon {font-family: 'MyFontWithIcons'; }
And letter "f" will be replaced with icon inside font which located on the place of f letter.
and css works with font and replacing f with icon inside font.
I think it's good idea or not? font file is less in size than lots of image icons.
and also with this technique I can use diffirent font colors = diffirent icon colors? sizes and so on.
So, it's good idea or not?
The problem with using a custom font for icons is that you've got no backup plan if:
Your user's browser is too old to support #font-face
The user agent isn't your traditional browser (eg. Screen readers for the blind, search engines, HTML-to-text converters, etc.)
The user copy-pastes the text containing the "icon" into something that discards rich formatting information or doesn't have the font in question.
The user agent will never support #font-face (Eg. Textual web browsers like Lynx, Links2, and ELinks for Unix/Linux)
The user is behind a corporate proxy that discards or mangles headers that your browser demands before displaying custom fonts. (more common than you think)
The user is running NoScript with the default font-blocking behaviour enabled to protect against 0-day exploits in the font engine.
Images provide the alt attribute for just this reason.
However, if you're going to use a font for icons, make sure you store your glyphs in a Unicode Private Use Area. That'll mitigate the problem a bit by ensuring there's probably no conflict (Companies can and do sometimes use PUA glyphs to store custom data) and, if they're coded smartly, screen readers could know to gracefully ignore PUA glyphs.
As for implementing a fallback, I'd suggest using Modernizr (specifically, Modernizr.fontface) to test for support.
It's a good idea but it doesn't work in all browsers (yet). Also, it only works with 2 color images (black and transparent), which makes it rather limited. For people with text browsers or text to speech software, it won't make any sense. It's not really 'semantic', because the <img>-tag was meant for images. Using fonts for that won't make any sense from a html-only perspective. It also clutters your css.
So that's a lot of bad things just for a little bit less bandwith; I wouldn't bother.
#font-face is not supported uniformly across browsers. Its a bit of a task to cater to all browsers esp. if including IE6
Accessibility: screen readers won't read icons, they would still see an 'f' and not an icon
You would need some fallback to degrade gracefully
All the other answers focus on the downsides.
I am, personally, a big fan of using icon fonts.
Here are some good reasons to use an icon font:
You can seamlessly use icons inline with text. If you include an icon inside of a block of text, it will inherit the font size and color of its parent, and will be aligned with the accompanying text's baseline.
you can change the color of icon dynamically using css, without having to create and upload additional image files and use js to manipulated the markup. this means that a) you are keeping style determinations where they belong, i.e. in your stylesheets and b) you can simply and easily make your icon colors contextual (e.g. all icons inside headers are white, or else they are black) and themable (e.g. all icons are white if body has class dark-theme, and all icons are pink if body has class tropical-theme)
the icon can easily be scaled without using additional bandwidth (as it would if you were increasing the size of the image file), without having to create and upload additional image files. corollary: you don't have to worry about different screen resolutions and don't need to make any allowances for retina, etc.
your font file will likely have a smaller file size than your image files would so, again, save on bandwidth.
if you use a font generator such as fontello, your collection of icons will automatically be catalogued for you and your designers to scrutinize, in a demo file. in addition, fontello has an API so your font generation can be managed automatically as part of your build process.
I'm trying to use the MusiSync font to embed a sharp and flat symbol in a line of text. In order to keep these symbols from being tiny I have to make their point size twice the size of the rest of the text. Unfortunately, this messes up the line height in Internet Explorer and I cannot find a way to control it. You can download the MusiSync font at:
http://www.icogitate.com/~ergosum/fonts/musicfonts.htm
My attempt to use this font in a web page can be found at:
http://www.williamsportwebdeveloper.com/MusiSync.htm
I opened up Photoshop and used the font you link to. There is a huge amount of white-space above each glyph in the font itself. The font is poorly designed.
If you set your style to this, you'll see the issue:
.style2 {
font-family: MusiSync;
font-size: 24pt;
border:1px solid #000000;
}
The problem appears in FireFiox 3 as well, its just manifesting itself a little differently.
You may be able to hack your way around this somehow, but it's going to be ugly. Unless you're using a lot of different font sizes, you may be better of using images.
Seeing that you are trying to use a very uncommon font, why not implement sIFR?
It will (possibly) solve some of your line height issues as well.
Read up here.
sIFR is an excellent choice for non-standard fonts.
You embed the font in a flash movie (don't worry most of the work is done for you) and add a bit of code to your page and the sIFR javascript will replace classes/id/tags etc with a flash movie containing the text/font that you're aiming for:
From http://www.mikeindustries.com/blog/sifr/
A normal (X)HTML page is loaded into the browser.
A javascript function is run which first checks that Flash is installed and then looks for whatever tags, ids, or classes you designate.
If Flash isn’t installed (or obviously if javascript is turned off), the (X)HTML page displays as normal and nothing further occurs. If Flash is installed, javascript traverses through the source of your page measuring each element you’ve designated as something you’d like “sIFRed”.
Once measured, the script creates Flash movies of the same dimensions and overlays them on top of the original elements, pumping the original browser text in as a Flash variable.
Actionscript inside of each Flash file then draws that text in your chosen typeface at a 6 point size and scales it up until it fits snugly inside the Flash movie.
An excellent cross browser platform indepent solution for non-standard fonts.