Secondary fonts for Chinese characters - css

Is there any way in CSS to specify a different font to be used just for Chinese characters?
Specifically, I have some user inputted text which can contain either standard English, Han characters or a mix of both. I'd like to use Myriad Pro for non-Han characters, and Kaiti Std for all Han characters.
I realize this can be done by running over the content with JavaScript, adding span tags around the Chinese characters and then applying styles to them, but is there any more standard/efficient way?
I don't care about old browsers, although it should work in the latest version of Chrome/Firefox/Safari/IE.

You can specify a unicode-range for font-faces so that that each font only applies to a subset of unicode characters.
http://dev.w3.org/csswg/css-fonts/#composite-fonts
A very basic implementation would look something like (adjust for font files and formats as needed):
#font-face {
font-family: 'MyFonts';
src: local('Kaiti Std');
unicode-range: U+4E00-9FFF;
}
#font-face {
font-family: 'MyFonts';
src: local('Myriad Pro');
}
body {
font-family: 'MyFonts', sans-serif;
}
Some interesting browser quirks/work-arounds documented at http://24ways.org/2011/creating-custom-font-stacks-with-unicode-range/

Related

Apply custom font to Unicode range while preserving font of characters outside range

My goal is to apply a custom font that I have to a range of Unicode characters (Chinese in this case), and have the remaining characters retain their font.
Via this Stack Overflow question: How to apply font-face only to a certain range of Unicode characters and looking at the source code of this Chrome extension that forces custom fonts, I was able to create the below CSS code. The code is to be inserted as <style> element contents above the <head> of a webpage.
#font-face {
font-style: normal;
font-family: "李国夫手写体";
src: local("李国夫手写体");
unicode-range: U+2E80-9FFF, U+F900-FAFF, U+FE30-FE4F, U+20000-2FA1F;
}
#font-face {
font-style: bolder;
font-family: "李国夫手写体";
src: local("李国夫手写体");
unicode-range: U+2E80-9FFF, U+F900-FAFF, U+FE30-FE4F, U+20000-2FA1F;
}
:not(pre):not(code):not(textarea):not(tt):not(kbd):not(samp):not(var) {
font-family: "李国夫手写体" !important;
}
This does indeed change the fonts in the range to my custom one. However, it also sets all the fonts used by other characters outside the range to a default value.
Before:
After:
*Here the difference in English fonts is not super clear, but there are changes if you look closely at the font. The difference is however significant with different size/custom/fancy fonts — see below image.
Is there any way of applying a custom font to only characters in some range without affecting other characters?

How to apply font-face only to a certain range of Unicode characters

A string queried from database look like this អាស័យដ្ឋានបច្ចុប្បន្ន 123, Street: National Road 3, ភូមិ ១, អូរឫស្សីទី ២, ៧មករា, ភ្នំពេញ តទៅនេះហៅថាភាគី«ក»។
I used font face font-family: 'Battambang', cursive;. The ASCII characters look good using that font, but the other characters inside the string look a bit cumbersome.
Rendering on browser, it looks like this:
If I remove font-face the non-Unicode characters look good, but the Unicode characters don’t.
Therefore, is there any CSS trick I can use to apply the font only to certain Unicode characters but not to others?
Since the Battambang typeface doesn’t contain those characters, they’re falling back to what you specified: cursive. Use the one that would normally be inherited instead.
font-family: Battambang, Roboto; /* or whatever it would be normally */
For typefaces that do contain characters you want excluded, you’ll also need to specify a unicode-range:
#font-face {
src: /* … */;
font-family: Battambang;
unicode-range: U+1780-17FF, U+200B-200C, U+25CC;
}

Use font-weight bold only when Webfont doesn't support characters

I'm using a webfont that only supports most of the latin characters. However, the website is multilingual, russian is one of the languages. As you probably know, russian consists of cyrillic characters, which are then displayed in the secondary font-family. I found Verdana + font-weight:bold to be a good alternative.
However, font-weight bold needs to be related to Verdana only, so I can't just write it into the normal CSS, as the webfont should not be displayed bold. Here some tries that did not work:
CSS:
#font-face {
font-family: "some Webfont";
src:url('xyz.eot')
}
/* The font-weight won't work here */
#font-face {
font-family: "Verdana-Bld";
src:
local('Verdana');
font-weight:bold;
}
/* Doesn't work in IE9 at all */
#font-face {
font-family: "Verdana-Bld";
src:
local('Verdana Bold');
}
/* Doesn't work in IE9 at all */
#font-face {
font-family: "Verdana-Bld";
src:
local('Verdana Bold');
}
.container {
font-family:"some Webfont", "Verdana-Bld";
}
So font-face is probably not the solution here, Verdana Bold seems to be a good way, however, it's not working when using it in normal CSS like this:
.container {
font-family:"some Webfont", "Verdana Bold";
}
I don't get it, when using #font-face, it finds and renders that font, but not when using as font-family?
Verdana Bold is really just a typeface of the Verdana font family, and it should be used by setting font-family: Verdana; font-weight: bold. In some cases, it is possible to use a typeface as if it were a font family, by declaring its name as the value of font-family, but this is browser-dependent and depends on the font, too; for Verdana Bold, the trick does not appear to work. The more complicated trick of using #font-face works for some browsers but not all, as you have seen; this even depends on the font name you use (e.g., the “full font name” Verdana Bold vs. the PostScript font name Verdana-Bold).
So a different approach is needed: try and find a font that covers all the characters needed. E.g., at Google web fonts, you can set “Script” to “Cyrillic” to find fonts that support Russian letters. Such fonts generally support Latin letters, too.
So The font-weight in font-face doesn't set the font-weight but is kind of a filter for browsers to decide if it is the right font to use. So when the browser looks which font to display it will choose the font-face where you set font-weight: bold just if your current text is bold and will take the other one in any other situation.
I think that it is actually possible to make one font bold and the other one regular just if you can call this in font-face directly. (so if you could have something like local('Verdana Bold'). Then just get rid of font-face:bold and it should work fine.

Fallback fonts on special characters

I was wondering if it's possible to, when using #font-face, have a fallback setup so that if the text on my page contains characters that are not accounted for within the font (Japanese characters for example), only those characters are presented in a basic font and every other character remains as the custom font?
I'm imagining that potentially there'd be a mix of two fonts within one paragraph on occasion.
What you described is the default behaviour of a browser - it should naturally fall back to basic font for missing characters.
However, sometimes custom fonts use blank characters, in that case you can try using the unicode-range
For example:
#font-face {
font-family: BBCBengali;
src: url(fonts/BBCBengali.ttf) format("opentype");
unicode-range: U+00-FF;
}
Taken from this interesting article: Creating Custom Font Stacks with Unicode-Range
Unfortunatelly there are browser support issues.
CSS has default fallback to the system font if the specified font doesn't contain a character.
You can also specify which font to fall back to.
Example for a serif font:
body {
font-family: "MyNiceFontWithoutJapanesChars", "common serif font", serif;
}
As long as the fallback font has those characters your default font misses, you should be all right.

Use different fonts for Latin characters and Japanese characters with CSS

We are creating a site that uses both Japanese and English. We want to get away from the default Japanese fonts which can't use ClearType. Is there a way to tell the browser to use a different Japanese font JUST for Japanese characters (Like Meiryo) and another font just for latin characters (Like Helvetica) on the same page? We don't want any English words to use the Meiryo font.
We actually used a tip to specify English fonts first in the CSS from this article: http://www.lukew.com/ff/entry.asp?118
However, this doesn't work in IE. Even if we specify Helvetica, Verdana, or any other widely available font first and then the Japanese font in the CSS, IE will still use the Japanese font for English words. Firefox, Chrome, etc. work as expected.
(If possible we hope not to resort to something like wrapping each English word in a span)
I've solved my problem using 'unicode-range' CSS property.
You can find the details here:
https://developer.mozilla.org/en/docs/Web/CSS/#font-face/unicode-range
Example:
/* bengali */
#font-face {
font-family: 'Atma';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/atma/v2/tUcVDHNCVY7oFp6g2zLOiQ.woff2) format('woff2');
unicode-range: u+0980-09FF;
}
body {
font-family: 'Atma', arial, sans-serif;
font-size: 18px;
}
<p>Example is better than precept.</p>
<p>উপদেশের চেয়ে দৃষ্টান্ত ভালো।</p>
You cannot get around marking every language section with a class and font if you want this to work cross-browser. It cannot be done with only CSS.
You can apply a language class manually or automatically. Manually might be a lot of work to support and maintain, but is robust. Dynamically it can be done using a back-end script or Javascript, by scanning a string for characters that fall within certain unicode character blocks, and applying a language class accordingly.
You can find the block definitions here (Japanese is Hiragana and Katakana): http://www.fileformat.info/info/unicode/block/index.htm
I'd recommend the back-end way of doing this, because changing a font on the page might cause flickering or shifting of elements during page load.
Create css class for English and Japanese text.
.ja { font-family: meiryo, sans-serif; }
.en { font-family: arial, verdana, sans-serif; }
If entire page is in Japanese, add class="ja" to body tag, if there's mixed content, add class="ja" to the html element that contains Japanese text, for example:
<td class="ja">日本語</td>
How are you telling the page what language to print to screen?
If you are getting a variable can you not use this variable as a class which you use for a div of body.
<body class="english">
or
<body class="japanese">

Resources