有關(guān)字體的小小迷思
在前端工作中,大家都會時常需要注意到一些小小的細節(jié)的地方,雖然很小很容易忽略,但是卻也直接到關(guān)系到用戶體驗的問題。
Q1: – 明明是微軟雅黑,為什么在 MAC 下卻變成了種丑丑的字體?
Q2: – 為什么微軟雅黑的字有時候看著怪怪的,大小不一樣呢?
Q3: – 為什么相同的頁面在不同的系統(tǒng)不同的瀏覽器下看卻是不一樣的?
Q4: – 字體渲染到底跟什么有關(guān)系?
為此,做了一個小 DEMO 以測試一下,分析下相同的頁面在不同的 OS 和不同的瀏覽器下的表現(xiàn)差異。
一、編碼與解碼
Web 服務(wù)器返回的 HTTP 頭中的 Content-Type: text/html; charset=“”的編碼
與 html 中“ lang ”屬性有關(guān)
網(wǎng)頁本身 meta header 中的 charset 部分
瀏覽器菜單里一般允許用戶強制指定編碼
注:chrome55已經(jīng)去掉默認編碼選項,改為auto-detect。
二、選擇字體
按照字體的描述方式來分:
點陣字體
矢量字體(輪廓字體)
矢量字的好處是字體可以無級縮放而不會產(chǎn)生變形。目前主流的矢量字體格式有3種:Type1,TrueType 和 OpenType。如下圖中,前面有兩個 T 的是 TrueType 的格式字體,O 開頭的是 OpenType 的字體。
很多人把“宋體”(simsun)當(dāng)作點陣字體,其實不是,它和“微軟雅黑”(microsoft yahei)一樣,都屬于輪廓字體,只不多12px~17px的宋體內(nèi)置了點陣信息而已。
按照字體的表現(xiàn)形式來分:
襯線字體(serif):比如,宋體,Georgia,Times New Roman
非襯線字體(sans-serif):比如 Tahoma, Arial , 幼圓
其它字體:等寬字體(monospace),書寫體(cursive),夢幻體(fantasy)
三、系統(tǒng)已安裝的字體
首先系統(tǒng)所包含字體不只和系統(tǒng)預(yù)裝的字體有關(guān),還和系統(tǒng)上安裝哪些軟件有關(guān)。微軟操作系統(tǒng)下,詳細的系統(tǒng)和一些軟件包含的字體可以查看這個索引:Microsoft typography,Mac系統(tǒng)可以查看這個索引:List of typefaces included with OS X,移動端 IOS Fonts 和 IOS Font List 。
A1: 由于不同系統(tǒng)默認安裝的字體的不同,且不同瀏覽器默認渲染的字體不同,如果只在css里定義里,font-family:’微軟雅黑’ 的話,在MAC里有些瀏覽器下沒有相關(guān)中文字體定義的話,會回退到MAC下的默認宋體展示,視覺效果就會大打折扣了。
四、系統(tǒng)渲染引擎
不同瀏覽器有著不同的渲染引擎。Mac OS X 用戶使用 CoreText 渲染引擎,Windows7 和 Windows Vista 用戶使用 DirectWrite 或 GDI ,而 Windows XP 則使用 GDI。
GDI 分為 GDI Grayscale 和 GDI ClearType 。前者為灰階渲染 API,后者是亞像素渲染 API。由于 GDI ClearType 并未對字體進行垂直方向的平滑,因此當(dāng)字體較大時會出現(xiàn)邊緣不平滑的情況。為了彌補 GDI ClearType 的不足,MS實現(xiàn)了 DirectWrite API,它在 GDI ClearType 的基礎(chǔ)上增加了垂直方向的平滑。
使用同一顏色,感官上的顏色深淺為:黑白渲染> grayscale > sub-pixel。
iOS 和 Mac 的渲染引擎一樣,但采用的是灰度渲染,默認情況下亞像素抗鋸齒是關(guān)閉的,但可以通知設(shè)置開啟。
由于渲染策略的不同,字母a在不同的瀏覽器和 OS 下的渲染表現(xiàn)也不同。第一個是理想模型的a,第二個是灰階渲染的a,第三個是亞像素渲染,第四個是黑白渲染。
五、瀏覽器
常用字體在瀏覽器中的渲染情況
注:從 chrome52 開始,google 停止對于老的操作系統(tǒng)的支持,包括 windows xp 和 windows vist a停止了 GDI 的字體渲染,從而只支持 DirectWrite.
六、光柵化(hinting)
光柵化是將文字從一個向量表示(比如一個 TrueType 字體)轉(zhuǎn)化到光柵或者位圖表示的過程。在這個過程中往往涉及到一些抗鋸齒技術(shù)來使得屏幕上的字體更加平滑易讀。但是,號稱100美元一個字的微軟雅黑為什么會出現(xiàn)字體大小不一的情況?
A2: ClearType 的渲染方式,使得它非常依賴 hinting 信息。但是微軟雅黑的 hinting 飽受詬病,特別是在小號字顯示下,特別明顯。
七、CSS 定義
CSS 對于字體的定義屬性也有很多。比如 font-family,它的屬性的值是用于某個元素的字體族名稱或/及類族名稱的一個優(yōu)先表。瀏覽器會使用它可識別的第一個值。
字體系列名稱中有兩種,
第一種是指定的字體系列名稱,比如:“times”, Arial”等。
第二種是通常字體名稱,是一個字體族。比如我們習(xí)慣添加在 font-family 最后的 sans-serif 和 serif 。
A3: 從測試 Demo 中可以看出:字體的展現(xiàn)受系統(tǒng)預(yù)裝字體的影響,也受瀏覽器默認字體的影響。Mac 下的中文字體,除了受 font-family 屬性中的字體名稱優(yōu)先集影響外,也受最后一個屬性 serif 和 sans-serif 的屬性的影響。因此,如果你對中文字體只定義了微軟雅黑,或者沒有定義中文字體,并且定義了襯線字體,那在MAC下顯示的就是圖中的宋體。
不同的操作系統(tǒng)有不同的渲染引擎,但是即使是相同的操作系統(tǒng),不同的瀏覽器也會有不同的表現(xiàn)。因為瀏覽器廠商所選用的渲染 API 都是不同的。
-webkit-font-smoothing屬性:-webkit-font-smoothing: none | subpixel-antialiased | antialiased
none: 不平滑,字體具有鋸齒鋒利邊緣,適用于小像素的文本。
subpixel-antialiased 使用亞像素平滑。
antialiased 使用灰階平滑。
還有一些別的屬性:
Github上的 font-family 是這樣定義的:
1 | font-family:"-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" " |
那么這個 -apple-system 和 BlinkMacSystemFont 是什么呢?
-apple-system 用于調(diào)用系統(tǒng)默認 UI 字體,并且會根據(jù) font-weight 聲明選擇恰當(dāng)?shù)淖凅w。system 將來有可能成為標準,-apple- 為過渡階段的廠商前綴。
BlinkMacSystemFont:為 macOS Chrome 應(yīng)用系統(tǒng) UI 字體,與上面等同。
結(jié)論:
A4: 從字體在瀏覽器上的種種表現(xiàn)來看,分析其原因,這和編碼方式,系統(tǒng)字體類型及排版引擎,瀏覽器都有關(guān)系,是一種比較復(fù)雜的表現(xiàn)方式。小小字體在不同環(huán)境下的表現(xiàn)方式都是不一樣的,要盡量識別他們的差異,并能找到一種最佳適合的解決方式。
參考文檔:
1. 維基百科——計算機字體
https://zh.wikipedia.org/wiki/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%AD%97%E4%BD%93
2. 網(wǎng)站字體渲染過程
https://isux.tencent.com/website-font-rendering-process.html
3. 字體渲染
http://ued.ctrip.com/blog/font-rendering.html
4. DirectWrite 簡介
https://msdn.microsoft.com/zh-cn/library/windows/desktop/dd371554(v=vs.85).aspx
5. 在WEB內(nèi)容中使用系統(tǒng)字體
https://csspod.com/using-the-system-font-in-web-content/
6.A Closer Look At Font Rendering
https://www.smashingmagazine.com/2012/04/a-closer-look-at-font-rendering/
本文地址:http://likemindfilms.com/tutorial/di3382.html