We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
在这里开始前先记录几个概念
设备本身的像素分辨率,比如我的S9的分辨率为2960*1440。
设备独立像素也称为密度无关像素,比如我的S9它1个设备独立像素里面要展示4个物理像素。
CSS像素是一个抽像的单位,主要使用在浏览器上,用来精确度量Web页面上的内容。一般情况之下,CSS像素称为与设备无关的像素
devicePixelRatio,改值等于设备物理像素除以设备独立像素,在浏览器上我们可以通过打印window.devicePixelRatio来获取该值。而在CSS中,可以通过-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio进行媒体查询,对不同dpr的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)
没错,iOS 8以上直接写0.5px可以识别,安卓设备太杂,目前我在我的S9上测试不行,还是按照1px来显示的。
先说方案的原理:把原先元素的 border 去掉,然后利用 ::before 或者 ::after 伪元素重做 border ,并 transform 的 scale 缩小到原来的一半,原先的元素相对定位,新做的 border 绝对定位。
::before
::after
这个方案是我查找的的许多方案里面比较简单的方案了,这里放在首位,而且这个方案在四条边框都存在的情况下支撑圆角,首先这儿先贴出完整的演示代码(这里我先贴只有元素底部设置边框的情况):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Event</title> <style> * { margin: 0; padding: 0; } html, body { width: 100%; height: 100%; background-color: grey; display: flex; justify-content: center; align-items: center; } .outter { width: 300px; height: 300px; background-color: white; display: flex; justify-content: center; align-items: center; } .inner { width: 150px; height: 150px; margin: 10px; padding: 10px; background-color: violet; position: relative; border: none; } /* 一条边设置边框 - 底部 */ .inner::after { content: ''; position: absolute; bottom: 0; left: 0; background: #000; width: 100%; height: 1px; transform: scaleY(0.5); transform-origin: 0 0; } </style> </head> <body> <div class="outter"> <div id="inner" class="inner"></div> </div> <script> console.log(window.devicePixelRatio) </script> </body> </html>
这里有个额外的知识点,transform-origin,参考MDN上的资料就可以了,很好理解,它主要是来规定transform的rotate、translate、scale等这些属性应该在哪个基础点来进行变换。
上面的代码演示了元素底部设置边框,接下来我们修改代码,来分别展示上,左,右的设置方法。
.inner::after { content: ''; position: absolute; top: 0; left: 0; background: #000; width: 100%; height: 1px; transform: scaleY(0.5); transform-origin: 0 0; }
.inner::after { content: ''; position: absolute; top: 0; left: 0; background: #000; width: 1px; height: 100%; transform: scaleX(0.5); transform-origin: 0 0; }
.inner::after { content: ''; position: absolute; top: 0; right: 0; background: #000; width: 1px; height: 100%; transform: scaleX(0.5); transform-origin: 0 0; }
.inner::after { content: ''; position: absolute; top: 0; left: 0; border: 1px solid #000; box-sizing: border-box; width: 200%; height: 200%; transform: scale(0.5); transform-origin: 0 0; }
当你需要设置圆角是(四个边框的情况),在 .inner 和 .inner::after里面都跟上 border-radius即可(注意dpr为2时.inner::after里面的 border-radius 的值为 .inner 里面两倍才行,其它dpr值的情况暂未测试)。
.inner
.inner::after
border-radius
上面演示的是devicePixelRatio为2的情况,目前包括iphone和Android的很多设备都到了3或者4,比如iPhone X的dpr为3,Galaxy S9为4,所以可以用媒体查询来解决。
这里我先贴出阿里的一套方案:
/*Retian 1px border start */ .retinabt, .retinabb, .retinabl, .retinabr, .retinab { position: relative; } .retinabt:before, .retinabb:after { pointer-events: none; position: absolute; content: ""; height: 1px; background: rgba(32, 35, 37, .14); left: 0; right: 0; z-index: 26; } .retinabt:before { top: 0; z-index: 26; } .retinabb:after { bottom: 0; z-index: 26; } .retinabl:before, .retinabr:after { pointer-events: none; position: absolute; content: ""; width: 1px; background: rgba(32, 35, 37, .14); top: 0; bottom: 0 } .retinabl:before { left: 0; z-index: 26; } .retinabr:after { right: 0; z-index: 26; } .retinab:after { position: absolute; content: ""; top: 0; left: 0; -webkit-box-sizing: border-box; box-sizing: border-box; width: 100%; height: 100%; border: 1px solid rgba(32, 35, 37, .14); pointer-events: none; z-index: 26; } @media (-webkit-min-device-pixel-ratio:1.5), (min-device-pixel-ratio:1.5), (min-resolution:144dpi), (min-resolution:1.5dppx) { .retinabt:before, .retinabb:after { -webkit-transform: scaleY(.5); transform: scaleY(.5) } .retinabl:before, .retinabr:after { -webkit-transform: scaleX(.5); transform: scaleX(.5) } .retinab:after { width: 200%; height: 200%; -webkit-transform: scale(.5); transform: scale(.5) } .retinabt:before, .retinabl:before, .retinab:after { -webkit-transform-origin: 0 0; transform-origin: 0 0 } .retinabb:after, .retinabr:after { -webkit-transform-origin: 100% 100%; transform-origin: 100% 100% } } @media (-webkit-device-pixel-ratio:1.5) { .retinabt:before, .retinabb:after { -webkit-transform: scaleY(.6666); transform: scaleY(.6666) } .retinabl:before, .retinabr:after { -webkit-transform: scaleX(.6666); transform: scaleX(.6666) } .retinab:after { width: 150%; height: 150%; -webkit-transform: scale(.6666); transform: scale(.6666) } } @media (-webkit-device-pixel-ratio:3) { .retinabt:before, .retinabb:after { -webkit-transform: scaleY(.3333); transform: scaleY(.3333) } .retinabl:before, .retinabr:after { -webkit-transform: scaleX(.3333); transform: scaleX(.3333) } .retinab:after { width: 300%; height: 300%; -webkit-transform: scale(.3333); transform: scale(.3333) } } @media (-webkit-min-device-pixel-ratio:4), (min-device-pixel-ratio:4) { .retinabt:before, .retinabb:after { -webkit-transform: scaleY(.25); transform: scaleY(.25) } .retinabl:before, .retinabr:after { -webkit-transform: scaleX(.25); transform: scaleX(.25) } .retinab:after { width: 400%; height: 400%; -webkit-transform: scale(.25); transform: scale(.25) } } /*Retina 1px border end */
接下来我贴出自己写的一个,首先是媒体查询部分,这部分可以放到项目的公共部分:
.retina-border-all, .retina-border-top, .retina-border-right, .retina-border-bottom, .retina-border-left { position: relative; } .retina-border-all::after { content: ''; position: absolute; top: 0; left: 0; box-sizing: border-box; transform-origin: 0 0; } .retina-border-top::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 1px; transform-origin: 0 0; } .retina-border-right::after { content: ''; position: absolute; top: 0; right: 0; width: 1px; height: 100%; transform-origin: 0 0; } .retina-border-bottom::after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 1px; transform-origin: 0 0; } .retina-border-left::after { content: ''; position: absolute; top: 0; left: 0; width: 1px; height: 100%; transform-origin: 0 0; } @media (-webkit-device-pixel-ratio: 2) { .retina-border-all::after { width: 200%; height: 200%; transform: scale(0.5); } .retina-border-top::after { transform: scaleY(0.5); } .retina-border-right::after { transform: scaleX(0.5); } .retina-border-bottom::after { transform: scaleY(0.5); } .retina-border-left::after { transform: scaleX(0.5); } } @media (-webkit-device-pixel-ratio: 3) { .retina-border-all::after { width: 300%; height: 300%; transform: scale(0.333333); } .retina-border-top::after { transform: scaleY(0.333333); } .retina-border-right::after { transform: scaleX(0.333333); } .retina-border-bottom::after { transform: scaleY(0.333333); } .retina-border-left::after { transform: scaleX(0.333333); } } @media (-webkit-device-pixel-ratio: 4) { .retina-border-all::after { width: 400%; height: 400%; transform: scale(0.25); } .retina-border-top::after { transform: scaleY(0.25); } .retina-border-right::after { transform: scaleX(0.25); } .retina-border-bottom::after { transform: scaleY(0.25); } .retina-border-left::after { transform: scaleX(0.25); } }
然后是你要设置边框的元素部分的CSS:
.inner { width: 150px; height: 150px; margin: 10px; padding: 10px; background-color: violet; /* 四个边都要边框时并且需要圆角 */ /* border-radius: 10px; */ } .inner::after { /* 四个边都要边框时 */ border: 1px solid #000; /* 四个边都要边框时并且需要圆角 */ /* border-radius: 20px; */ /* 上、右、下、左方需要边框时 */ /* background-color: #000; */ }
HTML部分:
<div class="outter"> <div id="inner" class="inner retina-border-all"></div> </div>
使用Flexible实现手淘H5页面的终端适配
先放代码:
(function(win,doc) {//根据屏幕大小及dpi调整缩放和大小 var scale = 1.0, ratio = 1, dc=doc, viewporttexts=''; if (win.devicePixelRatio && devicePixelRatio >= 1.5) { ratio = devicePixelRatio; scale = scale/(devicePixelRatio); } viewporttexts = ' width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale +', minimum-scale=' + scale + ',user-scalable=no'; doc.querySelector('meta[name="viewport"]').setAttribute("content",viewporttexts); dc.documentElement.style.fontSize =doc.getElementsByTagName("html")[0].style.fontSize=Math.ceil(50*ratio) + "px"; })(window,document);
这个方案写1px的时候不转换rem,然后其他都要转换rem(字体也要写rem单位),上面的基础大小为50px,也就是说,ratio为1时,你的1rem相当于50px,这个在你的转换插件里面把倍率设置为50即可
然后我说一下我测试的结果,目前手头只有S9和iPhone 7(系统为iOS 11),S9的浏览器用的UC,测试我发现,上面这个方案在S9上很完美,看不出异常,然后在IP7上测试四边都设置边框的情况下,左右边框没起到作用,它是按照2px显示的,上下边框没问题,是按1px显示,当我单独设置一边的边框时,显示没有问题(补充:我发现当我左边的不设置边框或者不设置左右边框时,右边的四个边框都显示正常,无解-_-)。下面我贴几张图:
S9
IP7
-IP7-左边不设置边框
7种方法解决移动端Retina屏幕1px边框问题
移动端 Retina屏 各大主流网站1px的解决方案
css中引入svg来兼容部分安卓机显示0.5px边框的示例
The text was updated successfully, but these errors were encountered:
No branches or pull requests
开始
在这里开始前先记录几个概念
1、直接写0.5px(限iOS 8及以上设备)
没错,iOS 8以上直接写0.5px可以识别,安卓设备太杂,目前我在我的S9上测试不行,还是按照1px来显示的。
2、伪类 + transform 的实现
先说方案的原理:把原先元素的 border 去掉,然后利用
::before
或者::after
伪元素重做 border ,并 transform 的 scale 缩小到原来的一半,原先的元素相对定位,新做的 border 绝对定位。这个方案是我查找的的许多方案里面比较简单的方案了,这里放在首位,而且这个方案在四条边框都存在的情况下支撑圆角,首先这儿先贴出完整的演示代码(这里我先贴只有元素底部设置边框的情况):
上面的代码演示了元素底部设置边框,接下来我们修改代码,来分别展示上,左,右的设置方法。
当你需要设置圆角是(四个边框的情况),在
.inner
和.inner::after
里面都跟上border-radius
即可(注意dpr为2时.inner::after
里面的border-radius
的值为.inner
里面两倍才行,其它dpr值的情况暂未测试)。2.1 使用媒体查询实现多设备适配
这里我先贴出阿里的一套方案:
接下来我贴出自己写的一个,首先是媒体查询部分,这部分可以放到项目的公共部分:
然后是你要设置边框的元素部分的CSS:
HTML部分:
3、手淘的方案(这儿直接给链接,这个方案是五年前的了)
4、另一种rem + viewport的方案(等比例放大)
先放代码:
然后我说一下我测试的结果,目前手头只有S9和iPhone 7(系统为iOS 11),S9的浏览器用的UC,测试我发现,上面这个方案在S9上很完美,看不出异常,然后在IP7上测试四边都设置边框的情况下,左右边框没起到作用,它是按照2px显示的,上下边框没问题,是按1px显示,当我单独设置一边的边框时,显示没有问题(补充:我发现当我左边的不设置边框或者不设置左右边框时,右边的四个边框都显示正常,无解-_-)。下面我贴几张图:
S9
IP7
-IP7-左边不设置边框
参考资料
7种方法解决移动端Retina屏幕1px边框问题
移动端 Retina屏 各大主流网站1px的解决方案
css中引入svg来兼容部分安卓机显示0.5px边框的示例
The text was updated successfully, but these errors were encountered: