移动端1px边框的问题
2019-10-21 16:38·前端技术精髓前言
应该感觉不止一次会被涉及到关于1px的问题,其主要触发的场景就是高分屏上会把1px宽的边框显示成2px,在dpr为3的设备上,显示边框为3px.
为了避免大家少走弯路,这里简单带一下网上提到的几种方案,包括下面的:
- 边框的图片,border-image
- 背景图片
- 边框的阴影
- 设置viewport的meta属性(不建议使用)
推荐方案:
1 transform
针对边框设置1px之后,在使用transform,需要结合JavaScript代码,用来判断是否是Retina.
.hairlines li{ position: relative; border:none; } .hairlines li:after{ content: ''; position: absolute; left: 0; background: #000; width: 100%; height: 1px; transform: scaleY(0.5); transform-origin: 0 0; }
2 PostCSS的postcss-write-svg
使用PostCSS的插件是不是比我们修改图片要来得简单与方便。
使用PostCSS的postcss-write-svg插件,最后编译完会变成一背景图片样式。比如:
@svg square { @rect { fill: var(--color, black); width: 100%; height: 100%; } } #example { background: white svg(square param(--color #00b1ff)); }
3 0.5px
查看是否兼容设置0.5px的方案,进行兼容性测试,支持就设置这个样式,结合Flexible方案。
if (dpr >= 2) { var fakeBody = document.createElement('body') var testElement = document.createElement('div') testElement.style.border = '.5px solid transparent' fakeBody.appendChild(testElement) docEl.appendChild(fakeBody) if (testElement.offsetHeight === 1) { docEl.classList.add('hairlines') } docEl.removeChild(fakeBody) }
4 伪元素 transform、border-image
京东的1px的方案,边框均是伪元素实现的,但不是所有的样式有实现。
// transform 方案 @media only screen and (-webkit-min-device-pixel-ratio: 2){ .option:after { -webkit-transform: scale(.5); -webkit-transform-origin: 0 0; bottom: -100%; right: -100%; } } option:after { content: ""; display: block; border: 1px solid #ddd; position: absolute; top: 0; bottom: 0; left: 0; right: 0; pointer-events: none; } // border-image方案 .jd-header-bar { position: relative; border-width: 0 0 1px; border-bottom: 1px solid #bfbfbf; -webkit-border-image: url("data:image/gif;base64,R) repeat-x 0 0; background-size: 100% 44px }
5 box-shadow
天锚的方案:box-shadow
.templates-item-wrapper { width: 92%; margin: 0 auto; /* -webkit-box-shadow: 0 1px 2px 0 rgba(157,157,157,.5); */ -moz-box-shadow: 0 1px 2px 0 rgba(157,157,157,.5); /* box-shadow: 0 1px 2px 0 rgba(157,157,157,.5); */ }