在移動端開發時,經常會遇到在視網膜螢幕中元素邊框變粗的問題。本文將帶你探討邊框變粗問題的產生原因及介紹目前市面上最好的解決方法。
1px 邊框問題的由來
蘋果 iPhone4 首次提出了 Retina Display(視網膜螢幕)的概念,在 iPhone4 使用的視網膜螢幕中,把 2x2 個畫素當 1 個物理畫素使用,即使用 2x2 個畫素顯示原來 1 個物理畫素顯示的內容,從而讓 UI 顯示更精緻清晰,這 2x2 個畫素叫做邏輯畫素。像這種畫素比(畫素比(即dpr)= 物理畫素 / 邏輯畫素)為 2 的視網膜螢幕也被稱為二倍屏,目前市面上還有畫素比更高的三倍屏、四倍屏。而 CSS 中 1px 指的是物理畫素,因此,設定為 1px 的邊框在 dpr = 2 的視網膜螢幕中實際佔用了 2 個邏輯畫素的寬度,這就導致了介面邊框變粗的視覺體驗。
使用 transform 解決
通過設定元素的 box-sizing 為 border-box,然後構建偽元素,再使用 CSS3 的 transform 縮放,這是目前市面上最受推崇的解決方法。這種方法可以滿足所有的場景,而且修改靈活,唯一的缺陷是,對於已使用偽元素的元素要多巢狀一個無用元素。具體的實現如下:
.one-pixel-border {
position: relative;
box-sizing: border-box;
}
.one-pixel-border::before {
display: block;
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 200%;
height: 200%;
border: 1px solid red;
transform: translate(-50%, -50%) scale(0.5, 0.5);
}
這樣就可以得到 0.5px 的邊框。
還可以結合媒體查詢(@media)解決不同 dpr 值螢幕的邊框問題,如下:
@media screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {
...
}
@media screen and (-webkit-min-device-pixel-ratio: 3), (min-resolution: 3dppx) {
...
}
注意:IOS 系統的 safari 瀏覽器不支援標準的 min-resolution,使用非標準的 min-device-pixel-ratio。
使用 pixel-border.css 解決
pixel-border.css是一個解決移動端 1px 邊框的通用 CSS 工具。使用 transform 的解決方法,僅有幾行的原始碼,使用起來非常方便,是目前發現最好的解決方法。
安裝
npm安裝:
npm install pixel-border --save
yarn安裝:
yarn add pixel-border
瀏覽器安裝,建議安裝壓縮後的版本:
<link rel="stylesheet" href="path/to/pixel-border.min.css"><link>
使用
pixel-border 通過元素的 ::before 偽元素使用 transform 縮放為元素設定邊框。因此,你可以使用原生的 CSS 邊框屬性為原素設定邊框,只需要在元素上新增一個 pixel-border 或 pixel-border="true" 的屬性,並設定元素的 border-style 值即可。如下會建立一個單畫素邊框:
<div pixel-border style="border-style: solid;">單畫素邊框</div>
注意:pixel-border已為元素的邊框設定為固定值 1px,因此不要為元素再設定 border-width,並且元素的 box-sizing 值被設定為 border-box,請不要重置為其他型別的值。
設定任意邊框:
設定元素某一邊的邊框時,只需為元素設定 border-top-style、border-bottom-style、border-left-style、border-right-style 其中一項的值,並設定元素 border-color 的值即可。如下設定上邊邊框:
<style>
.border-top {
border-top-style: solid;
border-top-color: red;
}
</style>
<div class="border-top" pixel-border>上邊框</div>
設定圓角邊框:
當需要圓角邊框時,始終為 border-radius 設定百分比值。如下:
<style>
.border-radius {
width: 100px;
height: 100px;
border-style: solid;
border-color: red;
border-radius: 10%;
}
</style>
<div class="border-radius" pixel-border>圓角邊框</div>