CSS 中比一像素还要细的边框

那么CSS中的1px是什么?浏览器是怎么渲染它的?

网页在一个叫viewport的东西里渲染,可以理解为画布,画布被分成 N x M 个小方格,1个CSS像素,就是其中的一个小方格。


一,viewport又是什么?

网页在viewport上渲染,可以想像在PS上画东西时,上面也有个画布,这个画布分割了 N x M 个方格,N是它的宽度,M是它的高度。宽高都可以任意设置,所以说viewport是虚拟的。假设设置宽度是400,那么浏览器显示区域的横向将被分为400份,CSS的1px占的宽度就是显示区域的 1/400。

viewport值不一样时,对页面元素宽度的影响,比如一个头像宽度是50px。

当viewport宽度为500时,屏幕横向被分为500份,每份1px,所以头像宽度是屏幕的1/10。(500/50=10)

当viewport宽度为900时,屏幕横向被分为900份,每份1px,所以头像宽度是屏幕的1/8。 (900/50=18)

所以,在CSS中,1px是指viewport中的一个小方格,而viewport宽度是可以任意设置的。


二,怎么合理设置viewport的宽度?

viewport 的宽度可以是数字和字符串"device-width"。device-width指设备宽度。当取值为数字时,指不论是什么手机屏幕,viewport 都被分为多少份,当取值为device-width时,指的是手机屏幕的viewport宽度被设置为跟手机宽度一样。那这个宽度怎么算的呢?

device-width的算法

先理清几个非常关键的术语概念:

物理像素:买手机的时候会有一个 nm 的分辨率,那是屏幕的nm个呈像的点,一个点(小方格)为一个物理像素。它是屏幕能显示的最小粒度

CSS像素:就是CSS里的Px,上面已经讲了是viewport中的一个小方格。

像素密度:即dpi或ppi,屏幕每英寸所占的物理像素点。


而CSS像素与物理像素之间是有一个转换关系的。即是:

CSS像素 = 转换系数 * 物理像素


其中,转换系数计算过程如下:

安卓的密度区域和转化系数的对应表


iPhone的密度区域和转化系数的对应表

 


(声明:以上三个图片来源于 http://tgideas.qq.com/webplat/info/news_version3/804/7104/7106/m5723/201509/376281.shtml)

例如:某台安卓手机,分辨率是 1920*1080,屏幕对象线是5英寸。那么在这台手机上1个CSS像素,占了多少个物理像素?

第一步:勾股定理算出对角线的分辨率,即 √(1920²+1080²)≈2203px

第二步:算出dpi。对角线的分辨率/对角线英寸 = 2203/5≈440dpi

第三步:得出转换系数。根据上面的图片,安卓手机440dpi,属于XXHDPI,转换系数是3

因此这台手机中,1个CSS像素 = 3*物理像素。即1个CSS像素占了3个物理像素。

这个转换系数,也等同于dpr,设备像素比。

因为很明显device-width的宽度值单位是CSS像素。所以当viewport设置为device-width时,此时它是手机横向分辨率 / 转换系数。即:

device-width = 手机横向物理像素 / 转换系数

例如上述的例子中,该台安卓手机的device-width是1080/3 = 360,即viewport的宽度是 360 CSS像素。

而viewport设置为固定的数字有可能会破坏这种转换关系,都是建议设置viewport宽度为device-width,这样1个CSS像素就尽最大可能刚好占dpr个物理像素点。

 

三,为什么会出现比border-width:1px更细的边框?

屏幕能够显示的最小粒度是1个物理像素,而当viewport宽度设置为device-width时,1个CSS像素占用的物理像素是由转换系数决定的。所以,像iPhone6这样的高清屏上,转换系数为3,border-width:1px,这个边框占了3个物理像素。如果能让某个border的宽度为1个物理像素,那么它就比1个CSS像素要细,而本文最开始边框那个更细是因为经过特殊处理后使其只占用1个物理像素。

方法一是缩放整个页面,在CSS3标准里,可以缩放某个元素。例如某个div.border-top,为它设置如下样式,使该DIV的顶部有一个边框

.border-top{position: relative;border-top: none !important;}
.border-top:after {
    content: " ";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 1px;
    background-color: #D5D5D6;
    transform-origin: 0 0;
    transform: scaleY(0.5);
}


在该DIV后面添加一个高度为1px的内容,并且缩小dpr倍,这里就是缩小成原来的1/2。

优点是整个页面不用缩放,缺点是border代码较多,无法实现border-radius圆角 

 

四,使用 -webkit-min-device-pixel-ratio 适配屏幕

.border_1px:before{
 content: '';
 position: absolute;
 top: 0;
 height: 1px;
 width: 100%;
 background-color: #000;
 transform-origin: 50% 0%;
}
@media only screen and (-webkit-min-device-pixel-ratio:2){
  .border_1px:before{
    transform: scaleY(0.5);
  }
}
@media only screen and (-webkit-min-device-pixel-ratio:3){
  .border_1px:before{
    transform: scaleY(0.33);
  }
} 

 在 MDN 中,提示 -webkit-device-pixel-ratio 该特性是非标准的,请尽量不要在生产环境中使用它!

-webkit-device-pixel-ratio 是一个非标准的布尔类型 CSS 媒体类型,是标准 resolution (en-US) 媒体类型的一个替代方案。


五,使用 resolution CSS 媒体查询 适配屏幕

@media screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 2dppx) {
  ...
}

@media screen and (-webkit-min-device-pixel-ratio: 3), (min-resolution: 3dppx) {
  ...
}
声明:本站所有文章和图片,如无特殊说明,均为原创发布。商业转载请联系作者获得授权,非商业转载请注明出处。
真诚赞赏,手留余香
赞赏
随机推荐
Wordpress 使用 tag 标签获取文章列表的方法
HTML 对话框元素 dialog
CSS3 实现 Switch 开关
使用 svg 作为背景图片
Land 主题
WordPress关闭自动草稿
WordPress 自定义 JWT 授权和验证
Nginx 通过日志统计访问数据