對HTML標準的思考 - 記解決H5隨機顯示簡繁體漢字問題
遇到問題
上個月在開發淘票票專業版過程中,我們遇到了一個奇怪的問題:
H5容器裏的漢字被顯示為一些奇怪的樣子。
首先:
1)這個問題不能準確複現,同型號同係統的兩台 iPhone 6s Plus 有一台會出現;
2)不確定是否在 Android 上出現;
3)如果出現問題,重裝 APP 則有可能恢複正常。
介紹下出問題的環境:
目前隻在 iOS 係統中複現,H5 使用 Windvane 容器
真機不好調試,模擬器不能準確複現,暫時不知如何進行了。
跳進了一個坑
以為是簡繁體問題,打開輸入法看看繁體「票房」怎麼寫,似乎並不是繁體字:
直到項目進入了測試用例編寫階段,我發現 Aone 上能準確複現這個字體問題,如圖。
馬上打開 Chrome 進行調試,看到了一個陌生字體:AppleGothic
上字體網站預覽 AppleGothic 效果:
確實和截圖裏的字體非常相似。知乎搜索 AppleGothic ,其中有一條:
/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/Resources/DefaultFontFallbacks.plist
對應日/韓/簡/繁分別是 AquaHiraKaku/AppleGothic/STHeitiSC-Light/STHeitiTC-Light。
於是幾天時間一直在搜索相關資料,仍然無解。
跳出坑
開始想到是 iOS 係統字體顯示的優先級問題,在「設置-通用-語言與地區」可以看到。找到幾台複現問題的機器查了顯示順序發現,首選語言均是「簡體中文」、「繁體中文」、「English」,不太可能顯示「韓文」。
到底哪裏出了問題?
我又拿出截圖逐個對比了下字體,很明顯「排片」倆字的顯示效果不一致:
問題仍然沒解決。
定位問題
回到起點,幾乎沒有任何進展。
無奈,從代碼層麵分析:
影響文字顯示的主要是:
- 係統語言與區域設置;
- 瀏覽器字體順序設置;
-
font-family
屬性; - lang 屬性。
排除 1、2 不可改變因素,定位到第3、4點,發現問題:
其中第3點,我們選擇 reset 的 CSS 重置方案,body 節點設置了:
font-family: 'Helvetica Neue', sans-serif;
字體棧設置了 Helvetica
和 「非襯線」字體族,如果是中文字體,Helvetica
默認 Fallback 到下一字體,而下一個字體 sans-serif
則根據係統設置進行渲染。iOS 係統裏對於中文字體默認使用 「PingFang」,簡體為「PingFang SC」,繁體為「PingFang TC」。
聯係客戶端同學幫忙查了下 APP 區域設置,默認為 en-US
。
這一點我不太確定:
「如果 html 文檔沒有設置語言區域,會從瀏覽器或係統環境取到當前所在區域的字體作為顯示字體」
第4點,容器沒有找到 lang ,且檢測到當前環境為 en
,而文檔內容是「漢字」,則默認在「簡」、「繁」的「PingFang」中選擇,如:
font-family: 'Helvetica Neue', 'PingFang SC';
font-family: 'Helvetica Neue', 'PingFang TC';
預覽「PingFang TC」字體:
確實完全匹配。
解決
上麵提到的第 4 點,結合定位的 font-family
問題,主要有兩種解決方案。
- 設置
lang
- 設置
PingFang SC
操作第二點,局限性比較大。因為僅針對一種字體進行設置,如果未來引入了新字體,則同樣會出現這個問題;
我比較傾向於設置 lang
屬性解決:更新 html 的 <html>
標簽為 <html lang="cmn-Hans">
,使瀏覽器默認使用普通話的簡體中文作為顯示語言進行渲染。
對於 lang 屬性的最佳實踐,可以參考:BCP 47
取值順序:language-extlang-script-region-variant-extension-privateuse
來自:https://www.w3.org/International/articles/language-tags/
發布到預發環境下連續測試了一周,問題沒有複現,基本可確定問題解決。
附
對於 lang 屬性的設置,過去我們一直設置為 zh-cmn-Hans
,查閱了 IANA:
Type: redundant
Tag: zh-cmn-Hans
Description: Mandarin Chinese (Simplified)
Added: 2005-07-15
Deprecated: 2009-07-29
Preferred-Value: cmn-Hans
已被標記為「不推薦使用」,需要調整為「cmn-Hans」。如果為了兼容,可以加上「zh-」:「zh-cmn-Hans」
參考
- IANA language-subtag-registry
- IETF BCP 47
- W3C language-tags
完
最後更新:2017-07-19 15:02:38