解決移動(dòng)端1px在一些屏幕會(huì)變粗的原因
一绑警、起因
為什么移動(dòng)端css里面寫了1px, 實(shí)際看起來比1px粗. 其實(shí)原因很好理解:這2個(gè)’px’ 的含義是不一樣的. 移動(dòng)端 html 的 header 總會(huì)有一句
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
這句話定義了本頁面的 viewport 的寬度為設(shè)備寬度,初始縮放值和最大縮放值都為1,并禁止了用戶縮放. viewport 通俗的講是瀏覽器上可用來顯示頁面的區(qū)域, 這個(gè)區(qū)域是可能比屏幕大的场靴。
首先跌宛,我們了解devicePixelRatio這個(gè)東西
在window對(duì)象中有一個(gè)devicePixelRatio屬性,他可以反應(yīng)css中的像素與設(shè)備的像素比缠局。然而1px在不同的移動(dòng)設(shè)備上都等于這個(gè)移動(dòng)設(shè)備的1px拙毫,這是因?yàn)椴煌囊苿?dòng)設(shè)備有不同的像素密度。有關(guān)這個(gè)屬性迟杂,它的官方的定義為:設(shè)備物理像素和設(shè)備獨(dú)立像素的比例刽沾,也就是
devicePixelRatio = 物理像素 / 獨(dú)立像素 1px變粗的原因:
viewport的設(shè)置和屏幕物理分辨率是按比例而不是相同的. 移動(dòng)端window對(duì)象有個(gè)devicePixelRatio屬性,
它表示設(shè)備物理像素和css像素的比例, 在retina屏的iphone手機(jī)上, 這個(gè)值為2或3,
css里寫的1px長(zhǎng)度映射到物理像素上就有2px或3px那么長(zhǎng)
二、終極解決方案
1.用小數(shù)來寫px值 (不推薦)
IOS8下已經(jīng)支持帶小數(shù)的px值, media query 對(duì)應(yīng) devicePixelRatio 有個(gè)查詢值 -webkit-min-device-pixel-ratio, css可以寫成這樣
通過-webkit-min-device-pixel-ratio設(shè)置排拷。
.border { border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border { border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
.border { border: 0.333333px solid #999 }
}
如果使用less/sass的話只是加了1句mixin
缺點(diǎn): 安卓與低版本IOS不適用, 這個(gè)或許是未來的標(biāo)準(zhǔn)寫法, 現(xiàn)在不做指望
2侧漓、flexible.js
這是淘寶移動(dòng)端采取的方案, github的地址:https://github.com/amfe/lib-flexible. 前面已經(jīng)說過1px變粗的原因就在于一刀切的設(shè)置 viewport 寬度, 如果能把 viewport 寬度設(shè)置為實(shí)際的設(shè)備物理寬度, css 里的 1px 不就等于實(shí)際 1px 長(zhǎng)了么. flexible.js 就是這樣干的.
<meta name=”viewport”>里面的 scale 值指的是對(duì) ideal viewport 的縮放, flexible.js 檢測(cè)到 IOS 機(jī)型, 會(huì)算出 scale = 1/devicePixelRatio, 然后設(shè)置viewport
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
devicePixelRatio=2時(shí)輸出meta如下, 這樣viewport與ideal viewport的比是0.5, 也就與設(shè)備物理像素一致
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
3、偽類+transform實(shí)現(xiàn)
對(duì)于解決1px邊框問題监氢,我個(gè)人覺得最完美的解決辦法還是偽類+transform比較好布蔗。
原理:是把原先元素的 border 去掉藤违,然后利用 :before 或者 :after 重做 border ,并 transform 的 scale 縮小一半纵揍,原先的元素相對(duì)定位顿乒,新做的 border 絕對(duì)定位。
參考 https://blog.csdn.net/weixin_43675871/article/details/84023447