移动端1像素边框问题与CSS媒体查询

作移动端页面开发时,咱们是按照UI设计图上的尺寸来作的。css

好比说,UI给的图是750x1344(Iphone6标准),咱们在浏览器作适配时,按照375x667来裁切,设计图上30像素的高度,开发时使用的是15px,这是由于Iphone6的设备像素比为2,css中的1px在设备中的像素为2px。当咱们须要实现设计图中1px高度的边框时,在css中的1px实际上变成了2px边框,由此产生了1像素边框问题。html

一、window.devicePixelRatio设备像素比html5

定义:android

window.devicePixelRatio是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例。
公式表示就是:window.devicePixelRatio = 物理像素 / dipsweb

引用自张鑫旭大神的文档浏览器

用于描述整个渲染环境在硬件设备上的缩放程度,在程序中能够经过window.devicePixelRatio属性来获得这个值。app

与之相关的概念以下:iphone

物理像素(physical pixel):设备能控制显示的最小单位。
设备独立像素(DIP,device-independent pixel,density-independent pixel):独立于设备的用于逻辑上衡量像素的单位。
每英寸像素量(PPI,pixels per inch):一英寸长度上能够并排的像素数量。ide

正常人眼能够识别的分辨率为300PPI,而如今不少设备的分辨率都超过了300PPI。若是设备老是以满分辨率来显示东西就可能形成文字过小,人们看不清。所以像浏览器这样的软件就会对内容作一次放大后再进行渲染,也就是下降分辨率。要下降分辨率就须要让像素这个单位变大,所以PPI的计算再也不使用物理像素,而改用设备独立像素。那么设备独立像素和物理像素之间就存在一个比例差别,这就是设备像素比。
单位dppx(dots per pixel)表示每一个DIP占用几个物理像素。能够理解为,CSS中的单位px在屏幕上占用了多少物理像素。wordpress

引用自https://www.web-tinker.com/article/20590.html

 二、经常使用解决方案

2-一、border.css方案

在添加border样式的元素上设置:before和:after样式,而后在媒体查询中根据device-pixel-ratio的值来缩放对应宽度和高度,来达到边框大小为物理像素1px

@charset "utf-8"; .border, .border-top, .border-right, .border-bottom, .border-left, .border-topbottom, .border-rightleft, .border-topleft, .border-rightbottom, .border-topright, .border-bottomleft { position: relative;
} .border::before, .border-top::before, .border-right::before, .border-bottom::before, .border-left::before, .border-topbottom::before, .border-topbottom::after, .border-rightleft::before, .border-rightleft::after, .border-topleft::before, .border-topleft::after, .border-rightbottom::before, .border-rightbottom::after, .border-topright::before, .border-topright::after, .border-bottomleft::before, .border-bottomleft::after { content: "\0020"; overflow: hidden; position: absolute;
}
/* border * 因,边框是由伪元素区域遮盖在父级 * 故,子级如有交互,须要对子级设置 * 定位 及 z轴 */ .border::before { box-sizing: border-box; top: 0; left: 0; height: 100%; width: 100%; border: 1px solid #eaeaea; transform-origin: 0 0;
} .border-top::before, .border-bottom::before, .border-topbottom::before, .border-topbottom::after, .border-topleft::before, .border-rightbottom::after, .border-topright::before, .border-bottomleft::before { left: 0; width: 100%; height: 1px;
} .border-right::before, .border-left::before, .border-rightleft::before, .border-rightleft::after, .border-topleft::after, .border-rightbottom::before, .border-topright::after, .border-bottomleft::after { top: 0; width: 1px; height: 100%;
} .border-top::before, .border-topbottom::before, .border-topleft::before, .border-topright::before { border-top: 1px solid #eaeaea; transform-origin: 0 0;
} .border-right::before, .border-rightbottom::before, .border-rightleft::before, .border-topright::after { border-right: 1px solid #eaeaea; transform-origin: 100% 0;
} .border-bottom::before, .border-topbottom::after, .border-rightbottom::after, .border-bottomleft::before { border-bottom: 1px solid #eaeaea; transform-origin: 0 100%;
} .border-left::before, .border-topleft::after, .border-rightleft::after, .border-bottomleft::after { border-left: 1px solid #eaeaea; transform-origin: 0 0;
} .border-top::before, .border-topbottom::before, .border-topleft::before, .border-topright::before { top: 0;
} .border-right::before, .border-rightleft::after, .border-rightbottom::before, .border-topright::after { right: 0;
} .border-bottom::before, .border-topbottom::after, .border-rightbottom::after, .border-bottomleft::after { bottom: 0;
} .border-left::before, .border-rightleft::before, .border-topleft::after, .border-bottomleft::before { left: 0;
} @media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {
    /* 默认值,无需重置 */
} @media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) { .border::before { width: 200%; height: 200%; transform: scale(.5);
    } .border-top::before, .border-bottom::before, .border-topbottom::before, .border-topbottom::after, .border-topleft::before, .border-rightbottom::after, .border-topright::before, .border-bottomleft::before { transform: scaleY(.5);
    } .border-right::before, .border-left::before, .border-rightleft::before, .border-rightleft::after, .border-topleft::after, .border-rightbottom::before, .border-topright::after, .border-bottomleft::after { transform: scaleX(.5);
    } } @media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) { .border::before { width: 300%; height: 300%; transform: scale(.33333);
    } .border-top::before, .border-bottom::before, .border-topbottom::before, .border-topbottom::after, .border-topleft::before, .border-rightbottom::after, .border-topright::before, .border-bottomleft::before { transform: scaleY(.33333);
    } .border-right::before, .border-left::before, .border-rightleft::before, .border-rightleft::after, .border-topleft::after, .border-rightbottom::before, .border-topright::after, .border-bottomleft::after { transform: scaleX(.33333);
    } }

2-二、 lib-flexible.js-淘宝移动端方案

根据当前设备的window.devicePixelRatio,来设置viewport中的缩放比例,以达到设备物理像素=css像素

if (!dpr && !scale) { var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/iphone/gi); var devicePixelRatio = win.devicePixelRatio; if (isIPhone) { // iOS下,对于2和3的屏,用2倍的方案,其他的用1倍方案
        if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 其余设备下,仍旧使用1倍的方案
        dpr = 1; } scale = 1 / dpr; }
......
var metaEl = doc.createElement('meta'); var scale = isRetina ? 0.5:1; metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); if (docEl.firstElementChild) { document.documentElement.firstElementChild.appendChild(metaEl); } else { var wrap = doc.createElement('div'); wrap.appendChild(metaEl); documen.write(wrap.innerHTML); }

引用https://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html

三、用到的css媒体查询

@media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx)
max-device-pixel-ratio:设备像素比
max--moz-device-pixel-ratio:能够用于兼容版本号低于16的Firefox浏览器
-webkit-max-device-pixel-ratio:基于webkit的浏览器不支持dppx
max-resolution:指定输出设备的分辨率(像素密度),可替换老旧的 (max-device-pixel-ratio: 2)。分辨率能够用每英寸(dpi)或每厘米(dpcm)的点数来表示。此处表示最大分辨率
@media (-webkit-min-device-pixel-ratio: 2), /* Webkit-based browsers */ (min--moz-device-pixel-ratio: 2), /* Older Firefox browsers (prior to Firefox 16) */ (min-resolution: 2dppx), /* The standard way */ (min-resolution: 192dpi) /* dppx fallback */

引用https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Media_queries

相关文章
相关标签/搜索