关于移动端开发 1px 线的一些理解和解决办法

2019 年 6 月 9 日 前端大全

(给前端大全加星标,提升前端技能

作者: 大转转FE/李兴瑞

1px线变粗的原因

在做移动端项目时,常常是根据设计图设置元素节点的大小和样式,但是有时候根据设计图写出来的样式还是不如人意,虽然表面上看起来和设计稿是一样的,可是就是没设计稿那种感觉,而且莫名还有一种山寨的气息,UI审查的时候也常常会觉得分割线或则边框线太粗了,要更细一点,但是一看代码,已经是1px了,为什么看着还是那么粗呢?

要知道问题的原因首先要了解一下几个概念:

(1)物理像素(physical pixel)

一个物理像素是显示器(手机屏幕)上最小的物理显示单元(像素颗粒),在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。 如:iPhone6上就有750*1334个物理像素颗粒。

(2)设备独立像素(density-independent pixel)

设备独立像素(也叫密度无关像素),可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如:css像素),有时我们也说成是逻辑像素。然后由相关系统转换为物理像素。所以说,物理像素和设备独立像素之间存在着一定的对应关系,这就是接下来要说的设备像素比。

(3)设备像素比(device pixel ratio )简称dpr

设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系。它的值可以按如下的公式的得到:

设备像素比(dpr)=物理像素/逻辑像素(px) // 在某一方向上,x方向或者y方向,下图dpr=2

知道了设备像素比,我们就大概知道了1px线变粗的原因。简单来说就是手机屏幕分辨率越来越高了,同样大小的一个手机,它的实际物理像素数更多了。因为不同的移动设备有不同的像素密度,所以我们所写的1px在不同的移动设备上等于这个移动设备的1px。现在做移动端开发时一般都要加上一句话:

  
  
    
  1. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

这句话定义了本页面的viewport的宽度为设备宽度,初始缩放值和最大缩放值都为1,并禁止了用户缩放。

viewport的设置和屏幕物理分辨率是按比例而不是相同的,移动端window对象有个devicePixelRatio属性,它表示设备物理像素和css像素的比例,在retina屏的iphone手机上,这个值为2或3, css里写的1px长度映射到物理像素上就有2px或3px。通过设置viewport,可以改变css中的1px用多少物理像素来渲染,设置了不同的viewport,当然1px的线条看起来粗细不一致。

1px线变粗的解决方法

伪类 + scale

这种方法的原理就是把原来元素的border去掉,然后用 :before 或者 :after 重做 border ,原先的元素相对定位,新做的 border 绝对,定位使用 transform 的 scale 把线条高度缩小一半,新边框就相当于0.5px了。代码如下:

  
  
    
  1. .scale{

  2. position: relative;

  3. border:none;

  4. }

  5. .scale:after{

  6. content: '';

  7. position: absolute;

  8. bottom: 0;

  9. background: #000;

  10. width: 100%;

  11. height: 1px;

  12. -webkit-transform: scaleY(0.5);

  13. transform: scaleY(0.5);

  14. -webkit-transform-origin: 0 0;

  15. transform-origin: 0 0;

  16. }

使用flexible.js

前面已经说过1px变粗的原因就在于一刀切的设置viewport宽度,如果能把viewport宽度设置为实际的设备物理宽度,css里的1px不就等于实际1px长了么。 flexible.js的原理就是这样,先获取设备缩放比devicePixelRatio,然后根据缩放比来动态设定viewport的值,这样导致的结果就是无论是哪个设备,1px所表示的永远是1个设备像素,即该设备的最小像素。

  
  
    
  1. //devicePixelRatio=2时,输出meta如下

  2. <meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">

  3. //devicePixelRatio=3时,输出meta如下

  4. <meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">

使用meta viewport控制

原理如上。代码如下:

  
  
    
  1. //1px像素线条

  2. <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=0">

  3. //0.5像素线条

  4. <meta name="viewport" content="width=device-width,initial-scale=0.5,user-scalable=0">

使用box-shadow模拟边框

利用css 对阴影处理的方式实现0.5px的效果。代码如下:

  
  
    
  1. .box-shadow-1px {

  2. box-shadow: inset 0px -1px 1px -1px #c8c7cc;

  3. }

使用border-image

首先需要自己制作一个0.5像素的线条作为线条背景图片。。代码如下:

  
  
    
  1. p{

  2. border-width: 0 0 1px 0;

  3. border-image: imageUrl 2 0 round;

  4. }

利用背景渐变linear-gradient

利用linear-gradient利用背景图片渐变,从有色到透明,默认方向从上到下,从0deg到50%的地方颜色是边框颜色,然后下边一半颜色就是透明了。然后设置背景宽度100%,高度是1px,再去掉repeat,所以有颜色的就是0.5px的边框。代码如下:

  
  
    
  1. .bg_border {

  2. background-image: linear-gradient(0deg,black 50%,transparent 50%);

  3. background-size: 100% 1px;

  4. background-repeat: no-repeat;

  5. }



推荐阅读

(点击标题可跳转阅读)

看完这篇,你也可以实现一个360度全景插件

从 Mixin 到 HOC 再到 Hook

提高幸福感的 9 个 CSS 技巧



觉得本文对你有帮助?请分享给更多人

关注「前端大全」加星标,提升前端技能

好文章,我在看❤️

登录查看更多
0

相关内容

少标签数据学习,54页ppt
专知会员服务
192+阅读 · 2020年5月22日
【芝加哥大学】可变形的风格转移,Deformable Style Transfer
专知会员服务
30+阅读 · 2020年3月26日
深度神经网络实时物联网图像处理,241页pdf
专知会员服务
75+阅读 · 2020年3月15日
【新书】Java企业微服务,Enterprise Java Microservices,272页pdf
模型压缩究竟在做什么?我们真的需要模型压缩么?
专知会员服务
25+阅读 · 2020年1月16日
【电子书】C++ Primer Plus 第6版,附PDF
专知会员服务
83+阅读 · 2019年11月25日
社区分享|如何让模型在生产环境上推理得更快
那些酷炫的深度学习网络图怎么画出来的?
极市平台
28+阅读 · 2019年6月16日
说说我的老同事,前端大神程劭非
余晟以为
17+阅读 · 2019年1月14日
从零开始一起学习SLAM | 点云到网格的进化
计算机视觉life
12+阅读 · 2019年1月9日
从零开始一起学习SLAM | 神奇的单应矩阵
计算机视觉life
9+阅读 · 2018年11月11日
别@微信团队了,我用Python给自己戴上了圣诞帽!
PyTorch 到底好用在哪里?
AI研习社
3+阅读 · 2017年10月27日
Arxiv
3+阅读 · 2018年3月21日
Arxiv
8+阅读 · 2018年1月19日
Arxiv
6+阅读 · 2018年1月11日
VIP会员
相关VIP内容
少标签数据学习,54页ppt
专知会员服务
192+阅读 · 2020年5月22日
【芝加哥大学】可变形的风格转移,Deformable Style Transfer
专知会员服务
30+阅读 · 2020年3月26日
深度神经网络实时物联网图像处理,241页pdf
专知会员服务
75+阅读 · 2020年3月15日
【新书】Java企业微服务,Enterprise Java Microservices,272页pdf
模型压缩究竟在做什么?我们真的需要模型压缩么?
专知会员服务
25+阅读 · 2020年1月16日
【电子书】C++ Primer Plus 第6版,附PDF
专知会员服务
83+阅读 · 2019年11月25日
相关资讯
社区分享|如何让模型在生产环境上推理得更快
那些酷炫的深度学习网络图怎么画出来的?
极市平台
28+阅读 · 2019年6月16日
说说我的老同事,前端大神程劭非
余晟以为
17+阅读 · 2019年1月14日
从零开始一起学习SLAM | 点云到网格的进化
计算机视觉life
12+阅读 · 2019年1月9日
从零开始一起学习SLAM | 神奇的单应矩阵
计算机视觉life
9+阅读 · 2018年11月11日
别@微信团队了,我用Python给自己戴上了圣诞帽!
PyTorch 到底好用在哪里?
AI研习社
3+阅读 · 2017年10月27日
Top
微信扫码咨询专知VIP会员