web 前端移动端适配
rem,dpr,适配方案
专有名词与视口
- 分辨率:物理像素 * 物理像素
- 设备独立像素:不同于物理像素,是虚拟化的,比如说 css 像素 10px
- 设备像素比:dpr,设备像素(物理像素)/ css 像素,可以通过 JS 获取:
window.devicePixelRatio
布局视口
在 PC 浏览器中,布局视口和浏览器可视窗口宽度是一致的,同时和浏览器本身的宽度一致
但在移动端,布局视口的宽度是要远远大于浏览器的宽度的,这两个视口是相互独立存在的。这是由于,浏览器厂商为了让用户在小屏幕下网页也能够显示地很好,所以把布局视口宽度设置地很大,最常见的宽度是 980px,可以通过document.documentElement.clientWidth
得到
理想视口
由于布局视口明显不友好,且忽略了手机的尺寸问题
所以苹果引入了理想视口的概念,它是对设备来说最理想的布局视口尺寸,理想视口中的网页用户最理想的宽度,用户进入页面的时候不需要缩放
所以很明显,所谓的理想宽度就是浏览器(屏幕)的宽度了
所以就有了下面的代码:<meta name="viewport" content="width=device-width,initial-scale=1">
width=device-width
这句代码可以把布局视口设置成为浏览器(屏幕)的宽度
initial-scale=1
的意思是初始缩放的比例是 1,使用它的时候,同时也会将布局视口的尺寸设置为缩放后的尺寸。而缩放的尺寸就是基于屏幕的宽度来的,也就起到了和width=device-width
同样的效果
dpr 具体表现-模糊的由来
有时我们发现,在不同的设备中展示同一张图片清晰度会不一样,这就要涉及到一个属性:dpr-设备像素比
在任何屏幕中,css 像素所呈现的大小是一致的,但一个 css 像素对应(覆盖)的物理像素个数是不一样的
而一个 css 像素对应其 rgb 颜色,而若 dpr>1,则几个相邻的物理像素只对应一个 css 像素,rgb 值只能取近似值,则导致了模糊
解决方案:
很明显,由于 css 元素不够分导致了模糊,那么使用跟 dpr 同个倍数大小的图片便能解决问题
比如对于 dpr=2 的设备,一个 200x300 的 img 标签,原图就要提供 400x600 的大小
rem 布局和字体的处理
在手淘的适配方案 flexible.js 中可见,在宽高中使用的是 rem,这是为了保证在不同宽度尺寸的设备中能够保证布局的等比例缩放
而由于 rem 单位在不同的宽度下换算出来不一样但都适配了比例,而我们希望在移动端中字体的相对大小要大一点,看得清楚一点,则更好的做法是使用 px 和媒体查询来进行字体的适配
对 font-size 进行放大的处理,如下 sass 代码代码:
1 | @mixin font-dpr($font-size){ |
由于不同屏幕 dpr 不同,我们又想显示的代码一样大,于是就给字体再增大 dpr 的倍数,这样当缩小 dpr 倍的时候,字体也就和设计稿所示的大小一样大了
响应式与自适应
- 响应式:针对不同分辨率设备而进行的适配设计,以利用@media 规则为主要手段
- 自适应:以比例布局为主,适配不同的浏览器窗口大小
移动端适配三种方案
百分比适配
根据父容器的宽高来进行布局,在父容器宽高已知的条件下有效果
viewport 视口适配
viewport 视口适配方案核心在于:给定一个目标的屏幕宽度,然后根据当前设备实际的屏幕宽度进行缩放比例的设置
如下:
- 按照一个固定的屏幕宽度来进行适配
- 比如,我设定的设备宽度就是 320
- 那么一个 1/4 屏幕的宽度就是 80px(我像素就写死 80px)
- 如果实际运行的屏幕正好是 320,那刚好就是 1/4
- 如果在一个屏幕宽度为 640 的设备上,写死 80px 就只能占 1/8,解决方法就是,把 640 的设备的初始比例设置为 2 倍,即放大两倍
根据上述运算规则,有:
1 | (function () { |
有了上述代码,在对应设备中会进行比例缩放,则可以再 css 种根据目标宽度写死像素了
rem 适配
rem 是相对于根元素的字体大小,即设置到 html 上 font-size 的大小
而 font-size 指的是一个字的宽度,而宽度就是屏幕的尺寸单位,根据 font-size 便可以将屏幕宽度分割,1rem 则代表一份
所以,对于 rem 的设置先获取当前设备的宽度,并动态计算:
1 | (function () { |
接下来的布局则根据屏幕宽度的刻度-1rem 来进行
结语
以上,谢谢阅览