rem 產生的小數像素問題

因爲平常需求以無線居多,因此能夠在業務中作一些嘗試,如 rem,剛接觸這個特性的時候,曾經一度愛不釋手,彷彿在無線開發的坎坷路上尋找到一條捷徑。然而隨着使用範圍的擴大,慢慢的發現了一些使用 rem 帶來的問題。

rem

關於 rem 這個單位的介紹,在此就不贅述,有興趣的同窗能夠閱讀一絲的《響應式十日談第一日:使用 rem 設置文字大小》,文章對 rem 進行了詳細的介紹。瀏覽器

用途

在無線開發中,響應式佈局尤其重要,先不說屏幕尺寸愈來愈多樣化的 iPhone,單是安卓就有 N 多種尺寸要適配。佈局

在沒有使用 rem 以前,想要按照設計師的想法去適配不一樣 分辨率1 是一件很是難操做的事情。用了 rem 之後,一切簡單了許多,你能夠用它來設置元素的寬高、間距…,而後針對不一樣的分辨率計算並設置相對應的根字體大小,而後元素就好像縮放過同樣自動適應了當前的分辨率,大大的下降了適配工做量。字體

Demo:設計

上圖是同一個頁面在 Apple iPhone 5 和 Samsung Galaxy S4 兩款機器下的效果,能夠看出從 320px 寬的 iPhone 5 到 360px 寬的 S4,圖片像是等比放大了同樣,咱們分析下這個原理:cdn

假定2 width=320px 的分辨率下的根字體大小是 32px,由此推算:blog

  • width=320px 分辨率下:

根字體大小是 32px,該分辨率下寬 1rem 的元素在瀏覽器裏的真實寬度就是 1 * 32 = 32px;圖片

  • width=360px 分辨率下:

若是要達到等比放大的效果,寬 1rem 的元素在瀏覽器裏的真實寬度就應該是 32 * (360/320) = 36px,由此得出 width=360px 分辨率下的根字體大小爲 36px;開發

因而可知等比縮放是經過控制根字體大小來實現的,且根字體大小與屏幕寬度成正比。rem

小數像素

剛纔舉的例子裏面 1rem 在 width=320px 分辨率下的真實尺寸爲 32px,在 width=360px 分辨率下的真實尺寸爲 36px,均爲整數。文檔

若是是 1.75rem 呢?

表明機型 瀏覽器寬 對應尺寸
iPhone 4/4s/5/5s 320px 56px
Samsung Note 3, Nexus 5… 360px 63px
iPhone 6 375px 65.625px
Google Nexus 6 412px 72.1px
iPhone 6 Plus 414px 72.45px

能夠看到部分機型下出現了小數像素,那麼瀏覽器是如何處理小數像素的呢?

如圖,第一組每一個色塊的大小爲 1.75rem x 1.75rem,第二組每一個色塊的大小爲 1.85rem x 1.85rem;

先看第一組色塊,在 iPhone 6 下,其在瀏覽器內的渲染尺寸應該是 1.75 * 37.5 = 65.625px;

但真實渲染尺寸倒是另一種狀況:有的寬度是 66px,有的倒是 65px,並且順序上毫無規律。

這一結果讓我十分疑惑,若是瀏覽器統一作四捨五入處理,那麼全部的色塊尺寸也應該是同樣的,不會出現部分向上取整,部分向下取整。

思考許久無果,大膽設想了一下:瀏覽器在渲染時所作的舍入處理只是應用在元素的渲染尺寸上,其真實佔據的空間依舊是原始大小。

也就是說若是一個元素尺寸是 0.625px,那麼其渲染尺寸應該是 1px,空出的 0.375px 空間由其臨近的元素填充;一樣道理,若是一個元素尺寸是 0.375px,其渲染尺寸就應該是 0,可是其會佔據臨近元素 0.375px 的空間。因而就順着這個思路驗證瞭如下:

  • 第一個色塊的寬度爲 65.625px,根據四捨五入的原則其最終渲染尺寸爲 66px,空出的 0.375px 由第二個色塊補上;
  • 第二個色塊向左補進 0.375px,至關於減小了 0.375px,餘下 65.25px,根據四捨五入的原則其最終渲染尺寸爲 65px,多出的 0.25px 會佔用第三個色塊的空間;
  • 第三個色塊被佔用了 0.25px,至關於增長了 0.25px,等於 65.875px,根據四捨五入的原則其最終渲染尺寸爲 66px,空出的 0.125px 由第四個色塊補上;
  • 第四個色塊向左補進 0.125px,至關於減小了 0.125px,餘下 65.5px,根據四捨五入的原則其最終渲染尺寸爲 66px,空出的 0.5px 由第五個色塊補上;
  • 第五個色塊向左補進 0.5px,至關於減小了 0.5px,餘下 65.125px,根據四捨五入的原則其最終渲染尺寸爲 65px,多出 0.125px; 上述驗證與瀏覽器輸出結果徹底一致,代表瀏覽器在處理小數像素的時候並非直接舍入處理的,元素依舊佔據着應有的空間,只是在計算元素尺寸的時候作了舍入處理(後來在看到 LayoutUnit – WebKit 這篇文檔後,也印證了以前的假設)。

你能夠參考上述原理對第二組色塊進行驗證,而後比對結果。

問題

目前遇到最多的問題就是 background-image 的問題,常常會由於小數像素致使背景圖被裁掉一部分。

上圖是同一組 icon 在不一樣機型下的效果,能夠看出這些 icon 在 iPhone 5 和 Galaxy S4 下或多或少的會被裁掉一部分,緣由就是因爲小數像素致使的,這點能夠從元素的 Computed Style 上看出。

解決

如何避免這種問題呢?如下兩點建議:

  • 使用 iconfont;
  • 如需使用 background-image,儘可能爲背景圖設置必定的空白間隙,如圖:

小結

小數像素產生的問題不僅僅只有 background-image,還會有其餘還沒有遇到的坑,然而在瞭解了瀏覽器是如何處理小數像素的原理之後,此類問題就變得很好解決,也很是可控。

注:

  • 文中出現的分辨率都是指瀏覽器分辨率,關於邏輯分辨率、物理分辨率之間的關係能夠參考:「像素」「渲染像素」以及「物理像素」是什麼東西?它們有什麼聯繫?;
  • 爲了保證大部分分辨率下計算出的根字體大小都爲整數,因此約定根字體大小的計算公式爲:分辨率寬度 / 10;

轉載地址: fed.taobao.org/blog/2015/1…
相關文章
相關標籤/搜索