移動端1px誤差的原因以及解決方案
為什麼移動端css裡面寫了1px, 實際看起來比1px粗. 其實原因很好理解:這2個’px’的含義是不一樣的. 移動端html的header總會有一句
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
這句話定義了本頁面的viewport的寬度為裝置寬度,初始縮放值和最大縮放值都為1,並禁止了使用者縮放。
手機存在一個能完美適配的理想viewport, 解析度相差很大的手機的理想viewport的寬度可能是一樣的, 這樣做的目的是為了保證同樣的css在不同螢幕下的顯示效果是一致的, viewport的好處就在於一套css可以適配多個機型。
在window物件中有一個devicePixelRatio屬性,他可以反應css中的畫素與裝置的畫素比。然而1px在不同的移動裝置上都等於這個移動裝置的1px,這是因為不同的移動裝置有不同的畫素密度。有關這個屬性,它的官方的定義為:裝置物理畫素和裝置獨立畫素的比例,也就是
devicePixelRatio = 物理畫素 / 獨立畫素
1px變粗的原因: viewport的設定和螢幕物理解析度是按比例而不是相同的. 移動端window物件有個devicePixelRatio屬性, 它表示裝置物理畫素和css畫素的比例, 在retina屏的iphone手機上, 這個值為2或3, css裡寫的1px長度對映到物理畫素上就有2px或3px那麼長。
解決方案
1.rem解決:
////根據螢幕大小及dpi調整縮放和大小
(function () {
var scale = 1.0;
var ratio = 1;
if (window.devicePixelRatio >= 2) {
scale *= 0.5;
ratio *= 2;
}
var text = '<meta name="viewport" content="initial-scale=' + scale + ', maximum-scale=' + scale + ',' + ' minimum-scale=' + scale + ', width=device-width,' + ' user-scalable=no" />
';
document.write(text);
document.documentElement.style.fontSize = 50 * ratio + "px";
})();
2.flexible.js
這是淘寶移動端採取的方案, github的地址:https://github.com/amfe/lib-flexible. 前面已經說過1px變粗的原因就在於一刀切的設定viewport寬度, 如果能把viewport寬度設定為實際的裝置物理寬度, css裡的1px不就等於實際1px長了麼. flexible.js就是這樣乾的。
<meta name=”viewport”>
裡面的scale值指的是對ideal viewport的縮放, flexible.js檢測到IOS機型, 會算出scale = 1/devicePixelRatio, 然後設定viewport
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
3.偽類+transform實現
對於解決1px邊框問題,我個人覺得最完美的解決辦法還是偽類+transform比較好。
原理:是把原先元素的 border 去掉,然後利用 :before 或者 :after 重做 border ,並 transform 的 scale 縮小一半,原先的元素相對定位,新做的 border 絕對定位
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
<div class="box-shadow-1px scale">box-shadow-1px</div>
<style>
.box-shadow-1px {
height: 200px;
width: 200px;
text-align: center;
}
.scale{
position: relative;
margin-bottom: 20px;
border:none;
}
.scale:after{
content: '';
position: absolute;
top: 0;
left: 0;
border: 1px solid #000;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 200%;
height: 200%;
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: left top;
transform-origin: left top;
}
</style>
<script>
console.log(typeof ('a'+1))
</script>
</body>
</html>
相關文章
- 移動端1px解決方案
- 移動端高清屏 1px 解決方案
- 解決移動端1px Border
- 設計方案--移動端延遲300ms的原因以及解決方案
- 7 種方案解決移動端1px邊框的問題
- 移動 web 1px 邊框解決方案Web
- 適配移動端的問題以及解決方案
- 目前解決移動端1px邊框最好的方法
- Retina 屏移動裝置 1px解決方案
- 完美解決fixed在手機端的bug和移動端1px寬度
- 跨域的原因以及解決方案跨域
- 移動端滾動穿透解決方案穿透
- 移動端事件穿透的原理與解決方案事件穿透
- 移動端canvas不支援rem的解決方案CanvasREM
- 移動端滾動穿透問題解決方案穿透
- latex 錯誤以及解決方案
- 移動端實現1px的邊框
- JavaScript精度丟失原因以及解決方案JavaScript
- 移動端適配問題解決方案
- SVG圖片在移動端的應用解決方案SVG
- 移動端滾動穿透問題完美解決方案穿透
- 移動端swiper嵌iframe無法滑動的解決方案
- 移動端點透問題及其解決方案
- 1px邊框解決方案總結
- hotcss.js------移動端佈局優秀的解決方案CSSJS
- 移動端ios:active偽類無效的相容解決方案iOS
- Redis 快取擊穿、穿透、雪崩的原因以及解決方案Redis快取穿透
- 移動端常見相容性問題解決方案
- Vue.js 移動端適配之 vw 解決方案Vue.js
- 移動端深度編輯產品技術解決方案
- 解決移動端滾動穿透穿透
- h5移動端常見的問題及解決方案H5
- 移動端圖片上傳旋轉、壓縮的解決方案
- vue移動端的自適應佈局的兩種解決方案Vue
- vue移動端h5適配解決方案(rem or vw)VueH5REM
- 移動端web自適應適配佈局解決方案Web
- 移動端H5頁面生成圖片解決方案H5
- 深入理解移動端適配與探究其解決方案