1px 問(wèn)題指的是:在一些 Retina屏幕 的機(jī)型上,移動(dòng)端頁(yè)面的 1px 會(huì)變得很粗,呈現(xiàn)出不止 1px 的效果。原因很簡(jiǎn)單——CSS 中的 1px 并不能和移動(dòng)設(shè)備上的 1px 劃等號(hào)。它們之間的比例關(guān)系有一個(gè)專門的屬性來(lái)描述:
打開(kāi) Chrome 瀏覽器,啟動(dòng)移動(dòng)端調(diào)試模式,在控制臺(tái)去輸出這個(gè) devicePixelRatio 的值。這里選中 iPhone6/7/8 這系列的機(jī)型,輸出的結(jié)果就是2:
這就意味著設(shè)置的 1px CSS 像素,在這個(gè)設(shè)備上實(shí)際會(huì)用 2 個(gè)物理像素單元來(lái)進(jìn)行渲染,所以實(shí)際看到的一定會(huì)比 1px 粗一些。 解決1px 問(wèn)題的三種思路:
思路一:直接寫 0.5px
如果之前 1px 的樣式這樣寫:
可以先在 JS 中拿到 window.devicePixelRatio 的值,然后把這個(gè)值通過(guò) JSX 或者模板語(yǔ)法給到 CSS 的 data 里,達(dá)到這樣的效果(這里用 JSX 語(yǔ)法做示范):
然后就可以在 CSS 中用屬性選擇器來(lái)命中 devicePixelRatio 為某一值的情況,比如說(shuō)這里嘗試命中 devicePixelRatio 為2的情況:
直接把 1px 改成 1/devicePixelRatio 后的值,這是目前為止最簡(jiǎn)單的一種方法。這種方法的缺陷在于兼容性不行,IOS 系統(tǒng)需要8及以上的版本,安卓系統(tǒng)則直接不兼容。
思路二:偽元素先放大后縮小
這個(gè)方法的可行性會(huì)更高,兼容性也更好。唯一的缺點(diǎn)是代碼會(huì)變多。
思路是先放大、后縮小:在目標(biāo)元素的后面追加一個(gè) ::after 偽元素,讓這個(gè)元素布局為 absolute 之后、整個(gè)伸展開(kāi)鋪在目標(biāo)元素上,然后把它的寬和高都設(shè)置為目標(biāo)元素的兩倍,border值設(shè)為 1px。接著借助 CSS 動(dòng)畫特效中的放縮能力,把整個(gè)偽元素縮小為原來(lái)的 50%。此時(shí),偽元素的寬高剛好可以和原有的目標(biāo)元素對(duì)齊,而 border 也縮小為了 1px 的二分之一,間接地實(shí)現(xiàn)了 0.5px 的效果。
代碼如下:
思路三:viewport 縮放來(lái)解決