问题描述:移动端iPhone上的1px边框看起来像2px那么粗。
问题分析:不同的手机有不同的像素密度,在window对象中有一个devicePixelRatio属性,它可以反应设备的像素与css中的像素比。即devicePixelRatio=物理像素/独立像素。iPhone使用的是Retine屏,“Retina”是一种显示技术,可以把更多的像素点压缩至一块屏幕里,从而达到更高的分辨率并提高屏幕显示的细腻程度。因为Retine屏的分辨率始终是普通屏幕的2倍,1px的边框在devicePixelRatio=2的Retine屏下会显示成2px,所以css设置1px的样式,实际是2px的效果。
解决方案

1、用小数实现

div {
  border: 1px solid #dfdfdf;
}
@media screen and (-webkit-min-device-pixel-ratio: 2) {
  div {
    border: 0.5px solid #dfdfdf;
  }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
  div {
    border: 0.333333px solid #dfdfdf;
  }
}

无法兼容安卓设备和iOS8以下的设备。

2、用border-image实现

.border-image-1px {
  border-bottom: 1px solid #dfdfdf;
}
@media screen and (-webkit-min-device-pixel-ratio: 2) {
  .border-image-1px {
    border-bottom: none;
    border-width: 0 0 1px 0;
    -webkit-border-image: url(../img/dot.png) 0 0 2 0 stretch;
    border-image: url(../img/dot.png) 0 0 2 0 stretch;
  }
}

修改颜色麻烦,需要替换图片,圆角需要特殊处理。

3、用background-image实现

@media screen and (-webkit-min-device-pixel-ratio: 2) {
  .background-image-1px {
    background: url(../img/line.png) repeat-x left bottom;
    -webkit-background-size: 100% 1px;
    background-size: 100% 1px;
  }
}

修改颜色麻烦,需要替换图片,圆角需要特殊处理。

4、用多背景渐变实现

@media screen and (-webkit-min-device-pixel-ratio: 2) {
  .background-gradient-1px {
    background:
      linear-gradient(#dfdfdf, #dfdfdf 100%, transparent 100%) left / 1px 100% no-repeat,
      linear-gradient(#dfdfdf, #dfdfdf 100%, transparent 100%) right / 1px 100% no-repeat,
      linear-gradient(#dfdfdf,#dfdfdf 100%, transparent 100%) top / 100% 1px no-repeat,
      linear-gradient(#dfdfdf,#dfdfdf 100%, transparent 100%) bottom / 100% 1px no-repeat
  }
}

/* 或者 */

@media screen and (-webkit-min-device-pixel-ratio: 2) {
  .background-gradient-1px{
    background:
      -webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #dfdfdf), to(#dfdfdf)) left / 1px 100% no-repeat,
      -webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #dfdfdf), to(#dfdfdf)) right / 1px 100% no-repeat,
      -webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #dfdfdf), to(#dfdfdf)) top / 100% 1px no-repeat,
      -webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #dfdfdf), to(#dfdfdf)) bottom / 100% 1px no-repeat
  }
}

圆角没法实现,多背景图片有兼容性问题。

5、用box-shadow实现

.box-shadow-1px {
  box-shadow: inset 0px -1px 1px -1px #dfdfdf;
}

边框有阴影,颜色变浅。
6、用viewport+rem实现

devicePixelRatio=2时,

<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">

devicePixelRatio=3时,

<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">

这种兼容方案相对比较完美,适合新的项目,老的项目修改成本过大。
手淘H5页面就采用了Flexible技术,核心是viewport+rem。

7、用伪元素+transform实现
原理是,把元素的border去掉,然后利用:before或者:after重做border,并让transform的 scale缩小一半,元素本身相对定位,新做的border绝对定位。

@media only screen and (-webkit-min-device-pixel-ratio: 2.0){
  .border-1px, .border-top-1px, .border-right-1px ,.border-bottom-1px , .border-left-1px{
    position: relative;
    border:none;
  }
  /*线条颜色*/
  .border-1px:after, .border-top-1px:after, .border-right-1px:after, .border-bottom-1px:after, .border-left-1px:after {
    background-color: #f00;
  }

  /*上边边框一像素*/
  .border-top-1px:after {
    pointer-events: none;
    content:"";
    position: absolute;
    left:;
    top:;
    width: 100%;
    height: 1px;
    transform-origin: 0 0;
    transform: scaleY(0.5);
  }
  /*右边边框一像素*/
  .border-right-1px:after {
    pointer-events: none;
    content:"";
    position: absolute;
    right:;
    bottom:;
    width: 1px;
    height: 100%;
    transform-origin: 0 0;
    transform: scaleX(0.5);
  }
  /*底边边框一像素*/
  .border-bottom-1px:after {
    pointer-events: none;
    content:"";
    position: absolute;
    left:;
    bottom:;
    width: 100%;
    height: 1px;
    transform-origin: 0 0;
    transform: scaleY(0.5);
  }
  /*左边边框一像素*/
  .border-left-1px:after {
    pointer-events: none;
    content:"";
    position: absolute;
    left:;
    top:;
    width: 1px;
    height: 100%;
    transform-origin: 0 0;
    transform: scaleX(0.5);
  }

  /*边框一像素*/
  .border-1px:after {
    pointer-events: none;
    content: "";
    box-sizing: border-box;
    position: absolute;
    left:;
    top:;
    width: 200%;
    height: 200%;
    border: 1px solid #dfdfdf;
    -webkit-transform: scale(0.5);
    transform: scale(0.5);
    -webkit-transform-origin: left top;
    transform-origin: left top;
  }
}
@media only screen and (-webkit-min-device-pixel-ratio: 3.0){
  .border-1px, .border-top-1px, .border-right-1px ,.border-bottom-1px , .border-left-1px{
    position: relative;
    border:none;
  }
  /*线条颜色*/
  .border-1px:after, .border-top-1px:after, .border-right-1px:after, .border-bottom-1px:after, .border-left-1px:after {
    background-color: #f00;
  }

  /*上边边框一像素*/
  .border-top-1px:after {
    pointer-events: none;
    content:"";
    position: absolute;
    left:;
    top:;
    width: 100%;
    height: 1px;
    transform-origin: 0 0;
    transform: scaleY(0.333);
  }
  /*右边边框一像素*/
  .border-right-1px:after {
    pointer-events: none;
    content:"";
    position: absolute;
    right:;
    bottom:;
    width: 1px;
    height: 100%;
    transform-origin: 0 0;
    transform: scaleX(0.333);
  }
  /*底边边框一像素*/
  .border-bottom-1px:after {
    pointer-events: none;
    content:"";
    position: absolute;
    left:;
    bottom:;
    width: 100%;
    height: 1px;
    transform-origin: 0 0;
    transform: scaleY(0.333);
  }
  /*左边边框一像素*/
  .border-left-1px:after {
    pointer-events: none;
    content:"";
    position: absolute;
    left:;
    top:;
    width: 1px;
    height: 100%;
    transform-origin: 0 0;
    transform: scaleX(0.333);
  }

  /*边框一像素*/
  .border-1px:after {
    pointer-events: none;
    content: "";
    box-sizing: border-box;
    position: absolute;
    left:;
    top:;
    width: 300%;
    height: 300%;
    border: 1px solid #dfdfdf;
    -webkit-transform: scale(0.333);
    transform: scale(0.333);
    -webkit-transform-origin: left top;
    transform-origin: left top;
  }
}

移动端1px边框实现的更多相关文章

  1. 移动端1px边框

    问题:移动端1px边框,看起来总是2倍的边框大小,为了解决这个问题试用过很多方法,用图片,用js判断dpr等,都不太满意, 最后找到一个还算好用的方法:伪类 + transform 原理是把原先元素的 ...

  2. 移动端1px边框伪类宽高计算

    移动端1px边框在手机上看显得比较粗,于是我们用伪类结合css3缩放的方法去设置线条,但是如果设置div的一条边,水平线就设置宽度100%,垂直线就设置高度100%,那么如果是div的四条边呢?宽高1 ...

  3. 目前解决移动端1px边框最好的方法

    在移动端开发时,经常会遇到在视网膜屏幕中元素边框变粗的问题.本文将带你探讨边框变粗问题的产生原因及介绍目前市面上最好的解决方法. 1px 边框问题的由来 苹果 iPhone4 首次提出了 Retina ...

  4. 移动端1px边框问题

    用于手机端受dpr的影响,实际开发中,PC端和移动端展示的效果不太一样,往往在PC端显示的是1px,移动端常常是偏粗一些. 解决办法: 主要是用到伪类及缩放.在需要画边框的元素上,设置一个伪类,它的伪 ...

  5. 解决CSS移动端1px边框问题

    移动项目开发中,安卓或者IOS等高分辨率屏幕会把1px的border渲染成2px来显示,网上搜了一下,解决方法如下: 一.利用css中的transform的缩放属性解决,推荐这个.如下面代码. < ...

  6. 移动端1px边框解决方案

    在retina屏中,像素比为2(iPhone6/7/8)或3(iPhone6Plus/7Plus/8Plus),1px的边框看起来比真的1px更宽. 使用伪类加transform的方式 元素本身不定义 ...

  7. 解决移动端1px边框问题的几种方法

    1.边框粗细原因 在移动端下设置border为1px,在某些设备上看比1px粗. 这些由于不同的手机有不同的像素密度.在window对象中有一个devicePixelRatio属性,他可以反应css中 ...

  8. 移动端1px 边框完整方案(四个方向)

    使用stylus(预处理) 需要一个函数接收两个参数 第一个需要在哪个方向出现边框 第二个边框颜色 $border1px(face,$color) 根据传入的方向属性,调整其他参数 l  左右方向 t ...

  9. 关于移动端1px边框问题

    <div class="z_nei_list"> <div class="z_name_left font-size3">身份证号:&l ...

随机推荐

  1. [模板]快速傅里叶变换(FFT)

    Miskcoo大佬的多项式全家桶传送门 rvalue大佬的FFT讲解传送门 用途 将多项式快速(nlogn)变成点值表达,或将点值表达快速变回系数表达(逆变换),(多数时候)来达到求卷积的目的 做法 ...

  2. MQ服务器奔溃解决过程

    1.MQ服务器崩溃调节: 今天具安卓前端反应, 从昨天下午开始线上服务器使用 电话号码登陆和 使用电话号码注册功能不能使用, 经过前端仔细排查怀疑是后端问题,之后经过与ios前端 确认, 定位为后端服 ...

  3. 金融量化分析【day112】:双均线策略

    一.双均线策略 1.什么是双均线策略? 2.实现代码 def initialize(context): set_benchmark('601318.XSHG') set_option('use_rea ...

  4. swiper常见问题

    swiper是一个比较不错的一个轮播插件,但是呢,有时候在使用的时候也会出现很多的问题,我将我遇到的一些问题解决办法写在下面. 第一个问题:swiper分页器不显示 一般swiper使用分页器都是这样 ...

  5. 第三节: Quartz.Net五大构件之Scheduler(创建、封装、基本方法等)和Job(创建、关联等)

    一. 五大构件 引言: Quartz.Net的五大构件 1.  调度器:Scheduler 2.  作业任务:Job 3.  触发器: Trigger 4.  线程池: SimpleThreadPoo ...

  6. Java String相关

    一.String类的常用方法 1. int indexOf(String s) 字符串查找 2. int lastIndexOf(String str) 3. char charAt(int inde ...

  7. sort注意事项

    虽然是小事但是还是得注意一下:sort 区间左开右闭 从0开始 e.g: 10 9 8 7 6 5 4 3 2 1 sort(a+6,a+11)  区间 6 - 10 sort(a+6,a+10)  ...

  8. DUMP3.5 企业级电商项目

    购物车模块 加入商品 更新商品数 查询商品数 移除商品 单选/取消 全选/取消  购物车列表 [浮点型商业运算精度丢失问题]ej1st 一书提到 float double只适合科研计算,BigDeci ...

  9. CSRF篇-本着就了解安全本质的想法,尽可能的用通俗易懂的语言去解释安全漏洞问题

    0x01 Brief Description csrf 跨站伪造请求,请求伪造的一种,是由客户端即用户浏览器发起的一种伪造攻击.攻击的本质是请求可以被预测的到. 在了解csrf攻击之前,需要了解浏览器 ...

  10. Educational Codeforces Round 52 (Rated for Div. 2)

    题目链接 A. Vasya and Chocolate 题意 已知钱,价格,赠送规则求最多获得巧克力数 思路常规算即可 代码 #include <bits/stdc++.h> #defin ...