前端架构&软实力-移动端适配

2020-04-21 22:33:002021-02-20 17:16:39

移动端适配具体含义

为了在移动端让页面获得更好的显示效果,我们必须让布局视口、视觉视口都尽可能等于理想视口,但这并不能保证它们显示完全一致,我们需要一种方案(rem + vw适配)来让设计稿得到更完美的适配。

三个视口

  1. 布局视口

    布局视口 布局视口(layout viewport):当我们以百分比来指定一个元素的大小时,它的计算值是由这个元素的包含块计算而来的。当这个元素是最顶级的元素时,它就是基于布局视口来计算的。

    所以,布局视口是网页布局的基准窗口,在PC浏览器上,布局视口就等于当前浏览器的窗口大小(不包括bordersmargins、滚动条)。

    在移动端,布局视口被赋予一个默认值,大部分为980px,这保证PC的网页可以在手机浏览器上呈现,但是非常小,用户可以手动对网页进行放大。

    我们可以通过调用document.documentElement.clientWidth / clientHeight来获取布局视口大小。

  2. 视觉视口

    视觉视口 视觉视口(visual viewport):用户通过屏幕真实看到的区域。

    视觉视口默认等于当前浏览器的窗口大小(包括滚动条宽度)。

    当用户对浏览器进行缩放时,不会改变布局视口的大小,所以页面布局是不变的,但是缩放会改变视觉视口的大小。

    例如:用户将浏览器窗口放大了200%,这时浏览器窗口中的CSS像素会随着视觉视口的放大而放大,这时一个CSS像素会跨越更多的物理像素。

    所以,布局视口会限制你的CSS布局,而视觉视口决定用户具体能看到什么。

    我们可以通过调用window.innerWidth / innerHeight来获取视觉视口大小。

  3. 理想视口

    布局视口在移动端展示的效果并不是一个理想的效果,所以理想视口(ideal viewport)就诞生了:网站页面在移动端展示的理想大小 === 设备独立像素

    当页面缩放比例为100%时,CSS像素 = 设备独立像素理想视口 = 视觉视口

    我们可以通过调用screen.width / height来获取理想视口大小。

Meta viewport

元素表示那些不能由其它HTML元相关元素之一表示的任何元数据信息,它可以告诉浏览器如何解析页面

我们可以借助``元素的viewport来帮助我们设置视口、缩放等,从而让移动端得到更好的展示效果。

<meta  name="viewport"  content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">

device-width就等于理想视口的宽度,所以设置width=device-width就相当于让布局视口等于理想视口。

由于initial-scale = 理想视口宽度 / 视觉视口宽度,所以我们设置initial-scale=1;就相当于让视觉视口等于理想视口。

这时,1个CSS像素就等于1个设备独立像素,而且我们也是基于理想视口来进行布局的,所以呈现出来的页面布局在各种设备上都能大致相似。

rem + vw适配

  • rem是相对于根元素的字体大小的单位,也就是html的font-size大小,浏览器默认的字体大小是16px,所以默认的1rem=16px,我们可以根据设备宽度动态设置根元素的font-size,使得以rem为单位的元素在不同终端上以相对一致的视觉效果呈现。

  • vh、vw分别对应于视觉视口宽度 window.innerHeight和视觉视口高度 window.innerWidth

    100vh === window.innerHeight100vw === window.innerWidth

  1. 设置meta标签

    <meta  name="viewport"  content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
    
  2. 设置根font-size(对应于750px设计稿)

    html {
        font-size: 13.3333vw
    }
    
    /*
    750px = 100vw
    1px = 0.13333vw
    
    假定1rem = 100px
    则1rem = 13.333vw
    */