1. 首页

吃透移动端 H5 响应式布局

前言

最近写第三个移动端 H5 的项目了,准备记录下自己在 H5 项目中的一些实践探索。移动端 H5 与 PC 端开发最大的区别之一,大概就是响应式布局问题。

那么下面我们来聊聊移动端响应式布局,了解他的来龙去脉,对现有的最佳解决方案探索。

问题

全文将围绕下面几个问题进行论述和展开:

  • 写移动端 H5 相关页面,相比 PC 端有哪些值得注意的点?
  • 关于H5 响应式布局有哪些解决方案?
  • 什么是 rem?如何在项目中完美使用它?
  • vh/vw 是最佳解决方案吗?它有什么优势和缺陷
  • 大型开源库里面常用解决方案是什么?
  • 怎样快速搭建一套移动端布局解决方案?

由来

概念

什么是 H5 技术?

H5 这个命名本身是一个很不讨巧的命名,咋一眼看上去认为 HTML5,或者第 5 级标题的标签,对一些造成一些不小的误解。

比如:我的一个某后端同事,谈论到 H5 很简单,HTML 之前我也学过一些,以后要是你请假,我来帮你写。

我是一脸蒙蔽,H5 === HTML?

再看看,搜索引擎中H5是什么?(引用来自谷歌词条第一页)

吃透移动端 H5 响应式布局

如此看来,将 H5 视作 HTML 的大有人在,而 H5 这个概念只在中国特有,所以对外国人来说他们也认为是 HTML, 所以,对于外国人和非这个领域的人来说,他们存在一样的误解。

目前的 H5 算是一个比较大的概念了,我认为的 H5 技术是一系列移动端 web 前端技术的集合 大致用一个韦恩图表示如下

吃透移动端 H5 响应式布局

我们这里只谈 web 前端中 H5 技术,H5 技术本身是用于移动端的 web 网页。由于App本身有个 “ webview ” 的容器,在容器里可以运行 web 前端相关代码,由此 H5 和原生 App 结合又衍生出来了 Hybrid App 技术

Hybrid App 技术大致原理

吃透移动端 H5 响应式布局

这是我给公司同事普及 H5 知识绘制的图像。

实践

解决方案一:rem + pxToRem

概念

css 中用于计量的单位有两种,一种是绝对单位,另一种是相对单位

绝对单位

吃透移动端 H5 响应式布局 对于绝对单位,一般来说常用的也就 px, 其他的可能打印需要用到

相对单位

吃透移动端 H5 响应式布局 对于相对单位来说,emrem 属于一对,vwvh 属于一对。

前一对相对于字体大小,区别在于 rem 相对于根字体,对于我们控制整体的大小相对容易些,所以我们可以使用它来控制整个页面的缩放。

后一对,相对于视窗的大小,这个将在下一个节中发挥主要作用。

原理

  1. 监听屏幕视窗的宽度,通过一定比例换算赋值给htmlfont-size。此时,根字体大小就会随屏幕宽度而变化。
  2. px 转换成 rem, 常规方案有两种,一种是利用sass/less中的自定义函数 pxToRem,写px时,利用pxToRem函数转换成 rem。另外一种是直接写px,编译过程利用插件全部转成rem。这样 dom 中元素的大小,就会随屏幕宽度变化而变化了。

实现

  1. 动态更新根字体大小
const MAX_FONT_SIZE = 420

// 定义最大的屏幕宽度
document.addEventListener('DOMContentLoaded', () => {
  const html = document.querySelector('html')
  let fontSize = window.innerWidth / 10
  fontSize = fontSize > MAX_FONT_SIZE ? MAX_FONT_SIZE : fontSize
  html.style.fontSize = fontSize + 'px'
})

  1. pxrem

pxToRem 方案一

$rootFontSize: 375 / 10;
// 定义 px 转化为 rem 的函数
@function px2rem ($px) {
    @return $px / $rootFontSize + rem;
}

.demo {
    width: px2rem(100);
    height: px2rem(100);
}

pxToRem方案二

vue-cli3 中配置 装 postcss-pxtorem 插件就可以了,其他平台大致差不多

const autoprefixer = require('autoprefixer')
const pxtorem = require('postcss-pxtorem')
module.exports = {
  // ...
  css: {
    sourceMap: true,
    loaderOptions: {
      postcss: {
        plugins: [
          autoprefixer(),
          pxtorem({
            rootValue: 37.5,
            propList: ['*']
          })
        ]
      }
    }
  }
}

点击快速配置 H5 项目工程

继续探索postcss-pxtorem插件源码,查看它实现的原理

function createPxReplace (rootValue, unitPrecision, minPixelValue) {
    return function (m, $1) {
        if (!$1) return m;
        var pixels = parseFloat($1);
        if (pixels < minPixelValue) return m;
        var fixedVal = toFixed((pixels / rootValue), unitPrecision);
        return (fixedVal === 0) ? '0' : fixedVal + 'rem';
    };
}

px变换成 rem 主要是这个函数,当然里面有很多可配置的参数, 核心原理和我们方案一差不多,方便在于,不需要每次写px都要加上一个函数,代码也清晰很多

是不是所有元素 px 都要转换成 rem呢?,那可不一定哦,border 中的 px 不应该转 rem,涉及到另外一个 1px 的问题,上一篇文章详细论述过,避免 px 转 rem,将 border 中的 px 大写成 PX/Px/pX

1px 适配问题请移至 吃透移动端 1px

解决方案二:vh + vw

原理

vw 相对于视窗宽度的单位,随宽度变化而变化。由此看来,方案一其实是方案二的一种 Hack, 通过使用监听实现了方案二的效果

实现

与 rem 类似做法,直接使用 postcss-px-to-viewport 插件进行配置, 配置方式也是和 postcss-pxtorem 大同小异

我们看看插件的原理是不是也是一样的

function createPxReplace(opts, viewportUnit, viewportSize) {
  return function (m, $1) {
    if (!$1) return m;
    var pixels = parseFloat($1);
    if (pixels <= opts.minPixelValue) return m;
    var parsedVal = toFixed((pixels / viewportSize * 100), opts.unitPrecision);
    return parsedVal === 0 ? '0' : parsedVal + viewportUnit;
  };
}

果然呢,连方法名、变量名、代码逻辑,都一摸一样哈哈哈,谁抄谁,我就不指出来啦 – –

其他解决方案

| | 方案 | 缺陷 | ———- | ———— | ————| |1|百分比|高度无法百分比| |2|媒体查询 + meta 中 viewport |不同设备宽度不同,缩放比无法完全确定| |3|flex |还是无法解决宽度超出问题|

上面方案均存在致命缺陷,不推荐使用它完成移动端布局计算。

flex 与 rem 结合使用更佳

兼容性

上述两种方案,兼容性主要在于 rem,vh,vw 关键词上

吃透移动端 H5 响应式布局

rem在移动端表现高达 100%,令人惊叹! 吃透移动端 H5 响应式布局

吃透移动端 H5 响应式布局 vh vw 表现惨不忍睹

不得不说 rem 仍然是移动端 h5 布局的最佳方案

开源库解决方案

vant 组件库

吃透移动端 H5 响应式布局

vant 组件库中,默认采用 px 做计量单位,如果需要使用 rem,直接使用插件完美适配。

对于 vw 方案,vant 也是可以通过插件将 px 转成 vw,对于 vw 可能会存在一些坑点。

ant-design-mobile 组件库

ant-design-mobile 组件库仍然使用 px 单位

@hd: 1px; // 基本单位

// 字体尺寸
// ---
@font-size-icontext: 10 * @hd;
@font-size-caption-sm: 12 * @hd;
@font-size-base: 14 * @hd;
@font-size-subhead: 15 * @hd;
@font-size-caption: 16 * @hd;
@font-size-heading: 17 * @hd;

// 圆角
// ---
@radius-xs: 2 * @hd;
@radius-sm: 3 * @hd;
@radius-md: 5 * @hd;
@radius-lg: 7 * @hd;
@radius-circle: 50%;

// 边框尺寸
// ---
@border-width-sm: 1PX;
@border-width-md: 1PX;
@border-width-lg: 2 * @hd;

vant 组件一样,还是由开发者来决定到底用哪一种方案 这种把选择权交给开发者,算是一种开源库的最灵活的做法了。

总结

通过该文,你大概了解 H5 问题的来龙去脉了吧,也明白了如何解决移动端响应式布局问题,如果这票文章能解决你的疑问或者工作中问题,不妨点个赞收藏下。

由于技术水平有限,文章中如有错误地方,请在评论区指出,感谢!

上一篇文章 解决了 1px 问题,这篇文章解决了响应式布局问题, 接下我应该会继续研究下关于 H5 一些踩坑总结,之后应该回去研究下 vue 最新的源码再进行分享,想持续了解更多,不妨点个关注。

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文著作权归作者所有,如若转载,请注明出处

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:吃透移动端 H5 响应式布局

链接:https://www.javascriptc.com/3779.html

« JavaScript 中创建自定义排序方法
React hook + Typescript +Redux +AntD搭一个admin后台管理系统»
Flutter 中文教程资源

相关推荐

QR code