[CSS] 彈性化的 Media Query

好像是該來交點作業,不然部落格都快壞掉了(甚至熊熊想不起來 Octporess 要怎麼 deploy 到 Heroku 上

原先是想說要先寫一點 Media Query Level 4 的介紹,不過因為還沒有玩膩所以就先不要寫了(欸,由於寫文章的時候剛好是自己生日,所以,就先祝自己生日快樂。

然後我們聊一下彈性的 Media Query。


前言

導讀,

The EMs have it! Proportional Media Query FTW!

全文完(

其實這篇文章我之前就推過了,但是我不知道有沒有人實際去測試過這件事情。在這邊所謂的彈性化,其實是利用 em 這個對於文字單位的比例,來做到一些看起來很神奇的事情。這篇文章算是心得,所以看得懂英文的人就可以先離開了。

首先,先請教一個數學問題,

16 x 40 = 640
20 x  A = 640
24 x  B = 640

請問 A, B 各為多少?

從基本參考線開始

一般來說,我們在瀏覽器的使用上,預設的基本字型尺寸會是某一個數值,

16px ~= 12pt ~= 1em = 100%

嗯,原文當中寫 16px ~= 14pt 不知道是不是寫錯?我們以 16px 當作一個基準,來編排整個畫面的排版與設計。回歸到一個問題,我們在設計 RWD 時,我們會決定出某幾種尺寸,然後編排版面,然後最後定稿製作。

我們通常會這樣,

@media (min-width: 320px) { ... }
@media (min-width: 600px and max-width: 960px) { ... }

這是我們比較常見的做法,在特定的尺寸上,進行畫面編排上的改變。觸發這個改變的__點__是__尺寸__。這個尺寸是由裝置所告訴我的尺寸,當我們使用 width=device-width 的時候(這也是最常見的設定,我們的 @media 就會得到這樣的尺寸。

所以我們可以很直覺的知道,我們在什麼樣的__尺寸__上,會有什麼樣的結果。

當使用者的基本字型尺寸改變,會發生什麼事情?

內容優先

當一個以內容優先為主的網站,我們以 A book apart 為例子來看看,雖然說你會發現他們並不是使用 em 來當作 Media Query 的單位,但是,只是舉個例子所以別太在意(喂

我們用 Google DevTools 來覆寫我們給 Viewport 的數值,這是一般正常的尺寸 1440x400,這裡請留意一下 font scale factor

Example A book apart

然後我們把 font scale factor 這個數值給放大,

Example A book apart

畫面看起來好像怪怪的,我們稍後再解釋,接著我們把它打直來看,

Example A book apart

接著一樣把 font scale factor 這個數值放大,

Example A book apart

歐耶,好像 往某個奇怪的方向發展惹

問題

  • 畫面長大了,怎麼編排長得很奇怪
  • 字體放大,視覺上版面增大,但是排版沒有改變
  • 版面縮小,字體放大,但是版面沒有改變

盲點

  • Viewport 由原生裝置提供,但改變的為文字尺寸
  • Media Query 使用 pixel 作為單位的問題

華生 (?

由於我們的尺寸是由裝置(從 Chrome DevTools 可以看出,他是固定在某一個尺寸下,所以,對於 Media Query 來說,他會符合某一個條件成立後,所產生的結果。

因為 Media Query 被固定了,所以我們修改了文字尺寸時,並不會對畫面造成影響。

所以,這些結果造成的問題就很明顯,畫面不會因為我們的改變而產生變化,而且由於 viewport 我們預設使用了 device-width,雖然說,整體元素尺寸的寬度有造成改變,但是由於裝置還是告訴他是 1440px(以上面的例子來說,所以 Media Query 在這裡就不會動作。

這是預期的,對吧。

騙局與誤判

那麼,用 em 會有什麼差異?說破嘴不如 跑斷腿 貼張圖,

Example cloudfour

這是最基本的寬螢幕的顯示結果,然後我們來改變 font scale factor 看看會有什麼結果,

Example cloudfour

有沒有發現網站的排版產生了變化?

誤判

我們先來看一張寬度居於中間的排版樣式,

Example cloudfour

接著我們把畫面繼續縮小,直到他出現了 Mobile 的排版樣式,

Example cloudfour

這個時候,我們改變了 font scale factor,他發生了變化,

Example cloudfour

為什麼?

騙局

接著,我們調整瀏覽器預設字體大小,來看看會有什麼變化,首先先來張對照組,

Example cloudfour

接著,我把 Chrome 的預設字體調成非常大

Example cloudfour

再回到網站看看,有看到神奇的東西嗎?

Example cloudfour

那,如果是使用預設字體,而把頁面直接利用 Ctrl/Command + 來放大,又會是如何?

Example cloudfour

見證奇蹟的時刻!

彈性化的作用方式

一整個就是超不好維護的啊!

華生!你突破盲 點了!

我剛剛提起的問題,各位有答案了嗎?

A = 32
B = 26.667

加上單位,我來解釋一下這個簡易的算式,

16px x 20em = 640px
20px x 32em = 640px
24px x 26.67em = 640px

假設我們的 viewport 給我們的數值是 640px 那麼,當字體大小改變的時候,所用到的 em 數值就會不同。所以,這就是 Media Query 使用 em 所帶來的彈性優勢。當我們的基本字體有所不同的時候,所使用的 Media Query 就會不同,意思就是,

/* 當字體大小為 16px 的時候,會使用這個 @media */
@media (min-width: 40em)

/* 當字體大小為 20px 的時候,會使用這個 @media */
@media (min-width: 32em)

/* 當字體大小為 24px 的時候,會使用這個 @media */
@media (min-width: 26.67em)

為什麼這麼做?還記得我們所謂的 Content First 的概念嗎?當我們以文字內容優先的時候,文字的顯示就是最重要的一件事。為了不要在閱讀上造成困難,所以必須以文字大小為基準,來做版面上的調整與安排。

誤判從何而來?

為什麼我們修改了 font scale factor 之後,樣式反而不對了?根據 Chrome DevTools 給我們的解釋,

At present, Font scale factor will only set the text zoom. There are however plans to change this in the future to better emulate mobile devices using text autosizing and real device pixel ratio emulation. Until then, the current state will never be 100% accurate and may exhibit some visual artifacts and unexpected behavior when scaling the page.

阿鬼,你還是說中文吧。

簡單一句話,Chrome DevTools 對於 font scale factor 的調整,是 有可能 對其他的元素造成 無法預期 的錯誤。雖然說他是對文字尺寸上的調整,但是,根據實驗的結果,改變 font scale factor 是會把 Visual Viewport 跟著 放大 或是 縮小

但是,由於網頁的排版還是依照 Actual Viewport 的設定來做調整,那為什麼會誤判?有一個比較合理的解釋,

由於裝置告知的尺寸可能被 font scale factor 縮放,所以裝置可能被放大(依照上述例子 2 倍這樣,但是 Actual Viewport 卻還是保有元素原有的設置方式,所以還是維持原判 1 倍。

所以,這就造成了 Media Query 認為裝置是兩倍大,雖然文字已經放大,但是還是依照比例去找尋符合的 @media

16px x 40em = 640px
32px x 40em = 1280px

由於裝置的 Visual Viewport 被放大,由 640px 變成 1280px,所以就算是 font scale factor 放大兩倍(由 16px 變成了 32px,但是你注意到了嗎,他依舊維持了 40em 這個比例。

所以,這是造成誤判的原因之一( 以上若有雷同,絕對是巧合

到底誰設了騙局?

我們先來看 Firefox, Opera 與 Safari 在同樣字體放大的結果下,會有什麼結果,

Firefox

Example in the Firefox

Safari

Example in the Safari

Opera

Example in the Opera

所以,基本上 Firefox 與 Safari 是正常的,Opera 連最接近的結果都沒有(驚訝,至於 Chrome 為什麼會搞成這樣,這只能問天了(哀怨

小結

基本上,使用 em 搭配文字變化,請還是以 Ctrl/Command + + 來做縮放為準。但是其實,

使用 px 為單位,其實使用 Ctrl/Command + + 也會發生作用

搞毛啊!那這篇不就都廢話!

不信?你去 A book apart 然後多按幾下 Ctrl/Command + + 試試看。但是,如果是文字變化,那麼使用 px 為單位的 Media Query 在這裡就不會有任何改變了。

結論

使用 em 當作 Media Query 的單位,其實有一個相當大的目的,

Content is really king.

依照裝置所提供的文字基準,來對網站的排版作適度的改變,就是使用 em 作為彈性化的 Media Query 最大主因。所以,或許我們可以思考使用 pxem 所帶來的差異性,那一個面向才是你想要的東西。如果你不在意版面對於使用者在閱讀上面的影響,那你可以不用考慮這件事情。

但是,身為一個偽前端工程師,我還是覺得 卡早睡卡有眠(欸 當農夫比較實在(無誤

Hina Chen
偏執與強迫症的患者,算不上是無可救藥,只是我已經遇上我的良醫了。
Taipei