Defining small-caps font-variant with #font-face - css

How do I add a small-caps font as a variant?
I’m using Jos Buivenga’s Fontin, which has its small-caps variant as a seperate font rather than as an OpenType-style feature. This CSS snippet properly defines the regular, bold, and italic fonts in the family, but not the small-caps one. How can I make this work?
/* A font by Jos Buivenga (exljbris) -> www.exljbris.com */
#font-face {
font-family: "Fontin";
src: url(../Fonts/Fontin-Regular.ttf) format("truetype");
}
#font-face {
font-family: "Fontin";
font-style: italic;
src: url(../Fonts/Fontin-Italic.ttf) format("truetype");
}
#font-face {
font-family: "Fontin";
font-weight: bold;
src: url(../Fonts/Fontin-Bold.ttf) format("truetype");
}
#font-face {
font-family: "Fontin";
font-variant: small-caps;
src: url(../Fonts/Fontin-SmallCaps.ttf) format("truetype");
}
Related: How to add multiple font files for the same font? and Properly defining font-family in #font-face CSS rules.

Unfortunately, it seems that the effective way is to fake the small-caps typeface as a font family, declaring it with e.g.
#font-face {
font-family: "Fontin Small Caps";
src: url(Fontin-SmallCaps.ttf) format("truetype");
}
(note the lack of font-style setting, defaulting it to normal) and using a rule like
p { font-family: Fontin Small Caps; }
without setting font-style.
Testing with the logical way, as described in the question, and using the .ttf font from http://www.exljbris.com/fontin.html I noticed that Firefox, Chrome, Opera all apply “fake small-caps” (i.e., uppercase letters in reduced size), when I set font-family: Fontin; font-variant: small-caps;. This is sad, but not very surprising.
The odd thing is that Firefox and Opera, but not Chrome, use the small-caps typeface of Fontin when I only set font-family: Fontin. This does not happen if I remove the #font-face rule that has font-style: small-caps. So the browsers are really hostile to the logical way using small capitals.

Related

Why does generated bold fonts look bolder, thicker, on browsers?

I'm aware of browser differences here.
I'm aware of the "normal" font-weight attribute, even on bold fonts.
I'm aware there's different font generations around.
Regardless all this, each time we convert a bold font, it gets really thicker.
Has anyone experience this? What ways to you have to overcome this?
We normally end up relying on regular (pretending to be "bold") and light (if exists) to work as "regular", to "fix" the look and feel.
Note (update):
We are using fonts that do have a native bold. And that's the issue.
We are NOT adding any "extra bold".
It is called 'faux bold'. If text is styled as bold or italic and the typeface family does not include a bold or italic font, browsers will compensate by trying to create bold and italic styles themselves.
These computed shapes are ugly. With italic you get the slanted version of the roman type (while a true italic is a totally different shape concept) and the regular is 'upscaled' into bold. Almost if a border is applied. These computed shapes are a (type) designers nightmare.
More on faux bold: http://alistapart.com/article/say-no-to-faux-bold
You can avoid faux bold by supplying the appropriate fonts. Like this:
#font-face {
font-family: 'DroidSerif';
src: url('DroidSerif-Regular-webfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: 'DroidSerif';
src: url('DroidSerif-Italic-webfont.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
#font-face {
font-family: 'DroidSerif';
src: url('DroidSerif-Bold-webfont.ttf') format('truetype');
font-weight: bold;
font-style: normal;
}
#font-face {
font-family: 'DroidSerif';
src: url('DroidSerif-BoldItalic-webfont.ttf') format('truetype');
font-weight: bold;
font-style: italic;
}
body { font-family:"DroidSerif", Georgia, serif; }
h1 { font-weight:bold; }
em { font-style:italic; }
strong em {
font-weight:bold;
font-style:italic;
}
Read also the article (and how not to define style/weights):
http://www.456bereastreet.com/archive/201012/font-face_tip_define_font-weight_and_font-style_to_keep_your_css_simple/
UPDATE:
You might also experience font-smoothing issues. Which can be fixed with some css:
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

#font-face, font variants

This is my #font-face declaration to support different font variants, in this case the bold and bolder version of my font.
#font-face {
font-family: "santana";
src: url("data:font/ttf;base64,AAEAAAALAI....") format('truetype');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: "santana";
src: url("data:font/ttf;base64,AAEAAAALAI....") format('truetype');
font-weight: bold;
}
#font-face {
font-family: "santana";
src: url("data:font/ttf;base64,AAEAAAALAI....") format('truetype');
font-weight: bolder;
}
Right now I'm just working with Chrome and Firefox. In Chrome the normal and bold variants work, but not the bolder variant (keeps the 'bold' one). In Firefox only the bold variant works as expected, in any other case the bolder variant is used (even for normal weight).
Is this a known issue or is there a better way to do this declaration?
There are 2 separate issues here:
The use of font-weight keywords rather than numeric values.
Support for IE8 (and earlier versions), if needed.
Keywords
The problem with using font-weight keywords appears to be that lighter and bolder are not absolute values like normal and bold (always 400 and 700, respectively), but are relative to the established boldness of the parent element (100 lighter or darker). It may not be possible to treat lighter and bolder as if they're absolute values.
As #HTMLDeveloper and #Christoph suggested, using numeric values rather than keywords is the easy solution to this, and may by itself be an adequate solution (if support for IE8 isn't needed).
#font-face {
font-family: "santana";
src: url("data:font/ttf;base64,AAEAAAALAI....") format('truetype');
font-weight: 400;
font-style: normal;
}
#font-face {
font-family: "santana";
src: url("data:font/ttf;base64,AAEAAAALAI....") format('truetype');
font-weight: 700;
}
#font-face {
font-family: "santana";
src: url("data:font/ttf;base64,AAEAAAALAI....") format('truetype');
font-weight: 900; /* or whatever weight you need to use for "bolder" */
}
IE8 and earlier
Some browsers have display issues when multiple weights or styles are associated with the same font-family name.
Specific issues I'm aware of: (there may be others)
When more than 1 weight is linked to a font-family name, IE8 has display issues.
When more than 4 weights or styles are linked to a font-family name, IE6/7/8 has display issues.
The solution is to use a unique font-family name for each font variation:
#font-face {
font-family: "santana";
src: url("data:font/ttf;base64,AAEAAAALAI....") format('truetype');
}
#font-face {
font-family: "santana-bold";
src: url("data:font/ttf;base64,AAEAAAALAI....") format('truetype');
}
#font-face {
font-family: "santana-bolder";
src: url("data:font/ttf;base64,AAEAAAALAI....") format('truetype');
}
This approach is commonly used by font services like Typekit. If support for a wide variety of browsers is needed (or at least, IE8 in particular), this could be considered one of the prices you have to pay when embedding fonts.
In font-face single font the quotes for font family name is not needed. you should remove and run it will works fine. font-family: santana; font-weight: 900; do not need for single font, it needs only multiple fonts. instead of bolder use numerical value it should works fine.

Web Fonts and providing fallback fonts

When using web fonts using #font-face I was wondering what's the recommend method on using fallback fonts?
Like, for example if I was using a web font that was bold, such as:
#font-face {
font-family: 'OpenSansBold';
src: url('../fonts/OpenSans-Bold-webfont.eot');
src: url('../fonts/OpenSans-Bold-webfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/OpenSans-Bold-webfont.woff') format('woff'),
url('../fonts/OpenSans-Bold-webfont.ttf') format('truetype'),
url('../fonts/OpenSans-Bold-webfont.svg#OpenSansBold') format('svg');
font-weight: normal;
font-style: normal;
}
Now when you call this you obviously just do this:
font-family: OpenSansBold;
However I was wondering about providing fallback fonts such as if the download of the font fails for whatever reason.
Obviously that's easy enough to do with a normal style font (non bold/non-italic) as below..
font-family: OpenSansRegular, Arial;
However, what I'm wondering is what about when the font is bold or italic.
Is it advised to something like this and it won't affect the web font?
font-family: OpenSansBold, Arial;
font-weight: bold;
Just wondering because if you didn't specify the bold then if the web font failed, they would get Arial, but it wouldn't be bold.
You are presumably using font files and a CSS file as generated by FontSquirrel. The problem with their approach is that each specific font (such as Open Sans Regular and Open Sans Bold) is represented as a separate font-family, with font weight set to normal. This means that instead of markup like <p>foo <strong>bar</strong> and simple CSS like p { font-family: Open Sans, Arial } (letting browsers default strong to bold font weight and select the suitable font from the Open Sans family), you will be forced to set fonts explicitly. This means setting both font family and font weight, implicitly with the font-family property value.
You would need to tune the CSS to get a better approach. You would use the same font family but different weights in the #font-family rule, and in the font-family rule, you would only set the family:
#font-face {
font-family: 'open_sans';
src: url('opensans-bold-webfont.eot');
src: url('opensans-bold-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-bold-webfont.woff') format('woff'),
url('opensans-bold-webfont.ttf') format('truetype'),
url('opensans-bold-webfont.svg#OpenSans') format('svg');
font-weight: bold;
font-style: normal;
}
#font-face {
font-family: 'open_sans';
src: url('opensans-regular-webfont.eot');
src: url('opensans-regular-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-regular-webfont.woff') format('woff'),
url('opensans-regular-webfont.ttf') format('truetype'),
url('opensans-regular-webfont.svg#OpenSans') format('svg');
font-weight: normal;
font-style: normal;
}
* { font-family: open_sans, Arial; }
And then you would just use font-weight: bold (or HTML markup that has such an effect by default, like strong, b, th, h1 through h6) for those elements that should appear in Open Sans Bold.
Doing it the way you describe appears to work on most browsers, too, but I wouldn’t count on it. Once you have declared a font as normal weight in your #font-face, setting font-weight: bold on text in that font could cause a) a failure, since a the weights don’t match or b) the font taken as a starting point for algorithmic bolding, resulting in double bolding. And if I’m not mistaken, b) is what happens on Safari (Win 7).
You've correctly highlighted an issue with the 'new age' of web fonts, this blog post discusses it and presents a workaround http://elliotjaystocks.com/blog/font-weight-in-the-age-of-web-fonts/
Relevant snippet
Problem number two is significantly bigger than the first. Consider FF Enzo, which doesn’t have a 400 (or even 500) weight. In some circumstances, its Light (300) weight might perhaps be a little too thin for small body type, so let’s use the 600 weight instead. Ah, that looks okay.
But it’s not okay! Because if that font can’t be displayed and we fallback to something else, that fallback font will render at its 600 weight; in other words: bold.
A workaround?
There’s a way around this and it’s the method FontsLive use in the CSS they generate for their users: you declare each weight individually rather than the entire family. Their code looks a bit like this:
CSS code:
{ font-family: 'FamilyName Light', 'FallbackFamily', serif; font-weight: normal; }
{ font-family: 'FamilyName Medium', 'FallbackFamily', serif; font-weight: normal; }
{ font-family: 'FamilyName Bold', 'FallbackFamily', serif; font-weight: bold; }
{ font-family: 'FamilyName Black', 'FallbackFamily', serif; font-weight: bold; }
Update:
#font-face {
font-family: 'OpenSansBold';
src: url('../fonts/OpenSans-Bold-webfont.eot');
src: url('../fonts/OpenSans-Bold-webfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/OpenSans-Bold-webfont.woff') format('woff'),
url('../fonts/OpenSans-Bold-webfont.ttf') format('truetype'),
url('../fonts/OpenSans-Bold-webfont.svg#OpenSansBold') format('svg');
font-weight: bold;
font-style: normal;
}
And then something like (as you suggested):
{ font-family: OpenSansBold, 'Arial'; font-weight: bold; }
While the accepted answer works, if you want to provide a really accurate fallback font you will want to define a separate line height and letter spacing for each fallback as well. The main reason to do this is that Google recently introduced a score on Cumulative Layout Shift (CLS), indicating how much the page jumps around upon loading.
You can achieve this by putting a CSS class on the body before the font loading, that gets removed if font loading completes successfully. I do that by including this near the top of the page:
<script>!function(d){if (d.fonts.ready){d.body.className="loading";d.fonts.ready.then(function(){d.body.className=""})}}(document)</script>
You CSS would then look something like this:
h1,p {font-family: Open Sans, Arial}
h1.loading {font-family: Arial;line-height:16px}
p.loading {font-family: Arial;line-height:12px}
By adding and removing the "loading" class in the inspector you can then play with the CSS to get it to stop jumping around. With this you can reliably get the CLS to zero to please the Google gods. The only alternative alternative I've found is using a font loader library which will give a penalty on loading time.

How to use font-weight with font-face fonts?

I've got two font files like: FONT-light and FONT-bold. Both come from #font-face kit so each version has like 5 font files included (OGV, TTF, WOFF, EOT).
To go from light version to bold version I have to use font-family: FONT-light; and then font-family: FONT-bold;. I want to use font-weight: light; and font-weight: bold; instead because I need it to CSS3 transitions. How do I achieve that?
#font-face {
font-family: 'DroidSerif';
src: url('DroidSerif-Regular-webfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: 'DroidSerif';
src: url('DroidSerif-Italic-webfont.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
#font-face {
font-family: 'DroidSerif';
src: url('DroidSerif-Bold-webfont.ttf') format('truetype');
font-weight: bold;
font-style: normal;
}
#font-face {
font-family: 'DroidSerif';
src: url('DroidSerif-BoldItalic-webfont.ttf') format('truetype');
font-weight: bold;
font-style: italic;
}
From the tutorial: http://www.456bereastreet.com/archive/201012/font-face_tip_define_font-weight_and_font-style_to_keep_your_css_simple/
To use the font-weight and the font-style properties on embedded fonts (#font-face) isn't so simple. There are a few items that you need to care about.
1 - #font-face Syntax:
The syntax is very important to use the font over all browsers. Paul Irish, with many resources, wrote the 'Bulletproof Syntax', as is shown above, which was improved several times:
#font-face {
font-family: 'FONT-NAME';
src: url('FONT-NAME.eot?') format('eot'), url('FONT-NAME.woff') format('woff'), url('FONT-NAME.ttf') format('truetype');
}
This version (http://www.paulirish.com/2009/bulletproof-font-face-implementation-syntax/, look for 'The Fontspring #font-face syntax'), is the most recent and works from IE6, on iOS, Android. It's important to take a look on the link to learn well why it should be written in that way.
2 - Font properties like font-weight and font-style
If you want, is possible to apply the font-weight and font-style on the #font-face declaration to use variations of the same font, but you need to be specific and precise about these characteristics. There are some ways to do it.
2.1 - Using one font-family to each variation
Using the 'Bulletproof Syntax', supposing that you want to load the 'Normal', 'Bold' and 'Italic' variations, we have:
#font-face {
font-family: 'FONT-NAME-normal';
src: url('FONT-NAME-normal.eot?') format('eot'), url('FONT-NAME-normal.woff') format('woff'), url('FONT-NAME-normal.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: 'FONT-NAME-bold';
src: url('FONT-NAME-bold.eot?') format('eot'), url('FONT-NAME-bold.woff') format('woff'), url('FONT-NAME-bold.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: 'FONT-NAME-italic';
src: url('FONT-NAME-italic.eot?') format('eot'), url('FONT-NAME-italic.woff') format('woff'), url('FONT-NAME-italic.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
So, to use the variation that you want, you have to call the font-family that corresponds to it AND declare on the rule the font-weight: normal and font-style: normal. If you don't, the browser may apply the 'faux bold/italic' to the element that have this rules by default. The 'faux' styling works forcing the element to be shown with it, even if is already using an italic or bold font. The problem with is that the font always looks ugly because isn't the way that was made to look.
The same occurs when you define a 'Normal' font, for example, on a <p> element and, inside of it, you place a <strong> or <em>. The <strong> and <em> will force the bold/italic process over the font. To avoid that, you need to apply the correct font-family, destinated do the be bold/italic, to a rule for <strong> and <em>, with their respective properties (font-weight and font-style) set to normal:
strong {
font-family: 'FONT-NAME-bold';
font-weight: normal;
font-style: normal;
}
em {
font-family: 'FONT-NAME-italic';
font-weight: normal;
font-style: normal;
}
But there is a problem with it. If your fonts don't load the fallbacks choosen will lost their weights/styles. This leads us to the next way.
2.2 - Using the same font-family name, but different weights and styles
This way is more simple to handle through several weights and styles AND fallbacks correctly if your fonts don't load. Using the same example:
#font-face {
font-family: 'FONT-NAME';
src: url('FONT-NAME-normal.eot?') format('eot'), url('FONT-NAME-normal.woff') format('woff'), url('FONT-NAME-normal.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
#font-face {
font-family: 'FONT-NAME';
src: url('FONT-NAME-bold.eot?') format('eot'), url('FONT-NAME-bold.woff') format('woff'), url('FONT-NAME-bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
}
#font-face {
font-family: 'FONT-NAME';
src: url('FONT-NAME-italic.eot?') format('eot'), url('FONT-NAME-italic.woff') format('woff'), url('FONT-NAME-italic.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
In this method, the weights and styles in the #font-face declarations act as “markers”. When a browser encounters those weights and styles elsewhere in the CSS, it knows which #font-face declaration to access and which variation of the font to use.
Make sure if your weights and styles match. If so, when you use a <strong> or <em> inside a parent which is using the #font-face that you created, it will load the right declaration.
In the source of these methods of stylization embedded (http://coding.smashingmagazine.com/2013/02/14/setting-weights-and-styles-at-font-face-declaration/), have another method that combines the two that I've mentioned (the 2.1 and 2.2). But it brings a lot of problems, including the 'faux bold/italic', forcing you to declare to the <strong> the right font-family and, for the <em>, classes that styles over the variations of the font that differs in weight. I guess the two that I've choosed are good enough to do the job.
Sources:
http://www.paulirish.com/2009/bulletproof-font-face-implementation-syntax/
http://coding.smashingmagazine.com/2013/02/14/setting-weights-and-styles-at-font-face-declaration/
Edit 1:
There's no need to use a lot of font extensions. The .woff type attends almost every browser, except for IE, if you need to give support for IE8 (which accepts only .eot format). (http://caniuse.com/#feat=fontface)
Other tip that maybe is useful is to embed the font on the CSS using base64 encoding. This will help avoiding a lot of requests, but you need to remember that it'll overwight the CSS file. This can be handled organizing the CSS content and the fonts to give the first CSS rules quickly in one small file, delivering the others on another CSS file, on the close of <body> tag.
you can add number to font-weight property, for example to the light version.
font-weight: normal; // light version as it is.
font-weight: 700; // makes light version bolder.

Why do I have to declare specific bold/italic variants for web font?

I'm trying to use the Ubuntu font on a website. I am using the FontSquirrel #font-face generator. On computers where the Ubuntu font is installed everything works fine when I simply have css like font-family: Ubuntu. But on other computers it won't work unless I explicitly state which particular variety I want like font-family: UbuntuRegular or font-family: UbuntuBoldItalic. It is the same situation across all browsers.
It is silly to have to declare weight and style every time. Isn't there some way to just declare the general font family and have the bold and italic faces used automatically when needed?
Most #font-face generators set font-weight and font-style to normal and use separate declarations for each weight/style for backward compatibility. But you can rewrite the declarations to use the same family name for each variation, changing only font-weight and font-style within each where appropriate, e.g.:
#font-face { /* Regular */
font-family: 'Klavika';
src: url('klavika-regular-webfont.eot');
src: url('klavika-regular-webfont.eot?#iefix') format('embedded-opentype'),
url('klavika-regular-webfont.woff') format('woff'),
url('klavika-regular-webfont.ttf') format('truetype'),
font-weight: normal;
font-style: normal;
}
#font-face { /* Bold */
font-family: 'Klavika';
src: url('klavika-bold-webfont.eot');
src: url('klavika-bold-webfont.eot?#iefix') format('embedded-opentype'),
url('klavika-bold-webfont.woff') format('woff'),
url('klavika-bold-webfont.ttf') format('truetype'),
font-weight: bold;
font-style: normal;
}
So that H1 should inherit the bold weight without the need to specify the weight:
h1{ font-family: 'Klavika';}
456 Berea St has a good post detailing the implementation (and compatibility): http://www.456bereastreet.com/archive/201012/font-face_tip_define_font-weight_and_font-style_to_keep_your_css_simple/

Resources