吃透移动端 Html5 响应式布局


Posted in HTML / CSS onDecember 16, 2019

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

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

问题

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

写移动端H5 相关页面,相比 PC 端有哪些值得注意的点?

关于H5 响应式布局有哪些解决方案?

什么是 rem?如何在项目中完美使用它?

vh/vw 是最佳解决方案吗?它有什么优势和缺陷 大型开源库里面常用解决方案是什么?

怎样快速搭建一套移动端布局解决方案?

由来

概念

什么是 H5 技术?

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

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

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

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

吃透移动端 Html5 响应式布局

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

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

吃透移动端 Html5 响应式布局

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

Hybrid App 技术大致原理

吃透移动端 Html5 响应式布局

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

移动端 web 和 PC web 的区别

PC 端我们是怎么布局的呢? 一般采用两种方案,一种是 min-width 限制最小的宽度,浏览器宽度小于 min-width 就直接滚动。另外一种呢,就是留白。设置页面一个基础宽度,超出的部分留白。

但是这两种解决方案在移动端可行吗?

移动端手机的宽度,大多不一致,而且没办法进行窗口的缩放。让移动端产生滚动,体验更加糟糕,更别说和原生 app 性能相比较,基本页面展示体验就很差了。

那么留白呢? 更不可行了,手机设备本身宽度就小,再留白就基本看不了什么了。

所以为了让这种 web 能够像原生 app 一样的体验,就出现了 H5 技术。进一步衍生了 Hybird , 虽然比不上 app 性能,但是在 热更新 上占有绝对优势,有着原生无法替代的地方。

下面我们来就来实践下 H5 最基本的技术之一 移动端响应式布局

实践

解决方案一:rem + pxToRem 概念

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

绝对单位

吃透移动端 Html5 响应式布局 

对于绝对单位,一般来说常用的也就 px, 其他的可能打印需要用到

相对单位

吃透移动端 Html5 响应式布局 

对于相对单位来说, emrem 属于一对, vwvh属于一对。

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

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

原理

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

 实现

动态更新根字体大小

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'
})

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: ['*']
          })
        ]
      }
    }
  }
}

解决方案二: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 关键词上

吃透移动端 Html5 响应式布局

rem 在移动端表现高达 100%,令人惊叹!

吃透移动端 Html5 响应式布局 

吃透移动端 Html5 响应式布局 

vh vw表现还是比较令人满意,低版本的 safari 情况下会有兼容性问题,但不影响它会成为一种比较好的移动端布局解决方案。

 开源库解决方案

vant 组件库

吃透移动端 Html5 响应式布局

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 最新的源码 再进行分享,想持续了解更多,不妨点个 关注 呗。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
CSS3系列教程:背景图片(背景大小和多背景图) 应用说明
Dec 19 HTML / CSS
CSS3网格的三个新特性详解
Apr 04 HTML / CSS
CSS3绘制圆角矩形的简单示例
Sep 28 HTML / CSS
结合CSS3的布局新特征谈谈常见布局方法
Jan 22 HTML / CSS
可自定义箭头样式的CSS3气泡提示框
Mar 16 HTML / CSS
纯css3制作煽动翅膀的蝴蝶的示例
Apr 23 HTML / CSS
HTML5-WebSocket实现聊天室示例
Dec 15 HTML / CSS
24个canvas基础知识小结
Dec 17 HTML / CSS
详解前端HTML5几种存储方式的总结
Dec 27 HTML / CSS
HTML5打开手机扫码功能及优缺点
Nov 27 HTML / CSS
浅谈html5 video 移动端填坑记
Jan 15 HTML / CSS
AmazeUI在模态框中嵌入表单形成模态输入框
Aug 20 HTML / CSS
HTML文本属性&amp;颜色控制属性的实现
Dec 17 #HTML / CSS
吃透移动端 1px的具体用法
Dec 16 #HTML / CSS
关于html字符串正则判断和匹配的具体使用
Dec 12 #HTML / CSS
处理textarea中的换行和空格
Dec 12 #HTML / CSS
VSCode 自定义html5模板的实现
Dec 05 #HTML / CSS
HTML5 图片悬停放大的实现代码示例
Dec 04 #HTML / CSS
Html5写一个简单的俄罗斯方块小游戏
Dec 03 #HTML / CSS
You might like
PHP 中的类
2006/10/09 PHP
谈谈PHP语法(4)
2006/10/09 PHP
PHP自动选择 连接本地还是远程数据库
2010/12/02 PHP
让PHP更快的提供文件下载的代码
2012/06/13 PHP
php获取汉字拼音首字母的方法
2015/10/21 PHP
gearman管理工具GearmanManager的安装与php使用方法示例
2020/02/27 PHP
php多进程并发编程防止出现僵尸进程的方法分析
2020/02/28 PHP
提高网站性能之 如何对待JavaScript
2009/10/31 Javascript
ExtJS 2.0 GridPanel基本表格简明教程
2010/05/25 Javascript
javascript下高性能字符串连接StringBuffer类
2010/08/16 Javascript
使用jQuery的将桌面应用程序引入浏览器
2010/11/19 Javascript
正负小数点后两位浮点数实现原理及代码
2013/09/06 Javascript
JS实现三级折叠菜单特效,其它级可自动收缩
2015/08/06 Javascript
jQuery实现类似标签风格的导航菜单效果代码
2015/08/25 Javascript
莱鸟介绍window.print()方法
2016/01/06 Javascript
详解Angular结合zTree异步加载节点数据
2018/01/20 Javascript
vue 实现边输入边搜索功能的实例讲解
2018/09/16 Javascript
Vue的H5页面唤起支付宝支付功能
2019/04/18 Javascript
JavaScript canvas绘制折线图
2020/02/18 Javascript
[05:03]2018DOTA2亚洲邀请赛主赛事首日回顾
2018/04/04 DOTA
Python的Django框架中if标签的相关使用
2015/07/15 Python
儿童学习python的一些小技巧
2018/05/27 Python
python3.6使用urllib完成下载的实例
2018/12/19 Python
Python中的heapq模块源码详析
2019/01/08 Python
Python的pygame安装教程详解
2020/02/10 Python
英国景点门票网站:attractiontix
2019/08/27 全球购物
注塑工厂厂长岗位职责
2013/12/02 职场文书
师范学院美术系毕业生自我鉴定
2014/01/29 职场文书
房地产广告词大全
2014/03/19 职场文书
乡镇领导班子批评与自我批评材料
2014/09/23 职场文书
感谢信范文大全
2015/01/23 职场文书
2015年端午节国旗下演讲稿
2015/03/19 职场文书
2015年信访工作总结
2015/04/07 职场文书
小学生安全教育心得体会
2016/01/15 职场文书
go语言-在mac下brew升级golang
2021/04/25 Golang
golang为什么要统一错误处理
2022/04/03 Golang