起因
- 在项目开发过程中,前端代码设置 1px 边框,但在某些机型上显示较粗,像是 2px 甚至 3px,这就是1px像素问题
物理像素(DP)
- 物理像素又称设备像素,是组成显示屏的基本单位,每一台设备的物理像素在出厂时就已经固定好了,不会改变,我们平时看到的图片是通过每个像素不同颜色组合而成的
- 设计师一般要求的像素就是物理像素
逻辑像素(DIP)
- 逻辑像素又称为设备独立像素或CSS像素,是组成图像的基本单位,它是一个抽象概念,我们可以笼统的认为屏幕可视区域的宽度就是逻辑像素的大小。在1倍屏下,1倍逻辑像素=1倍物理像素;2倍屏下,1倍逻辑像素=2倍物理像素。逻辑像素是可变的,例如当我们放大页面的尺寸比例时,逻辑像素也就随之扩大
- 前端开发者在CSS中设置的像素就是逻辑像素
设备像素比(DPR)
- 设备像素比(DPR): 设备像素比 = 物理像素(DP) / 逻辑像素(DIP)
- 一般来说,在PC端浏览器中,设备像素比(DPR)等于1,1px 像素就代表1个物理像素;但是在视网膜(retina)屏幕中,DPR普遍是2(例如 iPhone 8)或3(例如 iPhone 8 Plus),这就导致了 1px 问题
解决方案
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
/* 四条border样式设置 */
.scale {
position: relative;
margin-bottom: 20px;
border: none;
}
.scale:after {
content: '';
position: absolute;
top: 0;
left: 0;
border: 1px solid red;
-webkit-box-sizing: border-box;
box-sizing: border-box;
width: 200%;
height: 200%;
/* 设置 X 轴Y 轴以中心点缩放 0.5 倍 */
-webkit-transform: scale(0.5);
transform: scale(0.5);
/* 以左上角为原点,因为 scale 的缘故,位置要移动到左上角 */
-webkit-transform-origin: left top;
transform-origin: left top;
}
/* 单条水平border样式设置,如果是垂直border, 设置width为1px, height: 100% */
.scale {
position: relative;
border: none;
}
.scale:after {
content: '';
position: absolute;
bottom: 0;
background: red;
width: 100%;
height: 1px;
/* 设置Y 轴以中心点缩放 0.5 倍 */
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
/* 以左上角为原点,因为scale的缘故,位置要移动到左上角 */
-webkit-transform-origin: left top;
transform-origin: left top;
}
</style>
<body>
<div> cell <div>
</body>
<script>
// 判断是否 Retina 屏
if (window.devicePixelRatio && devicePixelRatio >= 2) {
console.log('Retina 屏')
document.querySelector('div').className = 'scale';
}
</script>
</html>
- 第三方插件,淘宝移动端采取的方案 flexible.js,动态设置 meta 标签,css 边框可直接设置 1px
// Install
npm i -S amfe-flexible
// Import
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<script src="./node_modules/amfe-flexible/index.js"></script>
// 2 DPR
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
// 3 DPR
<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">
网友评论