# 1px 边框问题 [7 种方法解决移动端 Retina 屏幕 1px 边框问题](https://juejin.im/entry/584e427361ff4b006cd22c7c) [在 retina 屏中实现 1px border 效果](http://imweb.io/topic/55e3d402771670e207a16bd1) #### 下文出自[7 种方法解决移动端 Retina 屏幕 1px 边框问题](https://juejin.im/entry/584e427361ff4b006cd22c7c) ### 造成边框变粗的原因 其实这个原因很简单,因为 css 中的 1px 并不等于移动设备的 1px,这些由于不同的手机有不同的像素密度。在 window 对象中有一个 devicePixelRatio 属性,他可以反应 css 中的像素与设备的像素比。 > devicePixelRatio 的官方的定义为:设备物理像素和设备独立像素的比例,也就是 devicePixelRatio = 物理像素 / 独立像素。 ### 0.5px 边框 ```js 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; } ``` ### 使用 border-image 实现 ```css /* 底部边框 */ .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 实现 ```css .background-image-1px { background: url(../img/line.png) repeat-x left bottom; -webkit-background-size: 100% 1px; background-size: 100% 1px; } ``` ### 多背景渐变实现 ```css .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 模拟边框 ```css .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 样式设置: ```css .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 样式设置: ```css .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; } ``` ```js if (window.devicePixelRatio && devicePixelRatio >= 2) { document.querySelector("ul").className = "scale-1px"; } ```