边框变粗的原因
> css中的1px并不等于移动设备的1px,不同手机有不同的像素密度。window对象中有一个devicePixelRatio属性,即css中的像素 / 设备的像素比
之前的解决方案
1. 0.5px
通过javascript检测浏览器能否处理0.5px的边框,如果可以则给html元素添加个class
if (window.devicePixelRatio && devicePixelRatio >= 2) {
var test = document.createElement('div');
test.style.border = '.5px solid transparent';
document.body.appendChild(test);
if (test.offsetHeight == 1) {
document.querySelector('html').classList.add('hairlines');
}
document.body.removeChild(test);
}
样式如下
div {
border: 1px solid #bbb;
}
.hairlines div {
border- 0.5px;
}
存在的问题
不兼容安卓和ios8以下设备
2. 图片实现border
可以用gif、png或base64图片
.border {
border- 1px;
border-image: url(border.gif) 2 repeat;
}
存在的问题
需要改颜色的时候需要重新制作图片,很不方便
** 3. 淘宝M站 viewport+rem实现**
在devicePixelRatio = 2
时,输出viewport
<meta name = 'viewport' content='initial-scale=0.5, maximum-scale=0.5, user-scalable=no'>
在devicePixelRatio = 3
时,输出viewport
<meta name = 'viewport' content='initial-scale=0.3333333333, maximum-scale=0.333333333333, minimum-scale=0.3333333333'>
再通过设置对应viewport的rem基准值,就可以实现1px了。
存在的问题
多套样式还需要动态改变viewport,有点繁琐
伪类 + transform
原理是把原先的border去掉,然后利用:before 或者 :after 重做border, 并transform的scale缩小一半,原先的元素相对定位,新做的border绝对定位
.hairlines li {
position: relative;
border: none;
}
.hairlines li:after {
content: '';
position: absolute;
left: 0;
background: #000;
100%;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
.hairlines li {
position: relative;
margin-bottom: 20px;
border: none;
}
.hairlines li: after {
content: '';
position: absolute;
top: 0;
left: 0;
border: 1px solid #000;
box-sizing: border-box;
200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
}
结合js代码 判断是否是Retina屏使用:
if (window.devicePixelRatio && devicePixelRatio >= 2) { document.querySelector('ul').className = 'hairlines' }