一些常见的移动端适配方案,你了解吗?

推荐关注↓

作者:codinglin

https://juejin.cn/post/7172952008029110285

前言

移动端设备的尺寸很多,而 UI 设计稿一般只会基于一个尺寸(一般是 375px 或 750px )进行设计。

目前移动端适配方案有多种,本文将介绍一些具有代表性的适配方案。

媒体查询 @media

CSS3 中的媒体查询属性 @media 分别为不同屏幕尺寸的移动设备编写不同尺寸的 css 属性,示例如下所示:

/* <375px */
@media screen and (max-width:375px) { 
  .box {
    width100%;
  }
}
/* >=375px and <450px */
@media screen and (min-width:375pxand (max-width:450px) {
  .box {
    width90%;
  }
}
/* >=450px */
@media screen and (min-width:450px) {
  .col{
    width80%;
  }
}

缺点:

  1. 页面上所有的元素都得在不同的 @media 中定义一遍不同的尺寸,代价有点高。
  2. 如果再多一种屏幕尺寸,就得多写一个 @media 查询块。

rem 适配方案

remCSS3 新增的一个相对单位,它是一个相对于页面根元素 htmlfont-size 的一个单位。

假如设置了根元素 htmlfont-size18px,那么 1rem 等于 18pxrem 的大小会随着根元素 htmlfont-size 的改变而改变。rem 方案就是利用了这一点,根据不同的屏幕尺寸,来设置不同的根元素 htmlfont-size 的大小,以此来达到适配不同屏幕尺寸的目的。

目前,除了 IE8 及更早版本外,所有浏览器均已支持 rem

1. 使用 flexible

flexible 方案是阿里早期开源的一个移动端适配解决方案,引用 flexible 后,我们在页面上统一使用 rem 来布局。我们创建一个 rem.js 文件:

// 封装一个根据屏幕尺寸自动改变 html 的 font-size 大小的函数
const init = function ({
  let clientWidth =
    document.documentElement.clientWidth || document.body.clientWidth;
  // 设计图尺寸是 750px,这样 *20 之后,1rem 就等于 20px;
  const fontSize = (clientWidth / 750 * 20);
  document.documentElement.style.fontSize = fontSize + "px";
};

init();

window.addEventListener("resize", init);
export default init;

mian.js 中引入就能够使用了,需要自己手动将 px 转换为 rem

2. postcss-pxtorem 插件

viewport 适配方案

viewport 是指视窗、视口,即浏览器用来显示网页的那部分区域。

viewport 方案使用 vw/vh 作为样式单位。vw/vh 将 viewport 分成了一百等份,1vw 等于视口 1% 的宽度,1vh 等于视口 1% 的高度。当我们的设计稿宽度是 750px 时,1vw 就等于 7.5px

1. 设置 meta 标签

对于手机浏览器浏览页面,常对 viewport 进行如下设置即可:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes">

initial-scale:初始缩放比例,即当浏览器第一次加载页面时的缩放比例。maximum-scale:允许浏览者缩放到的最大比例,一般设为1.0。user-scalable:浏览者是否可以手动缩放,yes或no。

2. px 自动转换为 vw

使用插件 postcss-px-to-viewport[1] 进行相关配置,就可以帮助我们将 px 自动转化为 vw,提高开发效率。

使用 npm 或 yarn 安装:

npm install postcss-px-to-viewport --save-dev

或者

yarn add -D postcss-px-to-viewport

webpack 配置:

module.exports = {
  plugins: {
    // ...
    'postcss-px-to-viewport': {
      // options
      unitToConvert'px',    // 需要转换的单位,默认为"px"
      viewportWidth750,     // 设计稿的视窗宽度
      unitPrecision4,       // 单位转换后保留的精度
      propList: ['*''!font-size'],        // 能转化为 vw 的属性列表
      viewportUnit'vw',     // 希望使用的视窗单位
      fontViewportUnit'vw'// 字体使用的视窗单位
      selectorBlackList: [],  // 需要忽略的 CSS 选择器,不会转为视窗单位,使用原有的 px 等单位
      minPixelValue1,       // 设置最小的转换数值,如果为 1 的话,只有大于 1 的值会被转换
      mediaQueryfalse,      // 媒体查询里的单位是否需要转换单位
      replacetrue,          // 是否直接更换属性值,而不添加备用属性
      excludeundefined,     // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
      include/\/src\//,     // 如果设置了include,那将只有匹配到的文件才会被转换
      landscapefalse,       // 是否添加根据 landscapeWidth 生成的媒体查询条件
      landscapeUnit'vw',    // 横屏时使用的单位
      landscapeWidth1125,   // 横屏时使用的视窗宽度
    },
  },
};

3. 标注不需要转换的属性

在项目中,如果设计师要求某一场景不做适配,需为固定的宽高或大小,这时我们就需要利用 postcss-px-to-viewport 插件的 ignoring 特性,对不需要转换的属性进行标注,如下所示:

/* example input: */
.box {
  /* px-to-viewport-ignore-next */
  width100px;
  padding20px;
  height100px/* px-to-viewport-ignore */
}

/* example output: */
.box {
  width100px
  padding2.6667vw;
  height100px;
}

当然,viewport 适配方案也有一定的缺陷:px 转换成 vw 不一定能完全整除,因此有一定的像素差。

最后

目前比较推荐的移动适配方案是 rem&vw,了解其中的适配原理对于前端而言是非常重要的,相关问题也经常出现在面试题中。熟练使用插件也能给我们的工作带来很大的帮助。

以上就是笔者对移动端适配方案的一些见解,以及在使用移动端适配时遇到的一些坑,如有不足欢迎大家指正~,谢谢!

参考资料

[1]

postcss-px-to-viewport: https://github.com/evrone/postcss-px-to-viewport/blob/master/README_CN.md

- EOF -


加主页君微信,不仅前端技能+1

主页君日常还会在个人微信分享前端开发学习资源技术文章精选,不定期分享一些有意思的活动岗位内推以及如何用技术做业余项目

加个微信,打开一扇窗



推荐阅读  点击标题可跳转

1、移动端滚动穿透与滚动溢出解决方案

2、童鞋们,该放弃移动端 rem 适配方案了

3、优秀前端人都知道的 H5 移动端调试全攻略~


觉得本文对你有帮助?请分享给更多人

推荐关注「前端大全」,提升前端技能

点赞和在看就是最大的支持❤️

相关推荐

  • 我相信这是 Vue3 复用代码的正确姿势!
  • 卡住美国的脖子?中国将限制出口激光雷达技术
  • 拿大佬开刀:谷歌裁员中的开源人才危机
  • 不工作,靠海外抖音还清所有债务:会赚钱的人都在做这件事 !
  • 美日荷联手“芯片同盟”,损人不利己
  • 转转容器日志采集的演进之路
  • 斯坦福大学打响 ChatGPT 反击战,阻止学生用 AI 写作业
  • 余承东:华为技术走在产业前列,别人想超越很难;理想销量夺冠后,员工不满年终奖打折;黑客窃取GitHub代码签名证书|极客头条
  • ChatGPT is not all you need,一文综述6大公司9类生成式AI模型
  • 2023年,Prompt Tuning是否已全面超越Fine-Tuning?
  • Java 互相关联的实体无限递归问题的解决
  • 腾讯云团队为什么用阿里云的服务名?
  • SpringBoot超大文件上传,实现秒传!
  • 《用 C 写 Python》系列 PDF 版本发布啦!!!
  • 让人眼前一亮的应用「GitHub 热点速览」
  • 构建 Java 镜像的 10 个最佳实践
  • 美国政府考虑再次打压华为;超60国发现新变种CH.1.1;杜海涛被起诉,最新判决来了 | 每日大新闻
  • 四个菜1500块!旅游宰客真是“中国特色”?
  • 【了解】代码生成利器fastmybatis
  • MySQL大数据表处理的三种方案,查询效率嘎嘎高!