不同屏幕分辨率实现 1px 边框
造成边框实际不是 1px 原因
实际场景:在
Reina
(视网膜)屏幕的手机上,使用CSS
设置的1px
的边框实际会比视觉稿粗很多。
因为css
中的1px
并不等于移动设备的1px
,这些由于不同的手机有不同的像素密度。在window
对象中有一个devicePixelRatio
属性,他可以反应css
中的像素与设备的像素比。
devicePixelRatio
官方定义:设备物理像素和设备独立像素的比例,也就是devicePixelRatio = 物理像素 / 独立像素
。
实现 1px 边框的方式
1. 使用background-image实现
先准备一张符合你要求的图片。然后将边框模拟在背景上。
.background-image-1px {
background: url(../img/line.png) repeat-x left bottom;
-webkit-background-size: 100% 1px;
background-size: 100% 1px;
}
- 优点:
- 可以设置单条,多条边框
- 没有性能瓶颈的问题
- 缺点:
- 修改颜色麻烦, 需要替换图片
- 圆角需要特殊处理,并且边缘会模糊
2. 伪类 + transform 实现
把原先元素的 border
去掉,然后利用 :before
或者 :after
重做 border
,并 transform
的 scale
缩小一半,原先的元素相对定位,新做的 border
绝对定位。
单条border样式设置:
.scale-1px{
position: relative;
border:none;
}
.scale-1px:after{
content: '';
position: absolute;
bottom: 0;
background: #000;
width: 100%;
height: 1px;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
最好在使用前也判断一下,结合 JS 代码,判断是否 Retina 屏
if(window.devicePixelRatio && devicePixelRatio >= 2){
document.querySelector('ul').className = 'scale-1px';
}
- 优点:
- 所有场景都能满足
- 支持圆角(伪类和本体类都需要加border-radius)
- 缺点:
对于已经使用伪类的元素(例如clearfix),可能需要多层嵌套
3. viewport + rem 实现
通过设置对应viewport的rem
基准值 (viewport属性详解)
在devicePixelRatio = 2
时,输出viewport
:
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
在devicePixelRatio = 3
时,输出viewport
:
<meta name="viewport" content="initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no">
- 优点:
- 所有场景都能满足
- 一套代码,可以兼容基本所有布局
- 缺点:
老项目修改代价过大,只适用于新项目
4. 使用box-shadow模拟边框
利用css
对阴影处理的方式实现0.5px
的效果
样式设置:
.box-shadow-1px {
box-shadow: inset 0px -1px 1px -1px #c8c7cc;
}
- 优点:
- 代码量少
- 可以满足所有场景
- 缺点:
边框有阴影,颜色变浅
5. 多背景渐变实现
与background-image
方案类似,只是将图片替换为css3
渐变。设置1px
的渐变背景,50%
有颜色,50%
透明。
样式设置:
.background-gradient-1px {
background:
linear-gradient(#000, #000 100%, transparent 100%) left / 1px 100% no-repeat,
linear-gradient(#000, #000 100%, transparent 100%) right / 1px 100% no-repeat,
linear-gradient(#000,#000 100%, transparent 100%) top / 100% 1px no-repeat,
linear-gradient(#000,#000 100%, transparent 100%) bottom / 100% 1px no-repeat
}
/* 或者 */
.background-gradient-1px{
background:
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) left / 1px 100% no-repeat,
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) right / 1px 100% no-repeat,
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) top / 100% 1px no-repeat,
-webkit-gradient(linear, left top, right bottom, color-stop(0, transparent), color-stop(0, #000), to(#000)) bottom / 100% 1px no-repeat
}
- 优点:
- 可以实现单条、多条边框
- 边框的颜色随意设置
- 缺点:
- 代码量不少
- 圆角没法实现
- 多背景图片有兼容性问题
总结: 以上是常见的1px
边框问题的实现方式,各有优缺点,实际项目开发过程中,可根据需求场景选择合适的实现方式。