Chrome 79 - 遲到 6 年的 rem/em 修正

更新於 發佈於 閱讀時間約 15 分鐘

眼看 Chrome 79 大概再兩周就要釋出啦!

raw-image

對大多數人來說,這個也就是 Chrome 例行更新的一個版本。

而對我,Chrome 79 修正了一個最近一年多在我心裡佔有一席之地的 bug,我曾經努力試著解決它,最後似乎也找到自己應對它的方法。而現在它要被修掉了,多少有點感觸 😥。

本文特別想趕在 Chrome 79 正式釋出之前寫出來,讓在閱讀的你也可以一同經歷這個變化的過程。

想直接看結論也可以往下到 TL;DR 的部分喔!

Chrome 的「最小字體」傳說

我想小有接觸前端的人大概都知道 Chrome 有個 最小字體是 12px 的傳說,然而時過境遷、滄海桑田,2019 的現在還是如此嗎?

實際上現在再去 Google “chrome minimum font size” 得到的結果跟討論大都是 2013 年以前的內容,就算有稍微近期的文章,也大都是參考早期文章寫出來的。

從搜尋結果裡面可以找到這個 issue:

https://bugs.chromium.org/p/chromium/issues/detail?id=36429

裡面提到幾件重要的事情:

  • Chrome 預設的最小字體是和 UI 使用的語言有關的
  • 大部分的 UI 語言預設最小字體是 1px
  • 複雜 UI 語言(多為亞洲語言)的預設最小字體是 10px/12px
  • 2010年時還沒有辦法從設定該改最小字體的設定

而到了 2019 的現在,最小字體已經可以從設定裡面更改了,位置就在「設定」->「自訂字型」

raw-image

可能很多人會是在看到這篇文章之後才第一次打開這個設定畫面,比對一下上面列出來的項目可以發現繁中 UI 的 Chrome 的最小字體預設值就是 12px。

我猜如果從安裝時就是英文版 UI,預設值應該會是 0px/6px。

曾經是傳說的最小字體 12px,僅限於某些 UI 語言(基本上就是中文、日文、韓文、泰文)的瀏覽器。
現在其實是使用者把它調低就可以解決的問題。當然,對於開發者來說還是一個無法跨越的障礙。

做一個 fiddle 來測試一下「沒調設定」跟「調過設定」的結果: https://jsfiddle.net/pc035860/jgtfdL98/4/

raw-image

Twitch 聽說你是 rem 排版大師?

自從近年各瀏覽器對 rem 的支援度有提高之後,坊間出現一些使用 rem 為單位進行網頁排版的文章,並且漸漸也有些網站開始使用這種排版方法(雖然我覺得還是相對蠻少的)。

建議往下看之前要先瞭解一下用 rem 單位進行排版大概是怎麼樣進行,可以參考下面這篇 sitepoint 的文章 https://www.sitepoint.com/understanding-and-using-rem-units-in-css/

普遍常見的起手式,是把 rem base 設為 1px 或 10px,這樣一來直接使用 rem 單位換算的過程會簡單很多。

其中又以在 <html> 上用 font-size: 62.5% 來設定為 10px 最常見:

raw-image

Twitch 的大改版衝擊

Twitch 在 2018 年 2 月左右做了一次重大改版,把原本用的 Ember.js 換成 React,這一次改版同時也把網站的排版單位改為 rem,而這也是我們繁中 Chrome 使用者的噩夢開端(好像講得有點誇張了)。

改版之後,原本頻道的資訊頁面變得非常奇怪。下面示範截圖是目前最新版,當然也還是用 rem 單位排版。

正常來說應該是這樣:

raw-image

改版後就直接跑掉:

raw-image

這還只是第一眼就覺得不對勁的部分。

用 Firefox 打開 Twitch 來比較就可以看出整個網站都有點不一樣,Chrome 整體似乎大了一號,這邊就單取側邊欄來對比:

raw-image

WTF!? 不是, Twitch 難道沒有測過嗎…

怎麼一回事

來看一下 Twitch 的 <html> 怎麼寫的

raw-image

也就是他們的 rem base 是設定為 10px,接著看看對應的 side-nav class 寬度是多少呢?

raw-image

10 * 24 = 240,他們希望的寬度是 240px,那麼實際上在我們繁中 Chrome 顯示會是多寬呢?

raw-image

288 / 24 = 12,結果不言而喻啦!

Chrome 的最小字體被套用在 <html> 上,導致 rem 的 base 直接用 12px 起跳。

類似問題,其實也曾經在 Apple 的網站上出現過,不過當時是用 em 為單位。

眼尖的你可能會在上面的截圖中發現,字體大小是相同的。那麼我們就接著來看字體大小的部分:

raw-image

14 / 1.4 = 10 剛好是設定的 rem base 10px,也就是說 font-size 部分並沒有受到 <html> 上 12px 的影響,依然故我的使用了 10px 來計算。接著我順便檢查了 padding, margin 之類的屬性,發現結果跟上面 width 一樣是用 12px 來計算的,看來只有使用在 font-size 時候的計算是分開的。

於是我們稍微修改一下上面論述,得到一個小結論:

Chrome 的最小字體被套用在 <html> 上,導致 rem 單位使用在 font-size 以外的屬性上時,其 base 直接用 12px 來做計算

這邊我做了一個簡單的驗證用 fiddle: https://jsfiddle.net/pc035860/athfj0dc/18/

裡面的 .box ,希望透過 rem 設定出的正確數值如下:

raw-image

後面也還會用到這些數值來做正確性的驗證,稍微有個印象就好了。

好啦,都是 Chrome 的錯

前面說過現在最小字體可以調整是吧,那我們把最小字體的設定調到 10px 以下不就好了嗎?

那我們就拿上面驗證用的 fiddle 來比較一下,「保持預設 12px」跟「調整到 0px」的結果:

raw-image

怎…怎麼這樣,竟然沒有變!?

UI 語言的陷阱

冷靜想想,Twitch 團隊在改版過了一年多的現在都沒有修正是什麼原因?

  • 無法 reproduce 問題
  • 只有少部分的人有問題,不用管他們

難道問題出在語言上? 讓我們把 Chrome UI 語言設定成英文試試看。

raw-image

藍框處顯示目前是中文,點擊紅框處可以切換為英文。(註: Mac 使用者需要從「系統偏好設定」->「地區與語言」裡面改)

接著再用上面的 fiddle 來測一次最小字體 0px:

raw-image

沒錯,把 UI 切成英文後就一切正常了。

順帶一提,初始安裝英文 UI Chrome 的最小字體應該是 0px/6px 其中一個,可以直接得到上圖的結果。因此如果系統語言不是上述亞洲語系的話,壓根就沒有機會看到這個 bug。

總之雖然原因不明,但看起來在繁中 UI 的 Chrome 下,就算已經調整過最小字體,在 <html> 上用 font-size: 62.5% 並沒有辦法把字體壓到 12px 以下。

繁中 UI 的最後一搏

看到這裡是不是你也覺得繁中 UI 的 Chrome 使用者真是太絕望了…

在我多番嘗試之後發現,剩下最後一手可以解決這個問題:

<html> 上指定 rem base 的方式直接寫成 font-size: 10px

雖然會失去瀏覽器設定「字型大小」的彈性,但不失為一個解決辦法。

用這個更新的 fiddle 來測試: https://jsfiddle.net/pc035860/athfj0dc/20/

raw-image

其實避免碰到上面這種 rem 單位排版問題的方法就是總是將 base 設為 12px 以上。雖然會造成使用時換算單位的麻煩,但總比碰到這種難以 debug 的問題來的好。

同場加映一個也碰到類似問題的網站 issue: https://github.com/squidfunk/mkdocs-material/issues/911

擴充功能: Twitch REM fix

於是我為了我往後美好的瀏覽 Twitch 體驗,我決定做將這個 workaround 做成 Chrome extension。

起初還有「要判斷當前 UI 語言之後再來套用」之類的天真(?)想法,靜下心來仔細想想,沒有問題的人根本不會來裝這個extension

釋懷後的我,緩緩地開了個新的 CSS 檔案,在裡面輸入:

raw-image

大功告成。

截圖跟寫說明花的時間還比打這段 CSS 多…

基本上這個 extension 會在 *.twitch.tv 下面無腦套用 contentscript.css 的內容,有修正版面需求的人可以到下面的 Github 網址逛逛:

https://github.com/pc035860/twitch-rem-fix

所以 Chrome 79 是?

好了,上面說了這麼多,總算可以進入正題啦!

來看這個 2013 年的 Chrome issue

https://bugs.chromium.org/p/chromium/issues/detail?id=308862

這個 issue 是我在最小字體的相關搜尋中翻到的,主訴是「rem/em 用作單位時,在計算結果前就被套用了最小字體的限制」,怎麼聽起來這麼耳熟?

Use computed font-size for em/rem resolution.
This makes us match how Firefox applies minimum font-size and makes us not break relative length computation when pages use a font-size less than the user’s minimum font-size as a basis for widths, heights, margins, padding, etc.

從中推敲一下,未修正前的版本大概可以這樣表示(純示意,我沒有去翻 source code):

raw-image

這個 issue 最近終於修正完畢,在 Chrome 79 會 release。

在修正後,resultRelativeLength 的式子大致上變成這樣(純示意,我沒有去翻 source code):

raw-image

我實際從 beta channel 安裝 Chrome 79 的測試的結果也沒有問題,真的修正啦!

什麼都不用做,只要更新到 Chrome 79 以上、上面的 extension 也不用裝,各種 rem 單位排版造成的問題就迎刃而解。

如果你常在看的網站 (例如: Twitch),突然變了(回原)樣,千萬別太驚訝喔 😉

值得特別提出的是,在 Chrome 79 的繁中 UI 上用 font-size: 62.5% 還是沒有辦法把渲染字體壓到 12px 以下,就算你調了最小字體的設定也一樣。 更多討論請見本文最後的附錄。

TL;DR

🍖 Chrome 的最小字體其實現在可以設定了,並且根據安裝時的 UI 語言,預設值會不同

  • 中文、韓文、日文、泰文等 是 10px/12px
  • 其他通常是 6px 或以下

🍖 Twitch 改版後使用了 rem 單位排版,在繁中 UI 的 Chrome 看起來會跑掉

🍖 在繁中 UI 的 Chrome 底下,如果 font-size 用百分比單位表示,就算調了最小字體設定也沒有辦法被壓到小於 12px

  • 因此造成 Twitch 改版後版面跑掉
  • 把 UI 語言調成英文可以解決這個問題
  • font-size: 10px 取代 font-size: 62.5% 是一種 workaround
  • 我把 workaround 做成 extension 了

🍖 Chrome 79 會修正套用最小字體的方式

  • rem 單位排版計算錯誤的問題會消失
  • 可能有些你看習慣的網站會有變化 (例如: Twitch)
  • 套用在 <html> 上時,繁中 UI 百分比 font-size 的最小值依然是 12px (見附錄)

後記

從去年改版後, Twitch 版面的問題就一直困擾著我,有點像是揮不走的蒼蠅,每次打開網站就看到 😨

直到最近(2019/9)又再一次改版,新的版面搭上崩壞的 rem 單位真的是慘不忍睹,我只好弄了一個 extension 先撐著。

偶然發現下一版 Chrome release (大概兩周後)就可以躺著解決(?),發這篇文正是為了紀念這期間我內心的掙扎,還有製作擴充功能(跟它的說明)的流下的汗水。

raw-image

我會懷念你的, Chrome 78 (含以前)!

感謝你讀到這邊,下次有有趣的東西要分享的話,我會再回來的。

附錄: 最終負載測試

以下的測試用 Chrome 79 beta 進行,「最小字體」都已經設定為 0 。

這次在旁邊加了使用同樣 rem 做為長寬的 div 來對照: https://jsfiddle.net/pc035860/jgtfdL98/35/

分別對 繁中 / 英文 UI 版本 以及 font-size: 10px / font-size: 62.5% 的組合做交叉測試,得到的結果如下:

raw-image

🍖 rem 數值用在 width, height 上不受 font-size 指定方式的影響

🍖 在使用者可以設定的「最小字體」之外,還有別的隱藏字體大小門檻

  • 只在 font-size 用百分比設定時套用
  • 根據 UI 語言會有不同的數值
    🍺 繁中 UI 是 12px
    🍺 英文 UI 是 9px
  • 從 rem base 的角度來看,門檻應該是套用在計算完 rem -> px 結果之後,否則理應會影響我們用 rem 表示的寬跟高

比較一下 Firefox Developer Edition 71 的測試結果:

raw-image

我想 Chrome 應該是出於好意啦… 嗯…

最後把這個隱藏門檻也考慮進去,整理進前面提到的式子:

raw-image


留言
avatar-img
留言分享你的想法!
avatar-img
批歪的沙龍
4會員
7內容數
網頁前端是一個需要與時俱進的工作。 你也喜歡前端嗎? 在這邊你可以找到一些前端小知識、新技術或是趣聞,歡迎與我們一同成長 🚀
你可能也想看
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
孩子寫功課時瞇眼?小心近視!這款喜光全光譜TIONE⁺光健康智慧檯燈,獲眼科院長推薦,網路好評不斷!全光譜LED、180cm大照明範圍、5段亮度及色溫調整、350度萬向旋轉,讓孩子學習更舒適、保護眼睛!
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
近日,Google Chrome 發佈最新版本,新版瀏覽器多了「與 Gemini 對話」,在網址列輸入「@」可以選擇與 Gemini 對話,接著輸入對話指令即可傳送至 Gemini 聊天服務並獲得回覆。
Thumbnail
近日,Google Chrome 發佈最新版本,新版瀏覽器多了「與 Gemini 對話」,在網址列輸入「@」可以選擇與 Gemini 對話,接著輸入對話指令即可傳送至 Gemini 聊天服務並獲得回覆。
Thumbnail
避免網頁在不同瀏覽器中長不一樣。用 CSS Reset 來「重置」和統一瀏覽器預設樣式。
Thumbnail
避免網頁在不同瀏覽器中長不一樣。用 CSS Reset 來「重置」和統一瀏覽器預設樣式。
Thumbnail
Arc瀏覽器提供更個性化、有組織和高效率瀏覽體驗的用戶而設計。本文分享了從Chrome轉投Arc的動機、Arc瀏覽器的創新功能以及其侷限和缺點,並提出了對於初期適應問題的看法。對於追求新瀏覽體驗的用戶來說,Arc是一個值得考慮的選擇。
Thumbnail
Arc瀏覽器提供更個性化、有組織和高效率瀏覽體驗的用戶而設計。本文分享了從Chrome轉投Arc的動機、Arc瀏覽器的創新功能以及其侷限和缺點,並提出了對於初期適應問題的看法。對於追求新瀏覽體驗的用戶來說,Arc是一個值得考慮的選擇。
Thumbnail
這篇文章介紹了十五個超讚的Chrome擴充工具,從知識管理、工作效率提升、安全管理、語言學習、設計師工具到開發者工具,讓你的瀏覽體驗提升好多層次。一起挑戰極限,揭開Chrome的神祕面紗,讓生活更加美好燦爛吧!
Thumbnail
這篇文章介紹了十五個超讚的Chrome擴充工具,從知識管理、工作效率提升、安全管理、語言學習、設計師工具到開發者工具,讓你的瀏覽體驗提升好多層次。一起挑戰極限,揭開Chrome的神祕面紗,讓生活更加美好燦爛吧!
Thumbnail
每台Chromebook都有自己的生命周期,只要超過官方規定的使用期限,這台電腦之後就再也接收不到更新。日後網頁能不能正常顯示一切取決於瀏覽器版本有沒有達到要求。 明明電腦一切都正常,卻要因為版本沒有達到需求,就放棄整台電腦?不要忘記,瀏覽網頁是一台電腦最基本的功能之一,這樣做顯然是不合理的。
Thumbnail
每台Chromebook都有自己的生命周期,只要超過官方規定的使用期限,這台電腦之後就再也接收不到更新。日後網頁能不能正常顯示一切取決於瀏覽器版本有沒有達到要求。 明明電腦一切都正常,卻要因為版本沒有達到需求,就放棄整台電腦?不要忘記,瀏覽網頁是一台電腦最基本的功能之一,這樣做顯然是不合理的。
Thumbnail
看到許多人在Liker social 提醒大家記得更新Chrome,避免有漏洞,於是就順便更新了。
Thumbnail
看到許多人在Liker social 提醒大家記得更新Chrome,避免有漏洞,於是就順便更新了。
Thumbnail
為什麼長輩習慣使用自然輸入法? 隨著年紀增長,長期使用電腦眼睛很容易疲勞,尤其在選字的時候,密密麻麻的候選字,眼睛找得好吃力呀👀 別擔心!自然輸入法可以自訂視窗大小,從今以後打字、選字不再吃力❤️
Thumbnail
為什麼長輩習慣使用自然輸入法? 隨著年紀增長,長期使用電腦眼睛很容易疲勞,尤其在選字的時候,密密麻麻的候選字,眼睛找得好吃力呀👀 別擔心!自然輸入法可以自訂視窗大小,從今以後打字、選字不再吃力❤️
Thumbnail
之前我們已經介紹兩個今年Google 新提出的網站性能基準, Largest Contentful Paint 最大內容繪製,和 First Input Delay 首次輸入延遲。這次就看看 Cumulative Layout Shift 累計版面配置轉移。
Thumbnail
之前我們已經介紹兩個今年Google 新提出的網站性能基準, Largest Contentful Paint 最大內容繪製,和 First Input Delay 首次輸入延遲。這次就看看 Cumulative Layout Shift 累計版面配置轉移。
Thumbnail
對大多數人來說,Chrome 79 也就是例行更新的一個版本。 而對我,它修正了一個最近一年多在我心裡佔有一席之地的 bug,我曾經努力試著解決它,最後似乎也找到自己應對它的方法。而現在它要被修掉了,多少有點感觸 😥。
Thumbnail
對大多數人來說,Chrome 79 也就是例行更新的一個版本。 而對我,它修正了一個最近一年多在我心裡佔有一席之地的 bug,我曾經努力試著解決它,最後似乎也找到自己應對它的方法。而現在它要被修掉了,多少有點感觸 😥。
Thumbnail
最近用Google Chrome輸入中文,句子老是不見?來看看有什麼處理方法吧!
Thumbnail
最近用Google Chrome輸入中文,句子老是不見?來看看有什麼處理方法吧!
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News