7 种方案解决移动端1px边框的问题

7 种方案解决移动端1px边框的问题

造成边框变粗的原因

css中的1px并不等于移动设备的1px,这是由不同手机由不同像素密度,在window对象中有一个devicePixelRatio属性,他可以反应css中像素与设备的像素比

devicePixelRatio 的官方给的定义为: 设备物理像素和设备独立像素的比例,也就是devicePixelRatio = 物理像素 / 独立像素。

解决边框变粗的6种办法

总结:

  • 根据判断像素比大于等于2时,

1、0.5px边框

scss 复制代码
if(window.devicePixelRatio && devicePixelRatio>=2){
  var testElem = document.createElement('div')
  testElem.style.border = '.5px solid transparent'
  document.body.appendChild(testElem)
  if(testElem.offsetHeight ==1){
    document.querySelector('html').classList.add('hairlines')
  }
  document.body.removeChild(testElem);
}
// 脚本放在内联,如果里面运行 需要包装$(document).ready(function(){})
css 复制代码
div{
  border: 1px solid #bbb
}
.hairlines div {
  border-width: 0.5px;
}

2、使用border-image实现

准备一张符合要求的border-image

底部边框

css 复制代码
.border-bottom-1px{
  border-width: 0 0 1px 0 ;
  border-image: url(linenew.png) 0 0 2 0 stretch;
  -webkit-border-image: url(linenew.png) 0 0 2 0 stretch;
}

把border设置在底部,图片2px高,上面1px颜色透明,下面1px使用规定的border颜色

3、使用background-image实现

和border-image实现类似,需要事先准备好图片

css 复制代码
.backround-image-1px{
  background: url(../img/line.png) repeat-x left bottom;
  -wibkit-background-size:100% 1px;
  background-size:100% 1px;
}

缺点:

  • 修改颜色麻烦,需要替换图片
  • 圆角需要特别处理,边缘会模糊

4、利用多背景渐变实现

与background-image类似,把图片改成渐变的背景,一半设置颜色,一半设置透明

scss 复制代码
.background-gradient-1px{
  background:
    line-gradient(180deg, black,black 50%, transparent 50%) top left / 100% 1px no-repeat;
    line-gradient(90deg, black,black 50%, transparent 50%) top right / 1px 100% no-repeat;
    line-gradient(0, black,black 50%, transparent 50%) bottom right /  100% 1px no-repeat;
    line-gradient(-90deg, black,black 50%, transparent 50%) bottom left / 1px 100% no-repeat;
}
/*或者*/
.background-gradient-1px{
    background: -webkit-gradient(linear,left top, left bottom, color-step(.5,transparent),
                color-step(.5,#c8c7cc), to(#c8c7cc)) left bottom repeat-x;
    background-size: 100% 1px;
}

5、利用box-shadow模拟边框

css阴影的方式处理

css 复制代码
.box-shadow-1px{
  box-shadow: inset 0px -1px 1px -1px #c8c7cc
}

6、viewport + rem 实现

同时通过设置对应的viewport的rem基准值, 解决了1像素bug

这种方式比较完美,对老版本的修改不友好

优点:所有场景都能满足,一套代码,可以兼容所有布局

缺点:老项目修改代价过大

ini 复制代码
// 在devicePixlRatio = 1 时, 输出viewport
<mate name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
      
// 在devicePixlRatio = 2 时, 输出viewport
<mate name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no">
  
// 在devicePixlRatio = 3 时, 输出viewport
<mate name="viewport" content="initial-scale=0.333333,maximum-scale=0.333333,minimum-scale=0.333333,user-scalable=no">
xml 复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width,initial-scale=1,user-scalable=no"
    />
    <title>rem+viewport适配</title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      #box {
        width: 8rem;
        height: 8rem;
        border: 1px solid #000;
      }
    </style>
  </head>
  <body>
    <div id="box"></div>
  </body>
  <script type="text/javascript">
    //获取dpr
    var dpr = window.devicePixelRatio; // 2
    console.log(dpr, 'dpr+++');
    //比例              // 0.5
    var scale = 1 / dpr;
    var width = document.documentElement.clientWidth; //375
    //3.通过dpr让元素进行缩放,initial-scale=0.5
    var metaNode = document.querySelector('meta[name="viewport"]');
    metaNode.setAttribute(
      'content',
      'width=device-width,initial-scale=' + scale + ',user-scalable=no'
    );
    var width = document.documentElement.clientWidth; //750
    //4.布局元素 单位 rem ,反向把缩放比例乘回来  2
    var styleN = document.createElement('style');
    styleN.innerHTML = 'html{font-size: ' + width / 16 + 'px !important;}';
    document.head.appendChild(styleN);
  </script>
</html>

7、使用伪类+transform实现

对于老项目,这种方案比较完美, 原理是把原来的所有边框去掉,通过伪类崇左border,并且transform的scale缩小一半,原先的单挑border样式设置

css 复制代码
.scale-1px{
  position:relative;
  border:none;
}
.scale-1px:after{
  content: '';
  position:absolute;
  bottom:0;
  background: #000;
  width:100%;
  height:1px;
  transform:scale(0.5);
  transform-origin: 0 0;
}

.scale-1px-top {
  /* border-bottom: 1px solid rgb(229, 229, 229); */
  /* box-shadow: inset 0px -1px 1px -1px #c8c7cc; */
  border:none;
  position:relative;
}
.scale-1px-top:before{
  content: '';
  position: absolute;
  display:block;
  top: 0;
  left: 0;
  width: 200%;
  height: 1px;
  border-top: 1px solid #E7E7E7;
  -webkit-transform: scale(0.5,0.5);
  transform: scale(0.5,0.5);
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
}

.scale-1px-bottom {
  /* border-bottom: 1px solid rgb(229, 229, 229); */
  /* box-shadow: inset 0px -1px 1px -1px #c8c7cc; */
  border:none;
  position:relative;
}
.scale-1px-bottom:before{
  content: '';
  position: absolute;
  display:block;
  bottom: -1px;
  left: 0;
  width: 200%;
  height: 1px;
  border-bottom: 1px solid #ccc;
  -webkit-transform: scale(0.5,0.5);
  transform: scale(0.5,0.5);
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
}

.borderRadius-1px {
  /* border-bottom: 1px solid rgb(229, 229, 229); */
  /* 圆角(伪类和本体类都需要加border-radius) */
  border-radius:.16rem;
  border:none;
  position:relative;
}
.borderRadius-1px:after{
  /* 圆角(伪类和本体类都需要加border-radius) */
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  border: 1px solid #d1d1d1;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  width: 200%;
  height: 200%;
  -webkit-transform: scale(0.5);
  transform: scale(0.5);
  -webkit-transform-origin: left top;
  transform-origin: left top;
  border-radius:.16rem;
}

8 、svg

css 复制代码
<svg width=100% height=1   style="position: absolute;bottom: 0;left: 0;">
 <line x1="0" y1="0" x2="1000" y2="0" style="stroke:#E5E5E5;stroke-width:1" />
</svg>
相关推荐
我要洋人死1 小时前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼3 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風7 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#