1. 原因
在 Retina 屏幕中,css 中的 1px,它会以 2px 的形式呈现。所以设置 1px,手机端看到的不是 1 像素,显得粗一些。
在不同的屏幕中,dpr 的值不相同,所以手机中呈现的 1 像素也会不一样。
2. 解决方法
1) 伪元素 + transform
思路:
- 使用伪元素来实现边框效果
- 使用 media query 针对不同的 dpr 值,将这个伪元素进行缩放
scss 中的 minxin
@mixin border-1px($color,$position) {position: relative;@if ($position == "bottom"){&:after {content: "";position: absolute;left: 0;bottom: 0;border-top: 1px solid $color;width: 100%;}}@if ($position == "top"){&:before {content: "";position: absolute;left: 0;top: 0;border-top: 1px solid $color;width: 100%;}}@if ($position == "left"){&:before {content: "";position: absolute;left: 0;top: 0;border-left: 1px solid $color;height: 100%;}}@if ($position == "right"){&:after {content: "";position: absolute;left: 0;top: 0;border-left: 1px solid $color;height: 100%;}}}
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5) {.border-1px {&::after {-webkit-transform: scaleY(0.7);transform: scaleY(0.7);}}}@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {.border-1px {&::after {-webkit-transform: scaleY(0.5);transform: scaleY(0.5);}}}
CSS 实现
.scale-1px{position: relative;border:none;}.scale-1px:after{content: '';position: absolute;bottom: 0;background: #000;width: 100%;height: 1px;-webkit-transform: scaleY(0.5);transform: scaleY(0.5);-webkit-transform-origin: 0 0;transform-origin: 0 0;}
四条boder样式设置:
.scale-1px{position: relative;margin-bottom: 20px;border:none;}.scale-1px: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;}
优点:
- 所有场景都能满足
- 支持圆角(伪类和本体类都需要加border-radius)
缺点:
对于已经使用伪类的元素(例如 clearfix),可能需要多层嵌套
2) 使用 box-shadow 模拟边框
利用 css 对阴影处理的方式实现 0.5px 的效果
样式设置:.box-shadow-1px {box-shadow: inset 0px -1px 1px -1px #c8c7cc;}
优点:
代码量少
- 可以满足所有场景
缺点:
- 边框有阴影,颜色变浅
3) viewport + rem 实现
同时通过设置对应viewport的rem基准值,这种方式就可以像以前一样轻松愉快的写1px了。
在devicePixelRatio = 2 时,输出viewport:<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
在devicePixelRatio = 3 时,输出viewport:
<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">
这种兼容方案相对比较完美,适合新的项目,老的项目修改成本过大。
对于这种方案,可以看看《使用Flexible实现手淘H5页面的终端适配》
优点:
- 所有场景都能满足
- 一套代码,可以兼容基本所有布局
缺点:
