Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS Font Fallback for Missing Glyphs

Tags:

browser

css

fonts

CSS:

p { 
font-family: Gill Sans, SFU GillSans;
}

"SFU GillSans" is a font for Vietnamese language. According to this link, if p contains a Vietnamese character that is not in Gill Sans font, then the browser will look for it in "SFU GillSans" font.

Is it possible to switch to second font entirely, not only some characters, if the default font misses any character?

like image 564
hans-t Avatar asked Jun 05 '15 17:06

hans-t


2 Answers

With pure HTML/CSS: no you cannot do that.

But what you can do is determine which glyphs are being used in a string, compare that to the glyphs being available in a font, and conditionally set a different font for a section or entire page using a CSS class.

Determining which glyphs are used in a string can be done on-the-fly using JavaScript, or using any server-side language.


Update: I added an example below especially for Vietnamese.

The name and contents of VIETNAMESE_DIACRITIC_CHARACTERS and containsVietnamese can easily be changed to match (un)supported character ranges in your fallback or main font. (whitelist or blacklist approach).

// From http://stackoverflow.com/a/26547315/451480:
var VIETNAMESE_DIACRITIC_CHARACTERS = 'ẮẰẲẴẶĂẤẦẨẪẬÂÁÀÃẢẠĐẾỀỂỄỆÊÉÈẺẼẸÍÌỈĨỊỐỒỔỖỘÔỚỜỞỠỢƠÓÒÕỎỌỨỪỬỮỰƯÚÙỦŨỤÝỲỶỸỴ';

var paragraphs = document.querySelectorAll('p');

for (var i = 0, m = paragraphs.length; i < 1; i++) {
  if (containsVietnamese(paragraphs[i])) {
    paragraphs[i].className = 'vietnamese';
  }
}

function containsVietnamese(paragraph) {
  var text = paragraph.innerText || paragraph.textContent;
  for (var i = 0, m = text.length; i < m; i++) {
    // Return true if VIETNAMESE_DIACRITIC_CHARACTERS contains the uppercase character from the paragraph
    if (VIETNAMESE_DIACRITIC_CHARACTERS.indexOf(text[i].toUpperCase()) > -1) {
      return true;
    }
  }
}
p {
  border: 1px solid #ddd;
  font-family: myregularfont, sans-serif;
}
.vietnamese {
  font-family: myvietnamesefont, serif;
  background: green;
}
<p>This paragraph should switch to a serif font: bằng "level, flat" ngang and huyền trắc "oblique, sharp" sắc, hỏi, ngã, and nặng</p>
<p>Chinese (汉语 / 漢語; Hànyǔ or 中文; Zhōngwén) is a group of related but in many cases mutually unintelligible language varieties.</p>
<p>English is a West Germanic language that was first spoken in early medieval England and is now a global lingua franca.</p>
like image 178
Blaise Avatar answered Sep 30 '22 12:09

Blaise


Short answer: no. That's not what CSS can do.

Fallback fonts really do mean fallback, not "font switching on some signal". Fallback is only defined in terms of "if glyph X is not in font A, try font B (if specified), then C, then ... until we find a generic font-family, or nothing, in which case, use the parent element's font".

If that's what you SFU GillSans used for all text that has even a single vietnamese character in it, why not just use a font that looks good and has Latin-A through Latin-D support? You could, for instance, just use SFU GillSans as your main font, not as fallback font. On a CSS note: you need to put quotes around those names. Font-family values with special characters like dashes or spaces need to be quoted as per the CSS spec.

like image 22
Mike 'Pomax' Kamermans Avatar answered Sep 30 '22 12:09

Mike 'Pomax' Kamermans