移动端开发页面时,为了高度还原设计稿,开发中时常会遇到1px问题。下面是个人的一些理解。
什么是1px问题?
先来看如下代码,由于设置了1px的底边框,浏览器在渲染该元素时,会为该元素设置1px底边框,但在不同的屏幕上边框显示的效果不理想,有些屏幕上显示的会比效果图粗很多。div { border-bottom: 1px solid #ccc; }
这是因为现代的高分辨率屏大都是视网膜屏,不同的视网膜屏会用不同个数的物理像素来表现CSS中的1px(例如dpr=2的视网膜屏就会用2个物理像素的宽度来表现1px,dpr=3的则用3个物理像素来表现),由于表现1px所用到的物理像素个数不同,所以使得显示的效果的不同。这就是1px问题。
总之,解决1px问题,就是解决如何在不同的视网膜屏上均以1个物理像素的宽度来表现CSS中的1px。
解决思路一:通过css的transform: scale 来实现。(略)
解决思路二:通过html设置header的mate来实现。
在入口html页面中添加如下代码,可以放在document的DOMCcontentLoaded事件中,或window的onload事件中:
// 1. 获取header中的viewport
var viewport = document.querySelector("meta[name=viewport]");
// 2. 如果viewport 为空,则创建(略)
// 3. 根据设备像素设置viewport
if (window.devicePixelRatio == 1) {
viewport.setAttribute('content', 'width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no');
}
if (window.devicePixelRatio == 2) {
viewport.setAttribute('content', 'width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');
}
if (window.devicePixelRatio == 3) {
viewport.setAttribute('content', 'width=device-width,initial-scale=0.3333333333333333, maximum-scale=0.3333333333333333, minimum-scale=0.3333333333333333, user-scalable=no');
}
通过上述js 代码即可实现让浏览器用相同个数物理像素的宽度来表示css像素。
设置前后的效果图对比
代码只为了理解问题和解决思路,不代表实际应用,存在问题:
- 只考虑了dpr为3/2/1 的视网膜屏;
- 动态改变了initial-scale的值,会影响到其他元素的显示。这就引发了另外的一个问题:移动端的响应式布局
至此,结束。