移动端1px变粗的原因

移动端css里面写了1px,实际比1px粗。
其实原因很好理解:这两个’px’的含义是不一样的。
移动端的

头里有这样一段代码:

  1. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

代码解析:
name=”viewport” content=”width=device-width:本页面的 “ viewport” 的宽度为设备宽度。
initial-scale=1.0, maximum-scale=1.0:初始缩放值和最大的缩放值都为1。
user-scalable=no:禁止用户进行页面缩放。
移动端 window 对象有个 devicePixelRatio 属性,为设备投入比。
「drp = window.devicePixelRatio,也就是设备的物理指示与逻辑指示的比值。」
「以iPhone6应该:」
它的物理推测是750,逻辑推测为375,所以iphone6的drp = 2。
所以css里面写的1px宽度映射到物理预定上就有2px。

解决方案

一,使用小数来写px值

在ios8 +中当drp = 2的时候使用0.5px,使用媒体查询

  1. .border { border: 1px solid #999 }
  2. @media screen and (-webkit-min-device-pixel-ratio: 2) {
  3. .border { border: 0.5px solid #999 }
  4. }
  5. @media screen and (-webkit-min-device-pixel-ratio: 3) {
  6. .border { border: 0.333333px solid #999 }
  7. }

二,使用box-shadow模拟边框

利用css对阴影处理的方式实现0.5px的效果

  1. .box-shadow-1px {
  2. box-shadow: inset 0px -1px 1px -1px #c8c7cc;
  3. }


三,伪类 :之前,:之后与转换

构建1个伪元素,将其的长宽放大到2倍,边框宽度设置为1px,再用transform缩放到50%。
我这里只写了上下边框,还有左右边框,你们可以模仿一下。

  1. //所有边框
  2. .mx-1px {
  3. position: relative
  4. }
  5. .mx-1px:before {
  6. position: absolute;
  7. content: "";
  8. width: 100%;
  9. height: 100%;
  10. border: 1px solid #ccc;
  11. border-radius: 0;
  12. top: 0;
  13. left: 0;
  14. -webkit-transform-origin: 0 0;
  15. transform-origin: 0 0;
  16. box-sizing: border-box
  17. }
  18. @media screen and (-webkit-min-device-pixel-ratio: 2) {
  19. .mx-1px:before {
  20. width: 200%;
  21. height: 200%;
  22. -webkit-transform: scale(.5);
  23. transform: scale(.5)
  24. }
  25. }
  26. //上边框
  27. .mx-1px-top {
  28. position: relative
  29. }
  30. .mx-1px-top:before {
  31. position: absolute;
  32. content: "";
  33. -webkit-transform-origin: 0 0;
  34. transform-origin: 0 0;
  35. width: 100%;
  36. height: 1px;
  37. border-top: 1px solid #ccc;
  38. top: 0;
  39. left: 0
  40. }
  41. @media screen and (-webkit-min-device-pixel-ratio: 2) {
  42. .mx-1px-top:before {
  43. -webkit-transform: scaleY(.5);
  44. transform: scaleY(.5)
  45. }
  46. }
  47. //下边框
  48. .mx-1px-bottom {
  49. position: relative
  50. }
  51. .mx-1px-bottom:before {
  52. position: absolute;
  53. content: "";
  54. -webkit-transform-origin: 0 0;
  55. transform-origin: 0 0;
  56. width: 100%;
  57. height: 1px;
  58. bottom: -1px;
  59. border-bottom: 1px solid #ccc;
  60. left: 0
  61. }
  62. @media screen and (-webkit-min-device-pixel-ratio: 2) {
  63. .mx-1px-bottom:before {
  64. -webkit-transform: scaleY(.5);
  65. transform: scaleY(.5)
  66. }
  67. }

四,视口+ rem + js 即flexable.js

通过设置对应viewport的scale,这种方式就可以像以前一样轻松愉快的写1px了。
当drp = 1时:initial-scale=1
当drp = 2时:initial-scale=0.5
当drp = 3时:initial-scale=0.3333333333333333

  1. <html>
  2. <head>
  3. <title>1px question</title>
  4. <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  5. <meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
  6. <style>
  7. html {
  8. font-size: 1px;
  9. }
  10. * {
  11. padding: 0;
  12. margin: 0;
  13. }
  14. .top_b {
  15. border-bottom: 1px solid #E5E5E5;
  16. }
  17. .a,.b {
  18. box-sizing: border-box;
  19. margin-top: 1rem;
  20. padding: 1rem;
  21. font-size: 1.4rem;
  22. }
  23. .a {
  24. width: 100%;
  25. }
  26. .b {
  27. background: #f5f5f5;
  28. width: 100%;
  29. }
  30. </style>
  31. <script>
  32. var viewport = document.querySelector("meta[name=viewport]");
  33. //下面是根据设备像素设置viewport
  34. if (window.devicePixelRatio == 1) {
  35. viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');
  36. }
  37. if (window.devicePixelRatio == 2) {
  38. viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');
  39. }
  40. if (window.devicePixelRatio == 3) {
  41. viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');
  42. }
  43. var docEl = document.documentElement;
  44. var fontsize = 32* (docEl.clientWidth / 750) + 'px';
  45. docEl.style.fontSize = fontsize;
  46. </script>
  47. </head>
  48. <body>
  49. <div class="top_b a">下面的底边宽度是虚拟1像素的</div>
  50. <div class="b">上面的边框宽度是虚拟1像素的</div>
  51. </body>
  52. </html>

总结

对于老项目:采用伪类+ transform。
对于新项目:采用viewport的sacle值,这个方法兼容性好。