為什麼你永遠不應該在CSS中使用px來設定字型大小

前端小智發表於2023-04-10

image.png

本文首發於微信公眾號:大遷世界, 我的微信:qq449245884,我會第一時間和你分享前端行業趨勢,學習途徑等等。
更多開源作品請看 GitHub https://github.com/qq449245884/xiaozhi ,包含一線大廠面試完整考點、資料以及我的系列文章。

程式碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug

在Josh Collinsworth的部落格文章“永遠不要用px作為字型大小”中,作者討論了為什麼不應該使用畫素(px)作為網頁字型大小的單位[1]。作者指出,相對於容器、瀏覽器或使用者的字型大小,px值是靜態的。無論使用者的字型偏好設定如何,當我們以靜態畫素設定值時,它將覆蓋使用者的選擇,以我們指定的確切值替代。這意味著,如果我wu7的樣式表使用畫素單位,可能導致訪問網站的使用者難以閱讀。

因此,作者建議使用相對單位,如em、rem或百分比,而不是畫素。這些單位是基於使用者的字型大小偏好設定進行縮放的,從而提供了更好的可訪問性和可讀性。尤其是在設計響應式網站時,相對單位能夠提高跨裝置的相容性。透過使用相對單位,設計師可以確保網站在不同裝置和瀏覽器中以合適的字型大小顯示[1]。

下面是正文:

在 Web 開發領域中,有很多誤解流傳,即使它們被反駁了很多次也仍然存在。"外部連結應該總是在新標籤頁中開啟" 就是一個很好的例子。CSS Tricks 在將近十年前就對此進行了詳細的解釋(簡而言之:大多數情況下是錯誤的),但它似乎仍然在某些角落中存在。

案例證明:在CSS中, pxemrem 單位之間沒有功能上的區別的想法是一個我一遍又一遍聽到的誤解,因此我想在這裡發帖來解決這個問題。

我們要非常清楚:在CSS中使用的單位絕對很重要。並且在設定時 font-size 應儘可能避免使用 px

我們在談論什麼單位,它們是做什麼的?

在我們討論為什麼應該避免使用 px 作為 font-size 之前,讓我們確保我們都清楚我們正在談論哪些單位,以及它們的一般行為。

px

px 是畫素的縮寫……雖然現在大多數情況下它不再是一個真正的畫素。在顯示器通常是一個相對可預測的低解析度畫素比例,比如1024×768的時代, 1px 通常等於螢幕上的一個實際畫素。

螢幕使用稱為畫素的彩色光點陣來顯示影像。一個畫素是顯示器上的一個彩色光點;硬體能夠呈現的最小可能的“點”。這就是我在本節中所說的“字面上的”、“實際的”或“裝置”畫素;物理世界中的一個畫素。

然而,當高解析度(有時稱為“視網膜”)螢幕出現時,裝置開始將更多的畫素壓縮到更小的空間中,這些物理裝置畫素變得非常微小。在高解析度螢幕上瀏覽網頁,如果CSS中的 1px 仍然對應於一個字面裝置畫素,那麼甚至閱讀任何內容都將非常困難,因為畫素本身正在迅速縮小。畢竟,現代智慧手機的解析度甚至比高畫質電視還要高。

所以現在, 1px 通常對應於放大的“縮放”畫素的大小,而不是實際硬體上的字面畫素。在我們的 CSS 中, 1px 的東西可能會佔用多個物理硬體畫素,而我們沒有任何純 CSS 的方法來指定一個字面裝置畫素。但這沒關係,因為它們通常太小了,我們不想去處理它們。

一個例子:iPhone 14 Pro 上的畫素非常微小,16px 在字面上的裝置畫素大小大約相當於2pt字號的印刷字型大小。好在瀏覽器為我們縮放了它們!

大多數情況下,這些並不在本討論的語境中真正重要,但我認為了解這些還是很好的。重要的部分是: 1px 等於瀏覽器視為單個畫素的任何內容(即使在硬體螢幕上它不是真正的畫素)。

em 和 rem

這就帶我們來到了 emrem ,它們彼此相似。繼續講述不嚴格相關但仍然有趣的小知識: "em" 是一個排版術語,實際上比計算機早了幾十年。在排版上,一個 em 等於當前字型大小。

如果你將字型大小設定為 32pt(“pt”是另一個仍然有時使用的舊排版術語),那麼 1em 就是32pt。如果當前字型大小為 20px ,那麼 1em = 20px

在網頁上,預設字型大小為 16px 。一些使用者從不更改預設設定,但許多人會更改。但預設情況下, 1em1rem 都將等於 16px 。

“Em” 最初是指 “M” 字元的寬度,這也是名稱的由來。但現在它指的是當前字型大小,而不是特定字形的尺寸。

EM 和 REM 之間的區別

為了區分這兩者: 1rem 始終等於瀏覽器的字型大小,或者更準確地說是 html 元素的字型大小。 rem 代表“根em”,而網頁的根是 <html> 標籤。因此, 1rem = document 字型大小。(預設情況下,這是 16px ,但可以被使用者覆蓋。)

另一方面,em是當前元素的字型大小。看下面的CSS:

.container {
  font-size: 200%;
}

p {
  font-size: 1em;
}

考慮到上述 CSS, .container 元素內的段落將會變成原來的兩倍大小。這是因為 1em 表示“當前字型大小”,在 .container 內,它是200%1em × 200% = 2em (預設為 32px )。

然而, .container 元素外的段落仍將是 1em 的正常字型大小(預設為 16px )。

如果我們在上面的CSS中將 em 更改為 rem ,那麼所有段落標籤的字型大小將始終是瀏覽器的預設大小,無論它們在哪裡。

font-size: 1em 等同於 font-size: 100% 。
em 和 % 單位在其他情況下並不總是等價的;例如, width: 1emwidth: 100% 很可能會非常不同,因為此時百分比是基於父容器的寬度而不是其字型大小。但是,就 font-size 屬性而言, %em 是相同的。

總結一下:

  • 1em 是當前元素的字型大小。
  • 1rem (根em)是文件的字型大小(即瀏覽器的字型大小)。

好的,那就是單位的含義和來源。現在讓我們回答為什麼使用哪個單位很重要。

為什麼這一切都很重要

再次強調的誤解是:既然 1em16px 相等,那麼選擇哪個單位並不重要。這似乎是合理的;如果 16px = 1rem ,那麼選擇哪種方式輸入似乎並不重要。

記住, emrem 是相對的;預設情況下,它們都(最終)基於瀏覽器的字型大小。

2rem 是瀏覽器字型大小的兩倍; 0.5rem 是其一半,依此類推。因此,如果使用者更改其首選字型大小,如果使用 emrem ,則網站上的所有文字都會相應更改,就像應該的那樣。 2rem 仍然是該字型大小的兩倍; 0.5rem 仍然是其一半。

相比之下, px 值是靜態的。無論容器、瀏覽器或使用者的字型大小如何, 20px 只是 20px 。當設定靜態畫素值時,無論使用者的字型偏好大小如何,它都會覆蓋該選擇並使用指定的確切值。

批判性地說,這意味著如果你的樣式表使用 px 在任何地方設定 font-size ,那麼基於該值的任何文字都將無法由使用者更改。

那是非常糟糕的事情。它是不可訪問的,甚至可能會阻止某人完全使用該網站。

因此,雖然可能存在一些有效的用例來解釋這種行為,但它絕對不是你想要的預設行為。

這也是避免使用視口單位(如 vw 或 vh )設定字型大小的非常好的理由。它們也是靜態的,使用者無法覆蓋。
最多,像 calc(1rem + 1vw) 這樣的值可能是可以接受的,因為它仍然包含 rem 作為基礎。即便如此,我仍建議使用 clamp() 或媒體查詢來設定最小和最大值,因為螢幕尺寸往往遠遠超出我們所期望或測試的範圍。

超出字型大小的差異

好的,現在讓我們談談當我們不特別處理 font-size 屬性時, px em / rem 如何變化。

開發人員通常透過縮放頁面來進行測試,我認為這就是本文中心誤解的來源。當你縮放時,所有內容都會被縮放(放大或縮小),在這種情況下,選擇 pxem / rem 作為你的CSS單位通常並不重要。就縮放而言,兩者的行為方式相同。而且,大多數視力良好的開發人員可能不會意識到其中還有更多內容。然而,棘手的問題是:

即使超出 font-sizepx 的行為也與 emrem 不同。

px 單位仍然與螢幕上畫素的縮放值相關聯。 emrem 與文件的字型大小相關聯,而不是頁面的縮放或比例。

為了演示,請看這個 CodePen:

https://codepen.io/collinsworth/pen/WNyvvqY

HTML CSSResult Skip Results Iframe
EDIT ON
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nam eum aliquam eveniet.</p>
<p>Sapiente delectus in ab excepturi, commodi placeat quaerat saepe voluptas sunt numquam.</p>
<p>Rerum veniam, quidem voluptatibus deleniti nihil consequatur blanditiis explicabo eum quos. Nam.</p>
<p>Natus necessitatibus delectus neque tenetur sint illum obcaecati similique sequi doloribus eligendi?</p>
<p>Eos quidem iure debitis dolorum repellendus ab incidunt ipsam suscipit, autem consequuntur?</p>
p {
  border-bottom: 2px solid black;
  margin-top: 0;
  margin-bottom: 20px;
}

我們有幾個段落,每個段落底部有 2px 邊框,並且它們之間有 20px 邊距。請注意,我們對兩者都使用 px 單位。

如果你放大或縮小,元素的大小和距離保持相對不變。也就是說:你放大得越多,那條線就越粗,段落之間的間距就越大。

為了方便起見,這裡有一張截圖,顯示了同一支筆的400%縮放。文字、線條和間距都變大了4倍;它們相對於彼此的大小保持不變:

image.png

當涉及到縮放時, pxemrem 之間沒有真正的區別。但縮放並不是使用者使網站更易用的唯一方法。

如前所述,使用者還可以指定預設和/或最小字型大小。當他們這樣做時,功能開始分歧。

在下面的截圖中,我已將Firefox的預設字型大小設定為 64px 。看一下:

image.png

將螢幕截圖中的文字與其上方的文字進行比較。請注意,這一次,行並沒有變粗,段落之間的邊距也沒有成比例增加。只有文字本身變大了。因為邊框寬度和邊距都是在 px 中設定的,它們保持不變,不會縮放。

但是請注意,如果將CSS中的 px 更改為相應的 rem 值,會發現線條和間距確實變大了! (zh-Hans)

image.png

所以,這裡的總結是:

  • 當使用者更改字型大小時, px 值不會縮放。
  • em 和 rem 的值會隨字型大小成比例調整。

如果你想要一個互動式演示,將所有這些內容聯絡在一起,請檢視最終的 CodePen;調整頂部的滑塊以檢視修改文件字型大小對各種元素的影響,基於它們使用的 CSS 單位。
https://codepen.io/collinsworth/pen/KKepeMQ

選擇哪一個

因此,知道 emrem 會隨字型大小縮放,但 px 值不會,那麼我們該怎麼辦?我們應該永遠不使用 px 嗎?

雖然我認為如果你選擇這條路,你可能會沒事,但我仍然認為 px 有其存在的意義。

我們知道當使用者調整字型大小時 px 值不會改變,這意味著畫素單位實際上是某些美學元素的不錯選擇。也許我們有一定的間距,我們不希望在字型大小變大時變得更大。(如果預設情況下是一個大塊的負空間,也許允許它縮放到更大的尺寸是沒有意義的。)

也許有一些邊框大小我們不想改變,或者頁面上有用 CSS 建立的裝飾元素,在更大的字型大小下看起來效果不佳。也許我們不希望填充隨著字型大小的增加而膨脹。在所有這些情況下, px 仍然是一個不錯的選擇。

我個人建議使用 rem 來設定所有的大小。我只在想要與當前字型大小成比例的東西(例如,與一些文字旁邊的圖示應該與字元的高度完全相同,並且在一側有半個字元的情況)中新增 em 。我不會在任何地方使用 px ,除非是明確不想隨字型大小縮放的設計元素。

永遠不要用 px 單位中設定 font-size ,除非你非常確定你在做什麼,它會如何行動,以及在你這樣做時它是否仍然可訪問。

關於媒體查詢的重要說明

出於與上述所有原因相同的原因,重要的是要避免在 @media 查詢中使用 px ;當使用者縮放時,它將正常工作,但是使用 px 的媒體查詢將在使用者自己設定更大的字型大小時失敗。

@media (min-width: 800px) {
  /* Changing font size does NOT affect this breakpoint */
}

@media (min-width: 50rem) {
  /* Changing font size DOES affect this breakpoint */
}

這是因為隨著字型大小的增加, 50rem 會根據使用者的偏好變成不同的值,而 800px 則不會。

很可能,當我們為較大的斷點編寫CSS時,我們認為有足夠的螢幕空間讓元素擴充套件。如果使用者設定了非常大的字型大小,則可能不是這種情況,將媒體查詢設定為 rem 而不是 px 可以幫助我們避免這種假設並響應使用者的偏好。

我在這個網站上遇到了這個問題;我把所有的斷點都設定在 px 上。然而,當我將預設字型大小設定得更大時,我的媒體查詢沒有響應,因為它們仍然只檢視螢幕的畫素寬度。因此,我仍然有一個微小的側邊欄,裡面塞滿了難以辨認的巨大文字,因為我沒有考慮使用者的偏好。在那之後,我立即改為 rem ,問題得到了解決。

簡而言之:在媒體查詢中,除非您確定自己知道在瀏覽器中設定自己的字型大小會對使用者產生什麼影響,否則一定要避免使用 px

原文:https://joshcollinsworth.com/blog/never-use-px-for-font-size

交流

有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

相關文章