So I was under the assumption that for all possible values of font-weight, all fonts support them. However, this is wrong according to the specifications found here where it says "The nine font weights can not be relied on. These weights are dependent on weight subsets of a font being available." and exemplified in this doodle where there seems to be only normal and bold support (anything <=500 looks like normal) for font monospace. How can we tell, then, how many font-weight levels a given font supports?
In fact, the "nine font weights" are purely a CSS thing, not actually something that formally exists in any font specification. Also, any font can currently only model one weight (the OpenType specification only just got updated with variable dimensioning, and that's going to take a while to a) be refined as "this is the right way to do it" specification and b) make it into browsers), so if you want all nine supported weights you need nine fonts, and for each of those you need to tell CSS which weight it maps to because the font's internal weight value in no way has to match CSS's choice on what font weight numbers are.
If you rely on system fonts by name, or you rely on "not even fonts" by using category keywords like monospace then you're out of luck: there are almost no fonts that run the full CSS font width range.
So: if you want true control and all weights: use a webfont that you know has all nine weights, bound using some sensible #font-face rules. It's going to take a bit of effort to verify they do on your part, but once you do you are guaranteed it'll work in every (modernish) browser, on every operating system.
if you are using a google font, documentation clearly states the font weight available, for example:
https://fonts.google.com/specimen/Roboto
as for built in font, i'm not sure if there is a way. more info on how the browser handles a font-weight that is not supported can be found here:
https://css-tricks.com/almanac/properties/f/font-weight/
hope that helps :)
in my web project I need to mix latin and cyrillic characters. Unfortunately the cyrillic characters are not part of the webfont, thus the fallback steps in.
As I use a bold webfont the latin characters are bold but the fallback would only be bold, if I set the whole paragraph as font-weight:bold or alike.
I remember discussions that this should be prevented as some browsers can't display them correctly, but during my tests I wasn't able to produce a really broken layout when bolding the webfonts.
What do you think? How can I solve this problem?
Thank you
Markus
Yes, most webfonts provide specific weights like 400 for Regular and 700 for bold. If these aren't provided and you bold/strong them, you are in essence using the font outside of its original intent.
Font weight values can be used, but I'd always stick with the ones provided with the webfont you're using.
Also, if a weight you declare is not available, it will not show on the page but simply default the "logically closest" (this from the CSS Tricks article below) weight.
See a little more basic description here: https://css-tricks.com/almanac/properties/f/font-weight/
Yes it's still recommended you don't do this.
By using font-weight:bold you're forcing the browser to try and create the bold version of this font itself, which can often look distorted / fuzzy. This is referred to as faux styling.
You should set different #font-face definitions with different font-weight values which make use of multiple font files.
I'm searching for a method to tell the browser to render each glyph rendered with a specific font, e.g. FreeMono, in a bigger font size than glyphs rendered with other fonts. The reason for that is, that I use characters like ᚠ in a website and these glyphs are rendered using FreeMono in Chrome (see inspect element → computed → rendered fonts) and they look always like they're to small to fit the surrounding text. Is there any way I can do that?
You cannot. CSS has no tools for such font-specific tuning, apart from the font-size-adjust property, which has very limited effect, limited browser support, and buggy support.
If you use a character such as “ᚠ” U+16A0 RUNIC LETTER FEHU FEOH FE F on a web page, then it will be up to each browser in each system which font (if any) is used to render it, at least if you do not explicitly suggest some font(s) that contain it. It may be FreeMono, but most computers in the world do not have it. Besides, in FreeMono, “ᚠ” is rather large—taller than uppercase Latin letters. So if it looks too small, the reason might be a mix of fonts.
To make, say, Runic letters match the style of other text, you should try and find a font that is suitable for both—so that you can use a single font, designer by a typographer to make things fit. You would then probably need to find a suitable free font and use it as a downloadable font (with #font-face). It might be FreeSerif or FreeSans; only in very peculiar circumstances would I consider FreeMono, a monospace font, suitable for rendering computer code in some cases and mostly unsuitable for everything else.
I'm working on a site where small caps are important: setting the text of the Bible. In the Old Testament the name of God is transliterated as Lord but in small caps—not LORD. However, the state of OpenType small caps support at the moment is… less than optimal. Safari (even up through Safari 8 on Yosemite, from which I am typing this) still doesn't support the -webkit-font-feature-settings: 'smcp' option, and a lot of the hits for this website will be coming from mobile.
Unfortunately, "graceful degradation" is problematic here: if you specify both font-variant: small-caps and font-feature-settings: 'smcp' in a browser that supports the latter (e.g. Chrome), the font-variant declaration overrides it, so the horribly ugly old-style version still comes into play. (Note: this is as it should be per the spec: the font-variant declaration has a higher priority than the font-feature-settings declaration). Given the current implementations of font-variant: small-caps, though—shrunken capitals rather than actual small capitals—the result is that using font-variant: small-caps realists in not-so-gracefully degrading everyone's reading experience.
In the past, I have exported the small caps as a distinct webfont and specified them directly; see this post for a simple example: the first line of each paragraph is specified that way.
While I can do the same thing here (and at least in theory could deliver a pretty small typeface, since I really only need three characters: o, r, and d), I'd prefer simply to enable sane fallbacks. As noted above, however, that's not possible. I am open to but would very much prefer to avoid server-side solutions (browser detection, etc.) as a point of complexity that is better to minimize, especially given how rapidly browsers change. How else might one solve this problem, and especially are there existing solutions for it?
Edit: clarifying based on comments—in the future, font-variant: small-caps will handle this nicely, as per the spec it should display a small-capitals-variant of the typeface if the typeface supplies it. However, at present, no browser supports this (at least, none that I can find!). This means that instead, they all render fake small capitals simply by scaling down actual capitals. The result is typographically unpleasant, and unacceptable on this project.
Last updated 2016/02/28.
I spent a considerable amount of time researching this and wrestling with it.
After digging around as best I could, the top solutions for now are:
#supports
Take advantage of the #supports rule in browsers. This is what I initially
opted to do on this project.[1] You use the rule this way:
.some-class {
font-variant: small-caps;
}
#supports(font-feature-settings: 'smcp') {
.some-class {
font-variant: normal;
font-feature-settings: 'smcp';
}
}
I've simplified by leaving out the prefixed versions; you'll need to add the
-webkit- and -moz- prefixes to get this actually working. Update,
2012/02/28: you no longer need the -moz- prefix, and this will work in
Safari in the next release (iOS 9.3 and OS X Safari 9.1).
This has the advantage that support for real small caps and
support for the #supports rule are very similar:
#supports: Can I Use Feature Queries?: Chrome 31+, Firefox
29+, Opera 23+, Android 4.4+, Safari 9+, Edge 12+, Chrome for Android
Update, 2016/02/28: as the chart linked above will make clear, all
evergreen browsers now have #supports support.
font-feature-settings: Using Small Caps & Text Figures on the Web:
Chrome, Firefox, IE10+
This isn't perfect: since IE10/11 don't implement #supports, you miss one
browser. (Edit, 2015/09/31: IE proper doesn't have #supports, but Edge 12+
does, and that should increasingly cover all consumer users of the site.)
Still, this gets you most of the way there, and it should be future-facing: this
should progressively enhance the site nicely. The normal (bad, but functional)
small caps are displayed in the meantime, and when browsers eventually get
around to using OpenType small caps by default for font-variant: small-caps,
this will continue to work just fine. It's "progressive enhancement" and it'll
work nicely for most purposes.[2]
Typeface subsetting
As mentioned in the question, one can create a subset of the typeface that
includes only small capitals. This is what I have done for the small caps on my
own website; see the first line of the first
paragraph in this post for an example.
To pull this off, you'll need to start by subsetting the typeface. You can do
this manually with a font tool, or (the simpler way) you can use FontSquirrel's
custom subsetting tool in their webfont generator. (Note: You
must check the license and confirm that the typeface in question allows this
kind of modification. See below.) In the web font generator, first upload the
file you wish to modify. Then choose the Expert radio button. Most of the
settings you can leave as they are; they're good sane defaults. Midway down the
page you'll see OpenType Flattening options. Here, select only "Small Caps".
Run the generator. The result will be a complete replacement of the normal
lowercase letters with the small caps set.[3]
In that case, you can simply apply a style to the elements you want to have
small capitals, e.g.:
.divine-name {
font-family: 'my_typeface_smcp', 'my_typeface', serif;
}
The major advantage to this approach is consistency: that typeface is going to
display on every browser out there, back to IE5.5, as long as you deliver it
correctly using the various hooks required by #font-face.
There are a few disadvantages to this approach, though:
It means delivering another font file. In my case, this would be an
acceeptably low size (since I actually only need four characters), but it's
still something to consider in general. It is in any case another HTTP
request, which is going to further slow the page load time or at least give
you some flash of unstyled text when it reloads.
It may violate the licenses of the typefaces in question. For at least one
of the fonts I am using on this project, it does: the license explicitly
forbids rebuilding the font using tools like FontSquirrel. (FontSquirrel was
the tool I used for this approach before, and it works quite well.) This is
a make-or-break issue for using a subset of a typeface to accomplish the
goal. That being said, if you have a good reason to do it, you may be able
to get support from the vendor (especially if they're a small shop). For the
project that prompted this question, I was able to do just that with a nice
email—the designer is a great guy.
The other major reason not to do it this way is that it has a significantly
higher maintenance cost. If at any point you need to change or update the
typeface, you have to go through the subsetting process all over again. By
contrast, the first option will simply work, though admittedly not as
pleasantly as one might hope, and will not only continue to work but will
actually improve over time as browsers increase their implementation of the CSS3
standard.
Notes
For various reasons (especially see note 2 below), I actually opted for the
second approach outlined here, which is the same approach I was trying to
avoid. Alas.
Issues remain: even in the latest Chrome (38 as of the time of this
edit), using the font-feature-settings: 'smcp' approach has some
issues. For example, if you turn on letter-spacing (a fairly common
recommendation for small caps), the small caps will revert
to normal lowercase letters. Fixed in Chrome 48. HT to answerer
below.
From the FontSquirrel blog post that introduced the feature:
If you have a font with OpenType features, you can now flatten some of
them into your webfont. For instance, some fonts have small caps built in,
but they are completely inaccessible in a web browser. By selecting the
"Small Cap" option, the Generator will replace all the lowercase glyphs
with the small cap variants, giving you a small cap font. Please note that
not all OpenType features are supported and if the font lacks OpenType
features, using these options won't create them.
Support for font-feature-settings:"smcp" has improved in recent browsers. Chrome 48 fixes the letter-spacing bug. And according to caniuse.com, upcoming versions of Safari for both iOS and Desktop will support it. The prefixed version is still required for -webkit, though.
You already mentioned it here, graceful degradation.
Use the font-feature setting and if a browser does not support opentype features then the user will receive all the content still, with the worst-case scenario being full-size capitals; nothing is lost. I'd say that is a graceful degradation.
Aa an alternative you might want to consider using Typogruby (http://avdgaag.github.io/typogruby/), or similar, or manually adding a class to that word which you can target directly in your html, faking it with CSS2 e.g.:
.caps {font-size: .83em; letter-spacing: .25em; text-transform: uppercase;}
Edit: Of course, with the above method you can also specify a different font for the .caps class, one with full caps that will work well at small sizes in place of true small caps.
Stop thinking OpenType for a moment and think content: you need different styling for semantically different data (in this case, smallcaps styling for a special religious word) That's literally what HTML markup was invented for. Just auto-wrap those words in <span class="smallcapped"> markup with javascript, and have its class use a dedicated small-caps font. This is very easy to do, and even allows you to find the best suite smallcaps look independent of the main text typeface.
Simply run some code every time a section is DOM-loaded (emphatically not after your entire content is done, unless you're only ever showing short stretches of text):
function wrapSmallcaps(element) {
var content = element.innerHTML;
["LORD"].forEach(function(term) {
var search = new RegExp(" W?"+term+" W?",'g');
content = content.replace(search, function(a,b) {
return a.replace(term, "<span class='smallcapped'>"+term+"</span>");
});
});
element.innerHTML = content;
}
ex: http://jsbin.com/cowumaxe/1/edit
We could solve this by trying to make use of OpenType fonts, but you'd be tying yourself to one font, rather than one for for each style, making it extremely hard to improve the looks later on without violating font licenses when a better running text typeface or smallcaps typeface is found, or user feedback prompts you to improve the looks.
(and of course, this code is literally universal for any browser since IE8 -- http://caniuse.com/#search=queryselector shows zero "no support" or even "partial support" for all browsers people actually use)
See images:
Firefox on Mac:
Firefox on Chrome:
On chrome you can see that the same font using the same styling takes more room. What can I do so that all browsers will render the font the same way rather than adding more width to it?
I am using a font with #font-face property.
Unfortunately, there isn't much you can do about the way each browser renders your chosen typeface. Check out this article, it explains how different browsers and operating systems render different type face files:
http://www.smashingmagazine.com/2012/04/24/a-closer-look-at-font-rendering/
In the meantime, you can do two things.
1.) There are many fonts that can be used that are effected by this rendering difference much less. Experiment with different fonts that hold the same esthetic value of the font that you are using, and try to find one that not only fits your typographic needs but also have a less distinctive difference between their individual renderings across different platforms.
2.) Create a script to sense the user's browser/OS and use that script to adjust your font-weight accordingly.
Best of luck.
You forgot to mention which of the two cases is the correct font rendering.
A few ideas that come to mind:
Since you mentioned using font-weight:600 I would try to replace it with normal/bold (depending which result you want) and check if it makes any difference. If the font file does not support a weight for 600 the browser will go on interpreting it by itself - sometimes it takes bold sometimes normal.
If the problematic browser is Chrome you can also try playing with font-smoothing - sometimes it helps improving the font rendering:
-webkit-font-smoothing: none || antialiased || subpixel-antialiased
Also I'm not sure how you are implementing the #font-face - if you wrote it yourself I suggest generating your #font-face rule trough some service like Fontsquirell since it will generate a crossbrowser compatible code which often eliminates a few problems.
For more help you will need to expand your question with a bit more data - add the #font-face code, font name and specify which is the correct font rendering. Poor questions get poor answers.