zoukankan      html  css  js  c++  java
  • 移动端1px问题解决方法

    为什么移动端会产生1px问题呢?

    UI设计师设计的时候,画的1px(真实像素)实际上是0.5px(css)的线或者边框。但是他不这么认为,他认为他画的就是1px的线,因为他画的稿的尺寸本身就是屏幕尺寸的2倍。假设手机视网膜屏的宽度是320x480宽,但实际尺寸是640x960宽,设计师设计图的时候一定是按照640x960设计的。但是前端工程师写代码的时候,所有css都是按照320x480写的,写1px(css),浏览器自动变成2px(真实像素)。
    
    那么前端工程师为什么不能直接写0.5px(css)呢?因为在老版本的系统里写0.5px(css)的话,会被浏览器解读为0px(css),就没有边框了。所以只能写成1px(css),实际在屏幕上显示出来就是设计师画的1px(真实像素)的2倍那么宽,所以设计师会觉得这个线太粗了,和他的设计稿不一样。在新版的系统里,已经开始逐渐支持0.5px(css)这种写法。所以如果设计师在大图上设计了一个1px(真实像素)的线的话,前端工程师直接除以2,写0.5px(css)就好了。
    
    

    先上解决方法

    1.小数值

    div {
        border: 1px solid #000;
    }
    
    @media (-webkit-min-device-pixel-ratio: 2) {
      div {
        border: .5px solid #000;
      }
    }
    
    

    缺点: 兼容性差,目前只有IOS8+才支持,在IOS7及其以下、安卓系统都是显示0px。

    2.border-image

    .border-image-1px {
        border- 1px 0px;
        -webkit-border-image: url(border.png) 2 0 stretch;
        border-image: url(border.png) 2 0 stretch;
    

    优点:图片可以用gif, png, base64多种格式, 以上是上下左右四条边框的写法, 需要单一边框只要定义单一边框的border, 代码比较直观.
    缺点:大小,颜色更改不灵活

    3.background-img渐变

    .border {
        background:
        linear-gradient(180deg, black, black 50%, transparent 50%) top    left  / 100% 1px no-repeat,
        linear-gradient(90deg,  black, black 50%, transparent 50%) top    right / 1px 100% no-repeat,
        linear-gradient(0,      black, black 50%, transparent 50%) bottom right / 100% 1px no-repeat,
        linear-gradient(-90deg, black, black 50%, transparent 50%) bottom left  / 1px 100% no-repeat;
    }
    
    

    4.box-shadow

    .shadow {
            -webkit-box-shadow:0 1px 1px -1px rgba(255, 0, 0, 0.5);
    	box-shadow:0 1px 1px -1px rgba(255, 0, 0, 0.5);
    }
    
    

    5.viewport

    在devicePixelRatio=2设置meta
    <meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
    在devicePixelRatio=3设置meta
    <meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">

    6.transform:scale(0.5)

    这个方案也是WeUI正在用的,核心思想是使用transform的scale来整体缩放,如果你想画一条1px的线,就可以直接用

    div {
        height: 1px;
          background: #000;
          transform: scaleY(0.5);
          transform-origin: 0 0;
    }
    

    理论上在dpr为2时就是scaleY(0.5),在dpr为3时就是scaleY(0.333),但是我注意到WeUI并没有针对其他dpr的做特殊处理,可能是因为在iPhone6(dpr=2)和iPhone6 Plus(dpr=3)中看起来差别不大吧

    如果你想给一个元素加一个1px的边框可以利用到伪元素,在这个方案下边框加圆角也很容易实现,具体代码如下:

    div:after {
      content: " ";
       78px;
      height: 38px;
      border-radius: 4px;
      border: 1px solid #000;
      transform: scale(0.5, 0.5);
      transform-origin: 0 0;
      position: absolute;
    }
    

    建议采用transform和伪类

    相关知识

    1.device pixels
    设备像素:显示屏幕的最小物理单位,每个dp包含自己的颜色、高宽等,不可再细分。设备像素是在设备出厂是设定的,设备一旦造出来就不会变大小和数量。官方在产品说明书上写的1920x1080就是说的物理像素。
    2.dpi
    设备像素:显示屏幕的最小物理单位,每个dp包含自己的颜色、高宽等,不可再细分。设备像素是在设备出厂是设定的,设备一旦造出来就不会变大小和数量。官方在产品说明书上写的1920x1080就是说的物理像素。
    3.dpr
    设备像素比dpr = 设备像素 / CSS像素(某一方向上)
    可以通过window.devicePixelRatio获取设备的dpr值。一般来说,在桌面的浏览器中,设备像素比(dpr)等于1,一个css像素就是代表的一个物理像素。而在移动端,大多数机型都不是为1,其中iphone的dpr普遍是2和3,那么一个css像素不再是对应一个物理像素,而是2个和3个物理像素。即我们通常在css中设置的width:1px,对应的便是物理像素中的2px。手机机型不同,dpr可能不同。

    以iphone5为例,iphone5的CSS像素为320px568px,DPR是2,所以其设备像素为640px1136px

    640(px) / 320(px)  = 2
    1136(px) / 568(px) = 2
    640(px)*1136(px) /  320(px)*568(px) = 4
    
    
  • 相关阅读:
    FZU OJ 1056 :扫雷游戏
    HPU 1166: 阶乘问题(一)
    常用的一些模板
    PAT天梯:L1-019. 谁先倒
    HPU 1437: 王小二的求值问题
    《编程珠玑》阅读小记(7) — 代码调优与节省空间
    《编程珠玑》阅读小记(6) — 算法设计技术
    《编程珠玑》阅读小记(5) — 编程小事
    《编程珠玑》阅读小记(4) — 编写正确的程序
    《C/C++专项练习》— (1)
  • 原文地址:https://www.cnblogs.com/heson/p/10029737.html
Copyright © 2011-2022 走看看