移动端Retina屏边框线1px 显示为2px或3px问题解决方法
我们在开发移动端web项目时经常遇到设置border:1px,但是显示的边框却为2px或是3px粗细,这是因为设备像素比devicePixelRatio为2或3引起的。
1、何为“设备像素比devicePixelRatio”
设备上物理像素和设备独立像素(device-independent pixels (dips))的比例。
公式表示就是:window.devicePixelRatio = 物理像素 / dips dip或dp,(device independent pixels,设备独立像素)与屏幕密度有关。dip可以用来辅助区分视网膜设备还是非视网膜设备。
所有非视网膜屏幕的iphone在垂直的时候,宽度为320物理像素。当你使用<meta name="viewport" content="width=device-width">
的时候,会设置视窗布局宽度(不同于视觉区域宽度,不放大显示情况下,两者大小一致,见下图)为320px, 于是,页面很自然地覆盖在屏幕上。这样,非视网膜屏幕的iphone上,屏幕物理像素320像素,独立像素也是320像素,因此,window.devicePixelRatio
等于1
.
而对于视网膜屏幕的iphone,如iphone4s, 纵向显示的时候,屏幕物理像素640像素。同样,当用户设置
这样,在视网膜屏幕的iphone上,屏幕物理像素640像素,独立像素还是320像素,因此,
<meta name="viewport" content="width=device-width">
的时候,其视区宽度并不是640像素,而是320像素,这是为了有更好的阅读体验 – 更合适的文字大小。这样,在视网膜屏幕的iphone上,屏幕物理像素640像素,独立像素还是320像素,因此,
window.devicePixelRatio
等于2
.每个像素点实际上有4倍的普通像素点,如下示意(© smashingmagazine):
1个CSS像素点实际上有4个位图像素点,1个分成4个,显然不够分啊,只能颜色近似选取,于是,图片感觉就是模糊的(© smashingmagazine)!。这就是为什么使用两倍图。
视网膜屏幕下图片就显示OK了(非视网膜屏幕图片被压缩-减少像素取样——资源浪费!)
2、各“设备像素比”对应的设备
-webkit-min-device-pixel-ratio为1.0
- 所有非Retina的Mac
- 所有非Retina的iOS设备
- Acer Iconia A500
- Samsung Galaxy Tab 10.1
- Samsung Galaxy S
-webkit-min-device-pixel-ratio为1.3
- Google Nexus 7
-webkit-min-device-pixel-ratio为1.5
- Google Nexus S
- Samsung Galaxy S II
- HTC Desire
- HTC Desire HD
- HTC Incredible S
- HTC Velocity
- HTC Sensation
-webkit-min-device-pixel-ratio为2.0
- iPhone 4
- iPhone 4S
- iPhone 5
- iPad (3rd generation)
- iPad 4
- 所有Retina displays 的MAC
- Google Galaxy Nexus
- Google Nexus 4
- Google Nexus 10
- Samsung Galaxy S III
- Samsung Galaxy Note II
- Sony Xperia S
- HTC One X
-webkit-min-device-pixel-ratio为3.0
- iPhone 6 plus
- iPhone 6s plus
3、javascript获取“设备像素比”
document.getElementById("button").onclick = function() {
alert(window.devicePixelRatio);
};
alert(window.devicePixelRatio);
};
4、Demo实例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>移动设备的1px边框(默认1px的线太粗,用背景模拟)</title> <style> .bordercase,.borderbottom,.borderright{ border: 1px solid #000; } h1{font-size: 15px;} a.bt{display: inline-block;height:30px; red;color: #fff;} .borderbottom{#fff;font-size: 15px;} @media (-webkit-min-device-pixel-ratio: 2){ .borderbottom { border: none; background-image: -webkit-gradient(linear,left top,left bottom,color-stop(50%,transparent),color-stop(50%,#000000),color-stop(100%,#000000)); background-image: -webkit-linear-gradient(top,transparent 50%,#000000 50%,#000000 100%); background-image: linear-gradient(to bottom,transparent 50%,#000000 50%,#000000 100%); background-size: 100% 1px; background-repeat: no-repeat; background-position: bottom; } @media (-webkit-min-device-pixel-ratio: 2){ .borderright { border: none; background-image: -webkit-gradient(linear,left top,right top,color-stop(50%,transparent),color-stop(50%,#000000),color-stop(100%,#000000)); background-image: -webkit-linear-gradient(left,transparent 50%,#000000 50%,#000000 100%); background-image: linear-gradient(to right,transparent 50%,#000000 50%,#000000 100%); background-size: 1px 100%; background-repeat: no-repeat; background-position: right; } @media (-webkit-min-device-pixel-ratio: 3){ .borderbottom { border: none; background-image: -webkit-gradient(linear,left top,left bottom,color-stop(65%,transparent),color-stop(65%,#000000),color-stop(100%,#000000)); background-image: -webkit-linear-gradient(top,transparent 65%,#000000 65%,#000000 100%); background-image: linear-gradient(to bottom,transparent 65%,#000000 65%,#000000 100%); background-size: 100% 1px; background-repeat: no-repeat; background-position: bottom; } } </style> </head> <body> <ul> <li> <h1>问题:border:1px,在手机设备上是2px或是3px,Why??? </h1> <div class="bordercase">为什么我的边框那么大? 说好的1像素呢??? 瞬间各种不爱了。。。。。。 .bordercase{border: 1px solid #000;}</div> </li> <li><h1>1、何为“设备像素比devicePixelRatio”</h1> <p>设备上物理像素和设备独立像素(device-independent pixels (dips))的比例。公式表示就是:window.devicePixelRatio = 物理像素 / dips dip或dp,(device independent pixels,设备独立像素)与屏幕密度有关。dip可以用来辅助区分视网膜设备还是非视网膜设备。</p> </li> <li> <h1>2、“Retina”屏呈像原理</h1> <img src="page1.png" height="284" width="500" /> <img src="page2.png" height="168" width="500"/> </li> <li><h1>3、获取设备的devicePixelRatio(开启Chrome浏览器可以看到各种类型设备的像素比)</h1> <a class="bt" id="bt" onclick="alert(window.devicePixelRatio);">点击我查看设备的devicePixelRatio</a> </li><li><h1>4、解决方法(通过背景模拟边框线,把1px一分为二)</h1> <a class="bt" href='https://jsfiddle.net/starrycheng/6ndbw6ax/1/'" target="_blank">jsfiddle地址</a> <div class="borderbottom">看我下边框(在手机上才能看到我,在模拟器里有时候是看不到的。)</div> <br/> <br/> <br/> <div class="borderright">看我右边框(在手机上才能看到我,在模拟器里有时候是看不到的。)</div> <br/> <br/> <br/> <br/> <div> <br/> 我的代码样式代码 <br/> @media (-webkit-min-device-pixel-ratio: 2){ <br/> .borderbottom { border: none;(定义元素无边框) <br/> background-image: -webkit-gradient(linear,left top,left bottom,color-stop(50%,transparent),color-stop(50%,#000000),color-stop(100%,#000000));(//-webkit老式语法书写规则:线性渐变,从中间到下,颜色逐渐加深。50%从中间开始。从透明效果开始。) <br/> background-image: -webkit-linear-gradient(top,transparent 50%,#000000 50%,#000000 100%);(//-webkit最新发布书写语法:线性渐变,从中间到下,颜色逐渐加深。50%从中间开始。从透明效果开始。) <br/> background-image: linear-gradient(to bottom,transparent 50%,#000000 50%,#000000 100%);(//HTML5标准写法:线性渐变,从中间到下,颜色逐渐加深。50%从中间开始。从透明效果开始。) <br/> background-size: 100% 1px;(背景大小1像素,100%的宽度) <br/> background-repeat: no-repeat;(不重复) <br/> background-position: bottom;(背景出现位置) }}</div> </li> </ul> </body> </html>
各位大神还有什么其它的解决方案欢迎讨论,谢谢。