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
    
    
  • 相关阅读:
    LeetCode 453 Minimum Moves to Equal Array Elements
    LeetCode 112 Path Sum
    LeetCode 437 Path Sum III
    LeetCode 263 Ugly Number
    Solutions and Summay for Linked List Naive and Easy Questions
    AWS–Sysops notes
    Linked List
    All About Linked List
    datatable fix error–Invalid JSON response
    [转]反编译c#的相关问题
  • 原文地址:https://www.cnblogs.com/heson/p/10029737.html
Copyright © 2011-2022 走看看