1px 边框问题
下文出自7 种方法解决移动端 Retina 屏幕 1px 边框问题
造成边框变粗的原因
其实这个原因很简单,因为 css 中的 1px 并不等于移动设备的 1px,这些由于不同的手机有不同的像素密度。在 window 对象中有一个 devicePixelRatio 属性,他可以反应 css 中的像素与设备的像素比。
devicePixelRatio 的官方的定义为:设备物理像素和设备独立像素的比例,也就是 devicePixelRatio = 物理像素 / 独立像素。
0.5px 边框
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() {})
div {
border: 1px solid #bbb;
}
.hairlines div {
border-width: 0.5px;
}
使用 border-image 实现
/* 底部边框 */
.border-bottom-1px {
border-width: 0 0 1px 0;
-webkit-border-image: url(linenew.png) 0 0 2 0 stretch;
border-image: url(linenew.png) 0 0 2 0 stretch;
}
/* 上下边框 */
.border-image-1px {
border-width: 1px 0;
-webkit-border-image: url(linenew.png) 2 0 stretch;
border-image: url(linenew.png) 2 0 stretch;
}
/* 使用Media Query做兼容 */
.border-image-1px {
border-bottom: 1px solid #666;
}
@media only 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/linenew.png) 0 0 2 0 stretch;
border-image: url(../img/linenew.png) 0 0 2 0 stretch;
}
}
使用 background-image 实现
.background-image-1px {
background: url(../img/line.png) repeat-x left bottom;
-webkit-background-size: 100% 1px;
background-size: 100% 1px;
}
多背景渐变实现
.background-gradient-1px {
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;
}
/* 或者 */
.background-gradient-1px {
background: -webkit-gradient(
linear,
left top,
left bottom,
color-stop(0.5, transparent),
color-stop(0.5, #c8c7cc),
to(#c8c7cc)
) left bottom repeat-x;
background-size: 100% 1px;
}
使用 box-shadow 模拟边框
.box-shadow-1px {
box-shadow: inset 0px -1px 1px -1px #c8c7cc;
}
viewport + rem 实现
同时通过设置对应 viewport 的 rem 基准值,这种方式就可以像以前一样轻松愉快的写 1px 了。在 devicePixelRatio = 2 时,输出 viewport:
在devicePixelRatio = 3 时,输出viewport:
```html
这种兼容方案相对比较完美,适合新的项目,老的项目修改成本过大。对于这种方案,可以看看《使用 Flexible 实现手淘 H5 页面的终端适配》
伪类 + transform 实现
单条 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;
}
四条 boder 样式设置:
.scale-1px {
position: relative;
margin-bottom: 20px;
border: none;
}
.scale-1px:after {
content: "";
position: absolute;
top: 0;
left: 0;
border: 1px solid #000;
-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;
}
if (window.devicePixelRatio && devicePixelRatio >= 2) {
document.querySelector("ul").className = "scale-1px";
}