20

Is there any way to specify different font sizes for fallback fonts in CSS? I want to do something like this (which obviously does not work):

div {
    font-family: "Arial Narrow", Arial, Helvetica, sans-serif;
    font-size: 20px, 18px, 18px, 18px;
}

The idea being that Arial Narrow would display at 20px if the user has it installed; if not, the browser would fall back to Arial at 18px, then Helvetica at 18px, etc.

Or, could I use JS to achieve a similar effect?

daGUY
  • 27,055
  • 29
  • 75
  • 119
  • Could you break it in multiple rules with just one font: entry one after the other? Arial narrow 20 would be the last one. – microspino May 11 '11 at 21:43
  • @microspino, that would just over-ride the previous declaration. – DA. May 11 '11 at 21:44
  • @DA - would it still override it even if the font specified wasn't installed? It's an interesting idea... – daGUY May 13 '11 at 17:41
  • yes, it would, The two styles aren't 'linked' together. whatever the last font-size declaration for div is is what it will use regardless of the font being rendered. – DA. May 13 '11 at 17:59

6 Answers6

6

I understand what you want, but I think the answer to your question is "No, this can't be done in CSS", at least not in CSS2 afaik.

Hoping someone can prove me wrong, 'cause i want this too :D

I suppose JS can accomplish this, at least up to some point. Not sure if there is a "is this font installed?" method in JS, but you may be able to make some educated guesses based on OS and such. Got no experience there sorry.

Edit: some quick googling does provide a few clever JS tricks, though I haven't tried them yet. E.g. http://remysharp.com/2008/07/08/how-to-detect-if-a-font-is-installed-only-using-javascript/

Another edit, after some more searching: I was triggered by the "someone should propose it" :D. It seems CSS3 spec has the "font-size-adjust", which may be of use here. However, support in browsers other than Firefox may not be optimal at the time I write this. Here's the W3 word on that property: http://www.w3.org/TR/WD-font/#font-size-adjust

Jeroen
  • 60,696
  • 40
  • 206
  • 339
  • I, too, believe the answer is 'no' but it would be a useful feature if it existed. – DA. May 11 '11 at 21:45
  • +1 there is no reliable way to do this, not even in JS. See [Get computed font-family in JavaScript](http://stackoverflow.com/q/1960817) – Pekka May 11 '11 at 21:53
  • Remy Sharp's method is very clever, though that's overkill for my particular case. I was hoping there was a way to do this through plain CSS that I just wasn't aware of. Kind of surprising that there isn't, honestly...someone should propose it! :-) – daGUY May 11 '11 at 22:04
  • Good point daGUY, someone should! Turns out something alike was in the W3 documents for CSS3, I added a link to my answer. – Jeroen May 11 '11 at 23:21
  • @Jeroen - nice, that's the type of thing I was looking for. So it seems this may be more practical in the future once browser support catches on. Honestly, though, I prefer my hypothetical syntax - if you can specify multiple fonts with the font-family property, why not multiple sizes with the font-size property? – daGUY May 13 '11 at 17:38
  • there's always been a bit of dissonance between the W3C and typographers. We definitely need more type folks on the W3C proposal groups. ;) – DA. May 13 '11 at 18:01
6

The @font-face size-adjust descriptor in CSS Fonts Module Level 5 "defines a multiplier for glyph outlines and metrics associated with this font, to allow the author to harmonize the designs of various fonts when rendered at the same font-size". css-fonts-5 is a Working Draft (as at Feb 2022), but many browsers have support 'size-adjust' since late 2021.

In the example below, size-adjust is used to make 'courier-new 12pt' and 'Consolas 12pt' render with near-identical width; normally 'Courier New 11pt' is required to match the width of 'Consolas 12pt'.

@font-face {
  font-family: courier-new;
  src: local(Courier New);
  size-adjust: 91.6%
}
<p style="font-family: 'Courier New'; font-size: 11pt">ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 abcdefghijklmnopqrstuvwxyz</p>
<p style="font-family: courier-new; font-size: 12pt">ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 abcdefghijklmnopqrstuvwxyz</p>
<p style="font-family: Consolas; font-size: 12pt">ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 abcdefghijklmnopqrstuvwxyz</p>
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Trevor Davel
  • 571
  • 3
  • 5
1

I had a related problem using CSS3 fonts, which obviously don't work in IE6-8. The fallback font (Arial) is much bigger than the default font. Got round it in a similar way to mVChr but by detecting the browser. Not pretty really, but the joys of having to support IE. Code (with jQuery):

<script>
    $(document).ready(function() {
        //change font sizes in IE6-8 because they display Arial not Dincon
        if(navigator.userAgent.indexOf('MSIE 6') > -1 
         || navigator.userAgent.indexOf('MSIE 7') > -1 
         || navigator.userAgent.indexOf('MSIE 8') > -1) {
            $('.offending-class').css('font-size', '11px');
        }
    });
</script>
james-geldart
  • 709
  • 7
  • 9
0

If Arial Narrow is missing on some browsers, those browsers normally accept @font-face urls like

@font-face {
    font-family: Arial Narrow;
    src: url(Arial Narrow.otf);
} 
 

@font-face I find works on all common browsers except for IE8/IE9, if vista dose not have Arial Narrow for example I use fullback CSS for IE8 with new font size

<head>

<!--[if IE 7]>
 <link rel="stylesheet" type="text/css" href="css/ie7.css">
<![endif]-->
<!--[if IE 8]>
 <link rel="stylesheet" type="text/css" href="css/ie7.css">
<![endif]-->
<!--[if IE 9]>
 <link rel="stylesheet" type="text/css" href="css/ie7.css">
<![endif]-->
<!--[if IE 6]>
 <link rel="stylesheet" type="text/css" href="css/ie7.css">
<![endif]-->

</head>
  • 1
    Did you intend in your example to include the same css file for each version of IE? – EWit Nov 09 '14 at 11:33
0

With Javascript, you can make a span with a capital "A" in it. If Arial Narrow is installed, this will have a width of 11px, if not it will have a width greater than that. You can check this span and then hide it to determine what you have installed.

a = document.createElement('span');
a.innerHTML = 'A';
a.style.display = 'inline';
a.style.fontFamily = '"Arial Narrow", Arial, Helvetica, sans-serif';
a.style.fontSize = '20px';
document.body.appendChild(a);
aw = a.offsetWidth;
a.style.display = 'none';
a.parentNode.removeChild(a);

if (aw > 11) {
    document.getElementById('yourDiv').style.fontSize = '18px';
} else {
    document.getElementById('yourDiv').style.fontSize = '20px';
}
mVChr
  • 49,587
  • 11
  • 107
  • 104
0

Maybe a pretty obvious answer, but as long as there is no CSS rule for specifying the font-size of a backup font - which would make a lot of sense, the next best solution I found is to insert the font-family for each offending element and then pick as the fallback font something with a similar size or a smaller type to reduce the impact on your CLS (I found out Tahoma to be a great pick most of the time).

DeZeA
  • 417
  • 5
  • 9