吃透移动端 1px的具体用法
最近在写移动端 H5 应用,遇到一个值得记录下来的点。现在从它的由来到实现,我们来聊一下移动端 1px,说 1px 不够准确,应该说成 1 物理像素 。
通过阅读狼蚁网站SEO优化文章,你将会理解以下问题
问题
- 为什么有 1px 这个问题?
- 实现 1px 有哪些方法?这些方法分别有哪些优缺点?
- 开源项目中使用的哪些解决方案?
- 如何在项目中处理 1px 的相关问题?
由来
基本概念
,我们要了解两个概念,一个是 像素(pixel) 可以简写为 px ,一个是 设备像素比(DPR)
像素 指在由一个数字序列表示的图像中的一个最小单元,单位是 px,不可分割了。
设备像素比(DPR): 设备像素比 = 设备像素 / 设备独立像素。复制代码
狼蚁网站SEO优化我来简单解释下几个概念
- CSS 像素 (虚拟像素)指的是 CSS 样式代码中使用的逻辑像素,在 CSS 规范中,长度单位可以分为两类,绝对单位以及相对单位。px 是一个相对单位,相对的是设备像素。
- 设备像素 (物理像素)指设备能控制显示的最小物理单位,意指显示器上一个个的点。从屏幕在工厂生产出的那天起,它上面设备像素点就固定不变了,和屏幕尺寸大小有关。
- 设备独立像素 (逻辑像素)可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: CSS 像素),这个点是没有固定大小的,越小越清晰,然后由相关系统转换为物理像素。 也就是说,当逻辑像素是 1pt 时,在 DPR 为 2 的 设备上显示为 2px 的物理像素
参考数据
各种类型的 iphone 手机屏幕设备的参数
注这里的缩放因子呢,就是 DRP 的值
设计稿对比数据
会有人好奇,为什么设计稿上显示是 750x1334 呢,这是因为设计稿是显示的 物理像素
而我们 css 中的像素是 逻辑像素 应该为 375x 667,在编写代码时要将自定义宽度设置成 375px
那么此时设计稿上的 1px 宽度实际代表的 css 参数应该是 0.5px 对应物理像素 1px,那么怎么实现这个物理像素为 1px 呢
实践
归根结底有两种方案,一种是利用 css 中的 transfromscaleY(0.5)
,另一种是设置 媒体查询根据不同 DPR 缩放
解决方案一
原理
利用 css 的 伪元素 ::after
+ transfrom
进行缩放
为什么用伪元素?因为伪元素 ::after
或 ::before
是独立于当前元素,可以单独对其缩放而不影响元素本身的缩放
伪元素大多数浏览器默认单引号也可以使用,和伪类一样形式,而且单引号兼容性(ie)更好些
实现
<div class="cell border-1px"> cell <div> <style> .cell { width: 100px; height: 100px; } <!--全部边框--> .border-1px:after { content: ''; position: absolute; box-sizing: border-box; : 0; left: 0; width: 200%; height: 200%; border: 1px solid #000; border-radius: 4px; -webkit-transform: scale(0.5); transform: scale(0.5); -webkit-transform-origin: left; } <!--单边框,以上边框为例--> .border-1px-:before { content: ""; position: absolute; : 0; left: 0; right: 0; border-: 1px solid red; transform: scaleY(.5); transform-origin: left ; } </style>
解决方案二(升级方案一)
原理
使用 less 对公共代码(方案一)封装,增加媒体查询分别对不同 DPR 的设备,进行不同的缩放
.border( @borderWidth: 1px; @borderStyle: solid; @borderColor: @lignt-gray-color; @borderRadius: 0) { position: relative; &:before { content: ''; position: absolute; width: 98%; height: 98%; : 0; left: 0; transform-origin: left ; -webkit-transform-origin: left ; box-sizing: border-box; pointer-events: none; } @media (-webkit-min-device-pixel-ratio: 2) { &:before { width: 200%; height: 200%; -webkit-transform: scale(.5); } } @media (-webkit-min-device-pixel-ratio: 2.5) { &:before { width: 250%; height: 250%; -webkit-transform: scale(.4); } } @media (-webkit-min-device-pixel-ratio: 2.75) { &:before { width: 275%; height: 275%; -webkit-transform: scale(1 / 2.75); } } @media (-webkit-min-device-pixel-ratio: 3) { &:before { width: 300%; height: 300%; transform: scale(1 / 3); -webkit-transform: scale(1 / 3); } } .border-radius(@borderRadius); &:before { border-width: @borderWidth; border-style: @borderStyle; border-color: @borderColor; } } .border-all( @borderWidth: 1px; @borderStyle: solid; @borderColor: @lignt-gray-color; @borderRadius: 0) { .border(@borderWidth; @borderStyle; @borderColor; @borderRadius); }
其他方案
使用图片兼容性最好,灵活行最差,不能改变颜色、长度
使用 viewport
和 rem
, js
动态改变 viewport
中 scale
缩放,缺点在于不适用于已有的项目,例如使用 vh
和 vw
布局的
<meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
使用 css 渐变 linear-gradient
或者 box-shadow
上述 3 种方案均有致命缺陷暂不推荐使用
兼容性
看一下兼容性如何,主要是伪元素、 transform:scale
和 min-device-pixel-ratio
这几个关键词的兼容性
开源库的解决方案
vant 组件库
使用 less
写的
.hairline-mon() { position: absolute; box-sizing: border-box; content: ' '; pointer-events: none; } .hairline(@color: @border-color) { .hairline-mon(); : -50%; right: -50%; bottom: -50%; left: -50%; border: 0 solid @color; transform: scale(0.5); }
也是采用第一种解决方案
ant-design-mobile 组件库
.scale-hairline-mon(@color, @, @right, @bottom, @left) { content: ''; position: absolute; background-color: @color; display: block; z-index: 1; : @; right: @right; bottom: @bottom; left: @left; } .hairline(@direction, @color: @border-color-base) when (@direction = '') { border-: 1PX solid @color; html:not([data-scale]) & { @media (min-resolution: 2dppx) { border-: none; &::before { .scale-hairline-mon(@color, 0, auto, auto, 0); width: 100%; height: 1PX; transform-origin: 50% 50%; transform: scaleY(0.5); @media (min-resolution: 3dppx) { transform: scaleY(0.33); } } } } } .hairline(@direction, @color: @border-color-base) when (@direction = 'right') { border-right: 1PX solid @color; html:not([data-scale]) & { @media (min-resolution: 2dppx) { border-right: none; &::after { .scale-hairline-mon(@color, 0, 0, auto, auto); width: 1PX; height: 100%; background: @color; transform-origin: 100% 50%; transform: scaleX(0.5); @media (min-resolution: 3dppx) { transform: scaleX(0.33); } } } } } .hairline(@direction, @color: @border-color-base) when (@direction = 'bottom') { border-bottom: 1PX solid @color; html:not([data-scale]) & { @media (min-resolution: 2dppx) { border-bottom: none; &::after { .scale-hairline-mon(@color, auto, auto, 0, 0); width: 100%; height: 1PX; transform-origin: 50% 100%; transform: scaleY(0.5); @media (min-resolution: 3dppx) { transform: scaleY(0.33); } } } } } .hairline(@direction, @color: @border-color-base) when (@direction = 'left') { border-left: 1PX solid @color; html:not([data-scale]) & { @media (min-resolution: 2dppx) { border-left: none; &::before { .scale-hairline-mon(@color, 0, auto, auto, 0); width: 1PX; height: 100%; transform-origin: 100% 50%; transform: scaleX(0.5); @media (min-resolution: 3dppx) { transform: scaleX(0.33); } } } } } .hairline(@direction, @color: @border-color-base, @radius: 0) when (@direction = 'all') { border: 1PX solid @color; border-radius: @radius; html:not([data-scale]) & { @media (min-resolution: 2dppx) { position: relative; border: none; &::before { content: ''; position: absolute; left: 0; : 0; width: 200%; height: 200%; border: 1PX solid @color; border-radius: @radius 2; transform-origin: 0 0; transform: scale(0.5); box-sizing: border-box; pointer-events: none; // @media (min-resolution: 3dppx) { // width: 300%; // height: 300%; // border-radius: @radius 3; // transform: scale(0.33); // } } } } }
这个值得研究下,比 vant 和 第一种解决方案有点不同,主要在于处理了 DPR 为 2 和为 3 的两种情况,相比来说更加完善。
这里 PX 大写,为了防止插件将 px 转成 rem 等单位
通过该文,你大概了解 1px 问题的来龙去脉了吧,也明白了如何解决相关问题,如果这票文章能解决你的疑问或者工作中问题,不妨点个赞收藏下。
由于技术水平有限,文章中如有错误地方,请在评论区指出,感谢!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持狼蚁SEO。
长沙网站设计
- 如何进行东阳SEO关键词优化?
- 边坝哪有关键词排名优化:提升你的网站流量与
- 安国百度优化服务:提升您的在线可见性
- 阜康新手做SEO怎么做
- 山西seo网站排名关键词优化:提升您网站曝光率
- 临沂seo网站排名关键词优化:提高你的网站可见
- 广西SEO网站推广怎样付费比较合理
- 双辽SEO网站推广:提升你的网站可见性与流量
- 辽宁企业网站优化购买方式有哪些
- 提升宝清百度SEO排名的实用技巧与策略
- 静宁百度SEO排名:提升您网站曝光率的关键策略
- 彭州百度SEO排名的提升策略和实施指南
- 广南百度关键词SEO:提升网站排名的关键策略
- 辽宁关键词优化怎么做论坛营销
- 吉林百度seo排名如何做到让用户满意
- 内黄百度优化服务:提升在线可见性的关键