閱讀342 返回首頁    go 阿裏雲 go 技術社區[雲棲]


對HTML標準的思考 - 記解決H5隨機顯示簡繁體漢字問題

遇到問題

上個月在開發淘票票專業版過程中,我們遇到了一個奇怪的問題:

H5容器裏的漢字被顯示為一些奇怪的樣子

IMG_1653.png
IMG_1654.png

首先:
1)這個問題不能準確複現,同型號同係統的兩台 iPhone 6s Plus 有一台會出現;
2)不確定是否在 Android 上出現;
3)如果出現問題,重裝 APP 則有可能恢複正常。

介紹下出問題的環境:

目前隻在 iOS 係統中複現,H5 使用 Windvane 容器

真機不好調試,模擬器不能準確複現,暫時不知如何進行了。

跳進了一個坑

以為是簡繁體問題,打開輸入法看看繁體「票房」怎麼寫,似乎並不是繁體字:

image.png

直到項目進入了測試用例編寫階段,我發現 Aone 上能準確複現這個字體問題,如圖。

image.png

馬上打開 Chrome 進行調試,看到了一個陌生字體:AppleGothic

image.png

上字體網站預覽 AppleGothic 效果:

image.png

確實和截圖裏的字體非常相似。知乎搜索 AppleGothic ,其中有一條:

/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/Resources/DefaultFontFallbacks.plist
對應日/韓/簡/繁分別是 AquaHiraKaku/AppleGothic/STHeitiSC-Light/STHeitiTC-Light。

於是幾天時間一直在搜索相關資料,仍然無解。

跳出坑

開始想到是 iOS 係統字體顯示的優先級問題,在「設置-通用-語言與地區」可以看到。找到幾台複現問題的機器查了顯示順序發現,首選語言均是「簡體中文」、「繁體中文」、「English」,不太可能顯示「韓文」。

到底哪裏出了問題?

我又拿出截圖逐個對比了下字體,很明顯「排片」倆字的顯示效果不一致:

image.png

image.png

問題仍然沒解決。

定位問題

回到起點,幾乎沒有任何進展。

無奈,從代碼層麵分析:

影響文字顯示的主要是:

  1. 係統語言與區域設置;
  2. 瀏覽器字體順序設置;
  3. font-family 屬性;
  4. 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」字體:

image.png

確實完全匹配。

解決

上麵提到的第 4 點,結合定位的 font-family 問題,主要有兩種解決方案。

  1. 設置 lang
  2. 設置 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」

參考

  1. IANA language-subtag-registry
  2. IETF BCP 47
  3. W3C language-tags

最後更新:2017-07-19 15:02:38

  上一篇:go  中國企業如何應對網絡安全
  下一篇:go  php5.2.14多版本共存編譯