深受1px的困扰,如今终于解决了

54 篇文章 0 订阅
11 篇文章 0 订阅

为什么使用1px会出现问题?

css的1px不等于设备的1px

对于前端来说,在高清屏出现之前,前端代码的1px即等于手机物理像素点的1px。但有了dpr的概念之后,由于前端代码中使用的是css像素,手机会根据dpr换算成实际的物理像素大小来渲染页面。比如iphone6的设备像素比dpr=2,相当于1个css像素等于2个物理像素。

那么问题来了,以 iPhone6 为例,其 dpr = 2、屏幕尺寸(CSS 像素) 为 375x667,一般设计稿提供 2 倍图尺寸为 750x1334 。那么设计稿中的 1px,对应屏幕尺寸其实应该写成 0.5px。再由 dpr 计算公式可知,0.5 * 2 = 1px 物理像素。

此时你应该已经发现了,设计稿要实现 1px 细线、1px 边框,为什么前端实现总是偏粗的?那是因为如果你在代码中直接写成 1px,再通过 dpr 计算之后其实是 2px 物理像素,并不符合设计稿的要求。

那么当 dpr=2 时,代码中直接写成 0.5px 就解决问题了吗?

0.5px的兼容性问题

其实在项目中,我们已经采用rem单位进行了设计稿与屏幕尺寸的换算,即把1px换算成了0.5px。但这样会有各种兼容问题。

PC端

在PC端浏览器的最小识别像素为1px。所以在开发中工具书调试的时候,即便代码写的是0.5px,但默认会被浏览器识别并渲染为1px。

所以在浏览器看来总是偏粗了。

移动端

在手机端,不同手机浏览器对小数点像素的处理效果就更千奇百怪了。

在这里插入图片描述
从图中可发现,不同手机计算1px大小差别很大,而且手机本身对于小数点的处理情况就存在较大的兼容性问题。

那么如何实现1px的效果

  1. 使用伪元素 + css3缩放
  2. 使用viewport + rem布局
  3. 使用vw单位适配方案

1、伪元素 + css3缩放

常用方法,缩放的方式避免了直接写小像素带来的不同手机的兼容性处理不同。

css3缩放: transform: scale(0.5);

// 通过伪元素实现 0.5px 细线
.line::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 200%;
    height: 1px;
    background: #b3b4b8;
    transform: scale(0.5);
    transform-origin: 0 0;
}

为什么要放大200%后再缩小0.5?

为了只缩放border的1px的粗细,而保证border 的大小不变。若直接使用scale(0.5)的话border整体大小也会变为二分之一。

2、动态Viewport + REM方式

该方案参考了阿里早期开源的一个移动端适配解决方案flexible。

initial-scale 缩放值越大,当前 viewport 的宽度就会越小,反之亦然。

比如屏幕宽度是 320px 的话,如果我们设置 initial-scale=2 ,此时 viewport 的宽度会变为只有 160px 了。这也好理解,放大了一倍嘛,就是原来 1px 的东西变成 2px 了,但是并不是把原来的 320px 变为 640px ,而是在实际宽度不变的情况下,1px 变得跟原来的 2px 的长度一样了。

Flexible适配方案及问题

Flexible的大致实现思路是,首先根据dpr来动态修改meta标签中的viewport中的initial-scale值,以此来动态改变viewport大小。然后页面统一使用rem来布局。

为什么不直接引用flexible库来进行移动端适配呢?

因为lib- flexible这个库目前基本废弃了,虽然我们不会去使用flexible库,但其实大多数还是沿用了flexible实现的原理来进行移动端适配。

为什么页面所当比例initial-scale设置为1/dpr?

通过设置缩放比例1/dpr,可将viewport的宽度扩大dpr倍。

当设置 initial-scale = 1 / dpr = 0.5 时,获取到的 viewport 宽度 clientWidth = 750px ,被扩大了 dpr 倍,就正好是设备物理像素的宽度。

CSS像素个数 =  设备独立像素个数 /  scale   = ( 物理像素个数 / dpr )/ scale
scale = 1 / dpr 
// 所以
CSS像素个数 = 物理像素个数

总结

移动端适配主要就分为两方面,一方面要适配不同机型的屏幕尺寸,一方面是对细节像素的处理过程。如果你在项目中直接写了 1px ,由于 dpr 的存在展示导致渲染偏粗,其实是不符合设计稿的要求。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椰卤工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值