移动端1px问题
一、Viewport 基础
- 移动端viewport meta 标签大致如下:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<!--
width:控制 viewport 的大小,可以指定的一个值,如果 600,或者特殊的值,如 device- width 为设备的宽度(单位为缩放为 100% 时的 CSS 的像素)。
height:和 width 相对应,指定高度。
initial-scale:初始缩放比例,也即是当页面第一次 load 的时候缩放比例。
maximum-scale:允许用户缩放到的最大比例。minimum-scale:允许用户缩放到的最小比例。user-scalable:用户是否可以手动缩放
iphoneX的“刘海”为相机和其他组件留出了空间,同时在底部也留有可操作区域。两边会出现一道白条。
解决的方案是:1、给body添加一个background;2、添加viewport-fit=cover meta标签,使页面占满整个屏幕。
-->
二、window属性:devicePixelRatio
- 该属性返回当前显示设备的物理像素分辨率与 CSS 像素分辨率的比率。此值也可以解释为像素大小的比率:一个 CSS 像素的大小与一个物理像素的大小的比值。简单地说,这告诉浏览器应该使用多少个屏幕的实际像素来绘制单个 CSS 像素。
// media媒体查询语法
.border-1px{ border: 1px solid #ccc; }
@media (-webkit-min-device-pixel-ratio: 2) {
.border-1px{ border: 0.5px solid #ccc; }
}
三、解决方案:伪元素 + transform
- 原理是把原先元素的 border 去掉,然后利用 :before 或者 :after 重做 border ,并 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。
- 完善 mixin.scss 函数
// app 1像素边框
// $position:[边框位置]top, bottom, left, right
// $color:[边框颜色]
// $radius:[圆角]
// 使用:@include border(top, #ddd); 或 @include border(full, #ddd, 2px);
@mixin border($position: full, $borderColor: #e2e2e2, $radius: 0) {
content: ' ';
position: absolute;
pointer-events: none;
color: $borderColor;
@if $position==top {
border-top: 1px solid $borderColor;
height: 1px;
left: 0;
right: 0;
top: 0;
@media only screen and (-webkit-min-device-pixel-ratio:2) {
& {
-webkit-transform: scaleY(0.5);
-webkit-transform-origin: 50% 0%;
}
}
}
@if $position==bottom {
border-bottom: 1px solid $borderColor;
height: 1px;
left: 0;
right: 0;
bottom: 0;
@media only screen and (-webkit-min-device-pixel-ratio:2) {
& {
-webkit-transform: scaleY(0.5);
-webkit-transform-origin: 0 100%;
}
}
}
@if $position==left {
border-left: 1px solid $borderColor;
width: 1px;
top: 0;
bottom: 0;
left: 0;
@media only screen and (-webkit-min-device-pixel-ratio:2) {
& {
-webkit-transform: scaleX(0.5);
-webkit-transform-origin: 0% 50%;
}
}
}
@if $position==right {
border-right: 1px solid $borderColor;
width: 1px;
top: 0;
bottom: 0;
right: 0;
@media only screen and (-webkit-min-device-pixel-ratio:2) {
& {
-webkit-transform: scaleX(0.5);
-webkit-transform-origin: 100% 50%;
}
}
}
@if $position==full {
border: 1px solid $borderColor;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: none;
border-color: $borderColor;
@if $radius !=0 {
border-radius: $radius;
}
@media only screen and (-webkit-min-device-pixel-ratio:2) {
& {
right: -100%;
bottom: -100%;
-webkit-transform: scale(0.5);
-webkit-transform-origin: 0% 0%;
$radiusx2: null;
@each $i in $radius {
$radiusx2: append($radiusx2, $i * 2);
}
@if $radius !=0 {
border-radius: $radiusx2;
}
}
}
}
}