移动端1px解决方案,手机端1px问题
最近在移动终端写H5应用的时候,遇到了一个值得记录的点。现在从它的起源到实现,再来说说移动端的1px,说1px不够准确,应该说是1物理像素。
通过阅读下面的文章,你会理解以下问题:
问题
为什么有 1px 这个问题?实现 1px 有哪些方法?这些方法分别有哪些优缺点?开源项目中使用的哪些解决方案?如何在项目中处理 1px 的相关问题?由来
基本概念
首先需要了解两个概念,一个是像素(pixel) 可以简写为px,一个是设备像素比(DPR)。
像素:指图像中由一系列数字表示的最小单位。单位是px,不能再分了。
设备像素比率(DPR):设备像素比率=设备像素/设备无关像素。复制代码
下面我简单解释一下概念。
CSS(虚拟像素):指CSS样式代码中使用的逻辑像素。在CSS规范中,长度单位可以分为两类,绝对单位和相对单位。Px是相对单位,对面是设备像素。设备像素(物理像素):指设备能够控制显示器的最小物理单位,也就是显示器上的点。从工厂生产屏幕的那一天起,上面设备的像素就固定了,这和屏幕的大小有关。设备无关像素(逻辑像素):可以认为是计算机坐标系中的一个点。这个点代表一个程序可以使用的虚拟像素(例如,CSS像素)。这个点没有固定的大小。越小越清晰,然后被相关系统转换成物理像素。也就是说,当逻辑像素是1pt时,2px的物理像素参考数据显示在具有DPR 2的设备上。
各种类型iphone屏幕设备的参数
注意:这里的比例因子是DRP的值
设计草案比较数据
有人会奇怪为什么设计稿显示的是750x1334,因为设计稿显示的是物理像素。
而我们css中的像素是逻辑像素,应该是375x 667。在编写代码时,我们应该将自定义宽度设置为375px。
此时设计稿上1px宽度实际表示的css参数应该是物理像素1px对应的0.5px,那么如何实现物理像素是1px呢?
实践
归根结底,有两种方案,一种是使用css中的transfrom: scaley (0.5),另一种是根据不同的DPR将媒体查询设置为scale。
解决方案一
原理
转换后使用css伪元素:进行缩放
为什么使用伪元素?因为伪元素:after或:before独立于当前元素,所以它可以独立缩放,而不会影响元素本身的缩放。
伪元素大多数浏览器默认也可以使用单引号,形式和伪类一样,单引号兼容性(ie)更好。
实现
div class= cell border-1px cell div style . cell { width:100px;高度:100px}!-所有的边界。border-1px:在{content:“”之后;位置:绝对;框大小:边框-框;top:0;左:0;宽度:200%;身高:200%;边框:1px纯色# 000;边框-半径:4px-WebKit-transform:scale(0.5);变换:缩放(0.5);-webkit-transform-origin:左上;}!-单边框,以上面的边框为例-。border-1px-top:在{content:“”之前;位置:绝对;top:0;左:0;右:0;边框-顶部:1px纯红;transform:scaleY(. 5);变换-原点:左上;}/style解决方案二(升级方案一)
原理
用less封装公共代码(scheme 1),并添加媒体查询以扩展不同的DPR设备。边框(@边框宽度:1px@ border style:纯色;@边框颜色:@ lignt-gray-color;@ borderRadius:0){ position:relative;在{内容:""之前;位置:绝对;宽度:98%;身高:98%;top:0;左:0;变换-原点:左上;-WebKit-转换-来源:左上;框大小:边框-框;指针事件:无;} @ media(-WebKit-min-device-pixel-ratio:2){:before { width:200%;身高:200%;-WebKit-transform:scale(。5);} } @ media(-WebKit-min-device-pixel-ratio:2.5){:before { width:250%;身高:250%;-WebKit-transform:scale(。4);} } @ media(-WebKit-min-device-pixel-ratio:2.75){:before { width:275%;身高:275%;-WebKit-transform:scale(1/2.75);} } @ media(-WebKit-min-device-pixel-ratio:3){:before { width:300%;身高:300%;变换:缩放(1/3);-WebKit-transform:scale(1/3);} } .border-radius(@ borderRadius);在{ border-width:@边框宽度;边框样式:@ borderStyleborder-color:@ border color;}}.border-all(@边框宽度:1px@ border style:纯色;@边框颜色:@ lignt-gray-color;@borderRadius: 0) { .边框(@边框宽度;@ border style @ border color @ borderRadius);}其他方案:
使用图片:兼容性最好,灵活行最差,不能改变颜色、长度
使用视口和雷姆,js动态改变视口中规模缩放,缺点在于不适用于已有的项目,例如:使用可变区和大众汽车(大众的缩写)布局的
meta name= viewport id= web viewport content=初始比例=1,最大比例=1,最小比例=1,用户可缩放=否使用钢性铸铁渐变线性梯度或者箱形阴影
上述3种方案均有致命缺陷暂不推荐使用
兼容性
最后看一下兼容性如何,主要是伪元素、变换:缩放和最小设备像素比这几个关键词的兼容性
开源库的解决方案
vant 组件库
跳去开源代码库查看相关代码
使用较少的写的。发际线-普通(){位置:绝对;框大小:边框-框;内容:"";指针事件:无;}.发际线(@color: @border-color) { .发际线-普通();顶:-50%;右:-50%;底部:-50%;左:-50%;边框:0纯色@彩色;变换:缩放(0.5);}也是采用第一种解决方案
ant-design-mobile 组件库
跳去开源代码库查看相关代码。缩放-发际线-common(@color 、@top 、@right 、@bottom 、@ left){ content: ;位置:绝对;背景色:@颜色显示:块;z指数:1;top:@ top;右:@右;底部:@底部;左:@左;}.发际线(@direction,@ color:@ border-color-base)when(@ direction= top ){ border-top:1PX solid @ color;html:not([数据规模]){ @ media(最小分辨率:2d ppx){ border-top:none;*在{。比例-发际线-常用(@color,0,auto,auto,0);宽度:100%;高度:1PX变换-原点:50% 50%;变换:scaleY(0.5);@媒体(最小分辨率:3d ppx){ transform:scaleY(0.33);} } } }}.发际线(@direction,@ color:@ border-color-base)when(@ direction= right ){ border-right:1PX solid @ color;html:not([数据规模]){ @ media(最小分辨率:2d ppx){ border-right:none;*在{。比例-发际线-常用(@color,0,0,自动,自动);宽度:1PX身高:100%;背景:@颜色;变换-原点:100% 50%;transform:scaleX(0.5);@媒体(最小分辨率:3d ppx){ transform:scaleX(0.33);} } } }}.发际线(@direction,@ color:@ border-color-base)when(@ direction= bottom ){ border-bottom:1PX solid @ color;html:not([数据规模]){ @ media(最小分辨率:2d ppx){ border-bottom:none;*在{。比例-发际线-常用(@color,auto,auto,0,0);宽度:100%;高度:1PX变换-原点:50% 100%;变换:scaleY(0.5);@媒体(最小分辨率:3d ppx){ transform:scaleY(0.33);} } } }}.发际线(@direction,@ color:@ border-color-base)when(@ direction= left ){ border-left:1PX solid @ color;html:not([数据规模]){ @ media(最小分辨率:2d ppx){ border-left:none;*在{。比例-发际线-常用(@color,0,auto,auto,0);宽度:1PX身高:100%;变换-原点:100% 50%;transform:scaleX(0.5);@媒体(最小分辨率:3d ppx){ transform:scaleX(0.33);} } } }}.发际线(@direction,@color: @border-color-base,@ radius:0)when(@ direction= all ){ border:1PX solid @ color;border-radius:@ radius;html:not([数据规模]){ @ media(最小分辨率:2d ppx){ position:relative;边框:无;在{内容: 之前;位置:绝对;左:0;top:0;宽度:200%;身高:200%;边框:1PX纯色@彩色;border-radius:@ radius * 2;转换原点:0 0;变换:缩放(0.5);框大小:边框-框;指针事件:无;//@media(最小分辨率:3dppx) { //宽度:300%;//身高:300%;//border-radius:@ radius * 3;//transform:scale(0.33);//} } } }}这个值得研究下,比栈和第一种解决方案有点不同,主要在于处理了项目文件为2和为3的两种情况,相比来说更加完善。
这里军人服务社大写,为了防止插件将像素转成雷姆等单位
总结
通过该文,你大概了解1px问题的来龙去脉了吧,也明白了如何解决相关问题,如果这票文章能解决你的疑问或者工作中问题,不妨点个赞收藏下。
由于技术水平有限,文章中如有错误地方,请在评论区指出,感谢!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。