CSS - 移动端适配的前世今生

什么是 移动端适配?

移动互联网的快速发展,让人们已经越来越习惯于使用手机来完成大部分日常的事务.

移动开发目前主要包括三大类:

  • 原生App开发(iOS,Android,RN,uniApp,Flutter等)
  • 小程序开发(原生小程序,uniapp,Taro等)
  • Web页面(移动端的Web页面,可以使用浏览器或者webview浏览)

所谓移动端适配,就是 我们希望通过一套css 样式,来达到在所有移动设备上都能正常显示的目的.

至于要适配的原因也很简单,如果不做适配,同一套css 样式就会在下面的设备中显示的乱七八糟,影响用户体验.

适配相关的两个概念:

  • 自适应 : 根据不同的设备屏幕大小来自动调整尺寸,大小;
  • 响应式 : 会随着屏幕的实时变动而自动调整,是一种自适应.

移动的适配大部分是自适应的适配,因为 一个 用户的屏幕是不会变化的(用户 不缩放屏幕),我们只要能够用一套CSS 样式 在所有的手机屏幕上都可以正常显示就行了.

传统web 应用 大部分时间的适配做的是响应式的适配,因为 用户的浏览器,用户是可以随意放大缩小的,所以我们要做到页面内容能根据屏幕的变动而自动调整.

认识视口 viewport

什么是视口,请浏览css 专栏中的juejin.cn/post/730878... 中有介绍,可以先行了解,这里做简单的阐述:

  • 在一个浏览器中,我们可以看到的区域就是视口(viewport)
  • fixed 就是相对于视口来进行定位的.
  • 在PC端的页面中,我们是 不需要对视口进行区分的,因为我们的布局视口和视觉视口是同一个.

但是 在移动端就不太一样了,你布局的视口和你可见的视口是不一样的.

  • 这是因为移动端的网页窗口往往比较小 ,我们可能会希望一个大的网页在移动端可以完整的显示;
  • 所以在默认情况下,移动端的布局视口是大于视觉视口的;

所以在移动端,我们可以将视口划分为三种情况:

  • 布局视口(layout viewport)
  • 视觉视口(visual layout)
  • 理想视口(ideal layout)

这些概念的区分,事实上来自ppk,他也是对前端贡献比较大的一个人(特别是在移动端浏览器) www.quirksmode.org/mobile/view...

布局视口

默认情况下,一个PC端的网页在移动端会如何显示呢?

  • 第一,它会按照宽度为980px来布局一个页面的盒子和内容;
  • 第二,为了显示可以完整的显示在页面上,对整个页面进行缩小;

我们相对于980px 布局的这个视口,称之为布局视口

布局视口的默认宽度是980px

视觉视口

  • 如果在默认情况下,我们按照980px 显示内容,那么右侧有一部分区域就会无法显示,所以手机端浏览器会默认对页面进行缩放以显示到用户的可见区域中

  • 那么显示在可见区域的这个视口 ,就是视觉视口

在谷歌浏览器上, 按shift + 鼠标左键可以进行缩放.

理想视口

如果所有的网页都按照980px 在移动端布局,那么最终页面会被缩放显示

  • 事实上这种方式不利于我们进行移动端的开发 的,我们希望设置100px,那么显示的就是100px;
  • 如何做到这一点呢? 通过设置理想视口.

理想视口

  • 默认情况下的 布局视口 并不适合我们进行布局,
  • 我们可以对 布局视口进行宽度和缩放的设置 ,以满足正常在一个移动端窗口的布局;
  • 这个视口可以设置 meta 中的viewport

移动端上适配方案

移动端适配的核心思想

要完成移动端的适配,其实主要要完成三件事

  1. 移动端视口的调整
  2. 选择合适的相对单位和适配机制
  3. 选择合适的工具完成 像素 到 相对长度的转变

了解完视口的相关概念后,我们已经完成了第一步,通过meta 的设置,我们可以将移动的布局视口调整成为 理想视口.

比如:

css 复制代码
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0**">**

这样设置后,手机屏幕的 布局视口就和视觉视口保持一致了(宽度上).

关于第2步和 第3步,其实核心的理念就是希望能不同的屏幕尺寸上显示不同大小的内容,以完整的将整个内容合理的排布在手机屏幕上.

要做到这点,我们首先想到的就是用相对单位去设置每个盒子, 这样当屏幕尺寸变化后,我们统一调整相对单位的单位的大小,因为屏幕上的所有尺寸都是用相对单位来设置的,相对单位大小发生改变, 对应的内容也会发生变化,这样就做到了页面的自适应.

据此,移动端的适配大致有如下三种方案,其原理就是基于不同的相对单位来实现.

方案一:百分比设置;

  • 因为不同属性的百分比之,相对的可能是不同的参照物,所以百分比往往很难统一;
  • 所以百分比在移动端适配中使用是非常少的

方案二:rem单位 + 动态html 的font-size

方案三:vw单位

方案四:flex的弹性布局

本篇主要详细讲解方案二 和 方案三的实现,其他实现方式可以去查阅flex布局的相关知识

适配方案 - rem + 动态html 的font-size (曾经很流行,现在也在用(历史遗留项目),但已经是历史)

前提知识:

  1. 了解css 中的相对长度概念:juejin.cn/post/731526...
  2. 了解媒体查询的相关概念和用法:juejin.cn/post/731524...
  3. 了解css 预处理器 less 的使用:juejin.cn/post/731526...

rem 单位 是相对于 html 元素的font-size 来设置的,那么如果我们需要在不同的屏幕下有不同的尺寸,可以动态的修改html的font-size.

比如:

  • 设置一个盒子的宽度是2rem;
  • 设置不同屏幕上html的font-size不同

这样在开发中,我们只需要考虑两个问题: 问题一: 针对不同屏幕,设置html不同的font-size 问题二:将原来要设置的尺寸,转化成rem的单位;

动态的修改rem 的font-size 的尺寸的方案

方案一:媒体查询

可以通过媒体查询来设置不同尺寸范围内的屏幕html的font-size尺寸

缺点:

  1. 需要针对不同的屏幕编写大量的媒体查询;
  2. 如果动态改变尺寸,不会实时进行更新

方案二:编写js 代码

如果希望实时改变屏幕尺寸时,font-size也可以实时改变,可以通过js 代码;

具体实现:

  1. 根据html的宽度计算出font-size 的大小,并设置到html上;
  2. 监听页**面的实时改变,并且重新设置font-size 的大小到html **上;

方案三:lib-flexible库 真香方案 😄

事实上,lib-fixible库做的事情和js 代码是相同的,可以直接引入它.

rem 的单位换算的实现方案

方案一:手动计算 (可以有,不建议😄)

方案二: less/scss 函数 (凑乎能用,些许费时)

方案三:postcss-pxtorem (真香系列,最佳 推荐,自行搜索对应插件的使用方法即可)

通过前端的工程化开发,借助webpack 工具完成自动转化;

方案四: VSCode 插件(学习用,项目不建议,累呀,😄)

px to rem 的插件,在编写时自动转化

使用插件时,不要忘了根据 实际的设计稿,设置对应的插件配置哦

适配方案 - vw

vs 适配方案用法:

将你所有的尺寸单位都换成vw ,so easy.

vw 适配方案的现状

在flexible github 上已经有写过这样的一句话:

由于 viewport 单位得到众多浏览器的兼容,lib-flexible这个 过渡方案已经可以放弃使用,不管现在的版本还是以前的版本,都存在一定的问题.建议大家开始使用viewport 来替代次方.

所以它更推荐的是使用viewport 的两个单位vw,vh.

vw 的兼容想如何?

所以,老铁,放心用,它不会让你陷入滑铁卢😁

vw 适配要解决的问题

当你清楚的明白的理解了什么是vw 相对长度后,就明白这种方案的优越性,使用vw 方案,我们只需要处理一个问题.

那就是将原来要设置的尺寸,转化成vw的单位

vw单位换算的几种方案

方案一:手动换算(费时费力不讨好,不建议)

方案二: less/css 函数(凑乎能用,不推荐)

方案三:postcss-px-to-viewport-8-plugin(真香系列,逃课必胜法门😁)

和rem 一样,在前端的工程化开发中,借助webpack 的工具来完成自动化的转化.

方案四:VSCode 插件(学习用,项目不建议)

px to vw 插件,在编写时自动转化

一样好,需要根据设计稿设置好对应的配置

vw 和rem 的对比

rem 事实上作为一种 过渡的方案,它利用的也是vw的思想.

  • 前面不管我们 是自己编写的方案,还是flexible的源码.
  • 都是将1rem 等同于设计稿的1/10 ,再利用1rem 计算相对于 整个屏幕的尺寸大小.
  • 这样来看 ,1vw 不就是刚好等于屏幕的1/100 吗?
  • 而且相对rem,vw 还更加有优势

vw 相对于 rem的优势

  • 优势一 :不需要去计算 html 的font-size 大小,也不需要给html 设置这样一个font-size
  • 优势二: 不会因为设置html 的font-size大小,而必须给body 在设置一个font-size,防止继承.
  • 优势三: 因为不依赖font-size的尺寸,所以不用担心某些原因html的font-size尺寸被篡改,页面尺寸混乱
  • 优势四:vw 相比于rem 更加语义化,1vw 刚好是1/100 的viewport 的大小
  • 优势五 :我们只面对一个问题,将尺寸换算成vw的单位即可;

所以我说 rem 是移动端适配方案的前世,vw是 移动端适配方案的今生.

❤️❤️❤️❤️❤️❤️水平有限,语言难免出错,欢迎大家批评指正. ❤️❤️❤️❤️❤️❤️

❤️❤️❤️❤️❤️❤️细节上也有所不足,欢迎评论区详细讨论❤️❤️❤️❤️❤️❤️

相关推荐
神夜大侠2 小时前
VUE 实现公告无缝循环滚动
前端·javascript·vue.js
明辉光焱2 小时前
【Electron】Electron Forge如何支持Element plus?
前端·javascript·vue.js·electron·node.js
柯南二号2 小时前
HarmonyOS ArkTS 下拉列表组件
前端·javascript·数据库·harmonyos·arkts
wyy72932 小时前
v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条
前端·ui·html
前端郭德纲2 小时前
ES6的Iterator 和 for...of 循环
前端·ecmascript·es6
王解3 小时前
【模块化大作战】Webpack如何搞定CommonJS与ES6混战(3)
前端·webpack·es6
欲游山河十万里3 小时前
(02)ES6教程——Map、Set、Reflect、Proxy、字符串、数值、对象、数组、函数
前端·ecmascript·es6
明辉光焱3 小时前
【ES6】ES6中,如何实现桥接模式?
前端·javascript·es6·桥接模式
PyAIGCMaster3 小时前
python环境中,敏感数据的存储与读取问题解决方案
服务器·前端·python
baozhengw3 小时前
UniAPP快速入门教程(一)
前端·uni-app