移动端中1px边框问题
问题描述:
- 移动端给元素添加1px边框,有的手机会不显示边框
原因分析:
-
CSS像素为1px宽的直线,对应的物理像素是不同的,可能是2px或者3px,而设计师想要的1px宽的直线,其实就是1物理像素宽。
-
对于CSS而言,可以认为是border: 0.5px;,这是多倍屏下能显示的最小单位。然而,并不是所有手机浏览器都能识别border: 0.5px,有的系统里,0.5px会被当成为0px处理
-
这些由于不同的手机有不同的像素密度。在window对象中有一个devicePixelRatio属性,他可以反应css中的像素与设备的像素比。
解决方案:
- 1.border-image
基于media查询判断不同的设备像素比给定不同的border-image
.border_1px{
border-bottom: 1px solid #000;
}
@media only screen and (-webkit-min-device-pixel-ratio:2){
.border_1px{
border-bottom: none;
border-width: 0 0 1px 0;
border-image: url(../1px.png) 0 0 2 0 stretch;
}
}
优点:可以设置单条、多条表框。
缺点:更换颜色和样式麻烦,某些设备上会模糊。
- 2.background-image
和border-image类似,准备一张符合条件的边框背景图,模拟在背景上
.border_1px{
border-bottom: 1px solid #000;
}
@media only screen and (-webkit-min-device-pixel-ratio:2{
.border_1px{
background: url(../img/1px.png) repeat-x left bottom;
background-size: 100% 1px;
}
}
优点:可以设置单条、多条表框。
缺点:更换颜色和样式麻烦,某些设备上会模糊
- 3.伪元素+transform
基于media查询判断不同的设备像素比对线条进行缩放
border1px-after()
content ' '
position absolute
box-sizing border-box
pointer-events none
border-all($color=#ccc, $radius=0)
@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
&:after {
border1px-after()
transform-origin top left
top 0
left 0
width 150%
height 150%
transform scale(.66667, .66667)
border 1px solid $color /* px2rpx: no */
border-radius $radius /* px2rpx: no */
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
&:after {
border1px-after()
transform-origin top left
top 0
left 0
width 200%
height 200%
transform scale(.5, .5)
border 1px solid $color /* px2rpx: no */
border-radius $radius /* px2rpx: no */
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 3) {
&:after {
border1px-after()
transform-origin top left
top 0
left 0
width 300%
height 300%
transform scale(.33333, .33333)
border 1px solid $color /* px2rpx: no */
border-radius $radius /* px2rpx: no */
}
}
优点:可以满足所有场景,且修改灵活。
缺点:对于已使用伪类的元素要多层嵌套。
- 4.用JS计算rem基准值和viewport缩放值
/* 设计稿是750,采用1:100的比例,font-size为100 * (docEl.clientWidth * dpr / 750) */
var dpr, rem, scale;
var docEl = document.documentElement;
var fontEl = document.createElement('style');
var metaEl = document.querySelector('meta[name="viewport"]');
dpr = window.devicePixelRatio || 1;
rem = 100 * (docEl.clientWidth * dpr / 750);
scale = 1 / dpr;
// 设置viewport,进行缩放,达到高清效果
metaEl.setAttribute('content', 'width=' + dpr * docEl.clientWidth + ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');
// 设置data-dpr属性,留作的css hack之用,解决图片模糊问题和1px细线问题
docEl.setAttribute('data-dpr', dpr);
// 动态写入样式
docEl.firstElementChild.appendChild(fontEl);
fontEl.innerHTML = 'html{font-size:' + rem + 'px!important;}';
用JS根据屏幕尺寸和dpr精确地设置不同屏幕所应有的rem基准值和initial-scale缩放值,完美解决了1px细线问题