首先需要了解几个概念:
1、像素(Pixel)
一个显示屏的成像原理是通过一系列的小点排列成一个大的矩形,不同的小点通过显示不同的颜色来显示成图像。这每一个小点被叫做一个物理像素。例如,分辨率是1920设备像素*1080设备像素,意味着横向上排列了1080个显像用的小点,在纵向上排列了1920个显像用的小点。另一个常见的数据叫每英寸像素取值(Pixel per inch,简称PPI),意思是每一英寸内的物理像素数量,计算公式是
公式中的屏幕尺寸指的是屏幕对角线的长度。一个显示屏的PPI越高,说明在同一大小的屏幕上能显示更多物理像素,能给图像提供更多细节,即代表显示屏能够以越高的密度显示图像。当然,显示的密度越高,拟真度就越高。
比如小米 9 的PPI计算方法如下(已知分辨率 2340 x 1080 FHD,6.39英寸(对角线)):
2、CSS像素
作为Web开发者我们整天在CSS里用px作为长度单位。这里的px指的是CSS像素。浏览器里的一切长度都是以CSS像素为单位的。在非高清屏幕以及未缩放浏览器的情况下,一个CSS像素等于一个物理像素;而在搭载了苹果公司的视网膜显示屏等高清屏幕(PPI特别高,一个屏幕上的物理像素点非常多)的设备上,如果一个CSS像素仍等于一个物理像素,那么网页上的各种元素就变得非常小,用户很难看清,因此高PPI的设备中,一个CSS像素通常等于两个甚至三个物理像素(浏览器自动设定,不同浏览器设定的会不一样)。如果一个CSS像素占用n个物理像素,那么我们就说此时的dppx(dots per pixel)数为n。
dppx是一个单位。设备有多少dppx除了跟设备本身的PPI有关,也和当前的缩放状态有关,但总的来说不是前端开发者能控制的,而是浏览器厂商以及浏览器用户(通过缩放页面)控制的。桌面浏览器上,一个放大到200%的页面(假如设备不是高清屏),一个CSS像素此时等同于两个物理像素,即2dppx
那么最后以一个例子来讲解以上的概念:
本人的笔记本电脑是小米笔记本 Pro 15.6",分辨率1920物理像素*1080物理像素,对角线长度(即屏幕尺寸)15.6英寸,因此PPI为141.21。该PPI不算特别低(但比起移动设备来说真是弱爆了),因此在浏览器不缩放的情况下若一个CSS像素等于一个设备像素,那么因为页面尺寸过小,会影响我的浏览。可在F12输入window.devicePixelRatio查看。
是的,可以说dppx可以看作devicePixelRatio(设备像素比,简称DPR)的单位,尽管DPR本身并不需要单位。综上可以看出,DPR由浏览器厂商确定。
dppx可以看作window.devicePixel的单位,同时也可看作媒体查询中device-pixel-ratio的单位。但IE11及以下版本并不支持这个单位,此时使用不标准的单位:dpi(Dots per inch)来代替。1dppx=96dpi(这换算的过程不展开了,因为我也不清楚,直接拿来用似乎没问题,需要知道的是,dpi也有设备的物理dpi和做Web开发时的dpi的区别),因此兼容性好的媒体查询写法是(来源A full vendor stack for targeting High Resolution 'retina' devices):
@media (min-resolution: 192dpi), (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-device-pixel-ratio: 2), (min-resolution: 2dppx) {
**All your high resolution styles go here**
}
另外,以下内容也与DPR有关:
3、视口(viewport)
上面我们了解了设备的物理像素和CSS像素的区别,以及用dppx来度量具体设备上两者的比。接下来说说另一个重要概念:视口。
视口在CSS里的定义是元素的包含块,称为初始包含块。它的宽度是所有CSS百分比宽度推算的根源。(块级元素的宽度默认为100%)
在桌面上,视口的宽度等同于浏览器窗口的宽度,高度即为浏览器窗口的高度。而在浏览器宽度通常为240px~640px的移动设备上也这样做的话,则会很不方便。为了适应为桌面浏览器设计的网站(这类网站使用固定布局,页面主体的宽度通常显式地设置在1000px上下),浏览器出现了布局视口概念。与桌面浏览器不同的是,浏览器默认的布局视口宽度与浏览器宽度完全独立。通常是768px~1024px,最常见的是980px(默认的布局视口的高度,各手机各浏览器倒是没有个准。不过反正不重要),而桌面浏览器的布局视口的尺寸就是浏览器窗口的尺寸(其实桌面浏览器根本没有“布局视口”的概念,“视口”就是浏览器的窗口)。题主在题目中提到
bootstrap分别对应的是小屏幕768px,中屏幕992px,大屏幕1200px
这里的768px、992px、1200px是指什么的尺寸呢?可以看到,这里使用了单位px,暗示着这些都是CSS像素,而不是设备的物理像素,因此Bootstrap对“屏幕尺寸”的定义与设备屏幕的分辨率无关。实际上,这里的尺寸指的是浏览器的布局视口尺寸。
可以在meta标签内指定一个布局视口尺寸,而不是使用默认的尺寸:
然而一般不指定具体宽度而是做如下设置:
这里的device-width告诉浏览器,将布局视口的宽度设置为设备最理想的宽度(DPR是浏览器决定的,因此最理想宽度自然也是)。以iPhone6(设备像素:1334*750)来说,浏览器决定了DPR是2,因此最理想宽度是“750设备像素/2=375px”(布局视口高度则顺势变成了1334设备像素/2 = 667px)。宽度最理想,意味着用户无需缩放页面,因此很多手机浏览器(不含safari)在这样的设置下,不再具有300ms的click时延。该时延的本意就是用来判断用户是要click还是双击缩放页面。红箭头指向的即DPR
不同的设备有不同的理想宽度(同一设备的不同浏览器也有可能拥有不同的理想宽度,尽管这种现象极为极为罕见),且随着设备的横放竖放也会有所改变,因此通常不指定特定的尺寸,而是使用device-width进行自适应。宽度为理想宽度的布局视口叫做“理想视口”
当设备的横放、竖放方式被改变时,最佳DPR不变,布局视口宽度从"手机宽度/最佳DPR"变为"手机长度/最佳DPR",且因布局视口宽度有变,浏览器会进行一次重排。不过iOS上 的Safari在旋转时不会改变布局视口的宽度(因此DPR提高了),除非在meta指令里设置了initial-scale=1
媒体查询中,min-width、max-width的查询即是对布局视口宽度的查询。因此若想通过媒体查询来实现响应式设计,应当设置一个设备的布局视口宽度,否则移动浏览器使用默认布局视口宽度(大都是980px)会使针对视口宽度的媒体查询无功而返。
另有min-device-width、max-device-device的查询(本质上是screen.width的查询),对桌面浏览器的意义不大。在移动浏览器上,是对不随着设备的横屏、竖屏而改变的设备“最理想宽度”的查询。例如,iPhone X的“device-width”永远是375px,而它的“width”会随着横屏竖屏而改变。
总结
进行响应式的设计大概有以下几个注意点:
1. 通过meta标签指定布局视口而不是使用默认的、宽度通常为980px的布局视口
2. 通过媒体查询或者document.documentElement.clientWidth来根据布局视口的宽度的不同来做设计
3. 通过媒体查询或者window.devicePixelRatio来根据DPR的不同来提供分辨率不同的图像
作者:漏鱼
链接:https://www.zhihu.com/question/35221839/answer/68520787
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这里给大家提供一点简单粗暴的解决方案,一点经验,供大家参考。
html{font-size:62.5%}/*1rem就代表10px*/
这样就可以在不同的设备分辨率下,通过js或其他手段动态改变font-size的值,来改变所有使用了rem元素的尺寸。以上都不要忘了添加