本文整理了常用的 1 物理像素边框的实现方法及原理。
border-image
关于 border-image 的介绍不多说,可自行参考相关文档。
原理是:将 border-width 设为 1px,在 2 倍屏上使用一个上面透明、下面一个黑色的像素格图片(整体是宽 1x 高 2),相当于垂直方向是 2 个物理像素。用 2 物理像素去填满 1px 的独立像素,自然而然黑色的像素格就占一个物理像素了。3 倍屏同理。
1 2 3 4
| .one-pix-border { border-width: 1px; border-image: url("https://www.tanzhixuan.top/ng-s1/static/upload/img/6be26730/border.png") 50% 10% 0 10% stretch; }
|
缺点:需要制作图片,类似于安卓中的九点图。颜色不能在代码中自定义。
优点:可实现圆角,border-image 的兼容性还不错。
background-image
背景这个,同样可以使用图片来做,但用渐变来做,更简单。如二倍屏下:
1 2 3 4 5 6 7 8 9 10
| .border { background-image: linear-gradient(180deg, red, red 50%, transparent 50%), linear-gradient(270deg, red, red 50%, transparent 50%), linear-gradient(0deg, red, red 50%, transparent 50%), linear-gradient(90deg, red, red 50%, transparent 50%); background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%; background-repeat: no-repeat; background-position: top, right top, bottom, left top; padding: 10px; }
|
viewport+rem 实现
用页面的 devicePixelRadio 设置 meta 中的 viewport:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <html> <head> <title>1px question</title> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <style> html { font-size: 1px; } * { padding: 0; margin: 0; } .bds_b { border-bottom: 1px solid #ccc; } .a, .b { margin-top: 1rem; padding: 1rem; font-size: 1.4rem; } .a { width: 30rem; } .b { background: #f5f5f5; width: 20rem; } </style> <script> var viewport = document.querySelector("meta[name=viewport]"); var scale = 1 / window.devicePixelRadio; viewport.setAttribute('content', `width=device-width,initial-scale==${scale},maximum-scale=${scale},minimum-scale=${scale}, user-scalable=no`); var docEl = document.documentElement; var fontsize = 10 * (docEl.clientWidth / 320) + 'px'; docEl.style.fontSize = fontsize; </script> </head> <body> <div class="bds_b a">下面的底边宽度是虚拟1像素的</div> <div class="b">上面的边框宽度是虚拟1像素的</div> </body>
</html>
|
box-shadow
1 2 3
| .border { box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5); }
|
这个是我认为最优的方案了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| .border { position: relative; border: none; } @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) { .border::after{ position: absolute; left: 0; right: 0; content: ''; width: 200%; height: 200%; border-bottom: 1px solid #000; transform: scaleY(0.5); } } @media (-webkit-min-device-pixel-ratio: 3), (min-resolution: 3dppx) { .border::after{ position: absolute; content: ''; left: 0; right: 0; width: 300%; height: 300%; border-bottom: 1px solid #000; transform: scaleY(0.333333); } }
|