内容简介:移动端应用有各种复杂的页面需求,不仅要解决单屏、多屏、固定头部或底部等多个场景,还要兼容ios和Android内核,在经历了首先,需要实现的首页类似于app应用。
移动端优雅布局实践
前言:移动端有非常多的坑,布局首当其冲。
背景
移动端应用有各种复杂的页面需求,不仅要解决单屏、多屏、固定头部或底部等多个场景,还要兼容ios和Android内核,在经历了 项目实战(手机模式打开) 过后,总结出了一些经验,在这里和大家分享一下。
心路历程
首先,需要实现的首页类似于app应用。
-
第一站:统一flex布局的坑
→ flex教程
首页如上面的图片所示,然后偷了个懒,直接用了 antd-mobile的tab标签栏 ,它需要指定容器高度。于是,在项目最开始的时候直接通过js将容器设置为浏览器html窗口的高度:
// html高度 = body高度 = 主容器高度 doc.body.style.height = docEl.clientHeight + 'px';
这样做也有许多好处:纵向布局十分方便,不管是tab标签栏、tab标签页、头部固定元素或者底部固定元素实现起来都很简单;也能很简单就能实现元素居中对齐、两端对齐、自动分配空间等;同时也避免了Android输入框引起传统布局的问题。
不过这里有个唯一的不好的地方就是兼容不了ios的前进返回的操作栏和上下滚动回弹:
- 不能在滚动时隐藏前进返回的操作栏、
- 在上下滚动时容易触发页面的回弹效果,造成滚动卡顿。
这里补充一下:在ios上如果以正常流布局,内容超过一定高度时,向下滚动会隐藏底部的前进返回栏,向上滚动的时候再显示出来。当滚动到底部或者顶部时,再继续拉动页面,会有一个回弹的效果。
这两个问题极大的降低了ios的用户体验,又恰逢项目间隔期,有大把的时间,于是被推着到了布局优化上面。
-
第二站:寻找良好用户体验的布局案例
这里我们在寻找的过程中发现两个具有代表性的移动端应用:
- bilibili的m站
、
腾讯新闻
它用的是传统式流布局,头部和底部fixed固定,所有的内容全部向下平铺。
- 花瓣网H5
它采用的是设置主容器的position属性为absolute来脱离文档流的形式。
这两种布局方式在ios上都用户体验极好。但同时也发现他们都存在的一些问题,比如:登录页面明明不足一屏,却依然存在滚动;没有兼容iPhone X的安全域;弹窗滚动穿透等等。
如果能将这两种布局和flex进行整合一下,聚合各自的优点,基本上能打造一个用户体验和兼容性都令人满意的移动端应用了。
那么,如何基于现有的flex布局去整合这两种布局又成了一个问题。
-
第三站:基于flex调整布局结构
在调整之前,我的预期是这样的: 去掉外层高度限制,去掉纵向flex布局(除极少数单屏页面),将顶部、底部固定和弹窗设置为fixed 。
考虑到少数单屏页面需要继承html窗口的高度,于是采用了主容器脱离文档流的方式。
调整过后dom结构是这样的:
html > body > div#root > div.main-content(position: absolute)
只需要给 main-content 加上 height: 100%
,就可以满足单屏页面的需求。
好事多磨!
按照上面的想法进行改造过后又发现了新的问题: 脱离文档流过后,切换页面,html会保持最后滚动的位置 。
-
第四站:滚动条位置、滚动穿透、兼容iPhone X
-
解决滚动条位置被记录的问题找了一下发现
history
有个scrollRestoration
的属性,它有两个值,一个是默认值auto
还有一个是manual
。如果设置为manual
就可以手动设置滚动的位置。if ('scrollRestoration' in history) { history.scrollRestoration = 'manual'; }
然后在切换路由过后设置滚动的位置为起始位置:
Router.events.on('routeChangeComplete', () => { document.scrollingElement.scrollTop = 0; });
这样每次切换页面都是从初始位置开始。
这里有点鸡肋,前进后退也不会记录滚动位置。如果需要前进后退记录滚动的位置,就不能用这种脱离文档流的形式,需要用body滚动的形式,也就是。
-
解决滚动穿透这个问题,需要针对有滚动的弹窗和无滚动的弹窗单独处理。
overflow:hidden
-
兼容iPhone X
在meta标签后增加
viewport-fit=cover
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover"/>
然后留出安全域距离
padding-bottom: 0.49rem; // 底部button的高度 padding-bottom: calc(0.49rem + constant(safe-area-inset-bottom)); padding-bottom: calc(0.49rem + env(safe-area-inset-bottom));
这里需要注意些
padding-bottom
的时候需要写三个,第一个是为了兼容Android。
总结
总的来说flex布局还是带了十分大的便利,尤其是能根治居中、适配等一些老大难的问题。
每种布局的方式都有一定的缺陷,到目前为止还没有一种万能的方案来解决移动端各种复杂的场景。还是需要根据自己的需求还选择使用哪种实现方式。
*前面这三种方案各自的缺陷:
纵向flex布局(不建议使用) | body流式平铺(传统) | absolute脱离文档流(激进) |
---|---|---|
ios前进后退的操作栏无法隐藏、回弹效果引起卡顿 | 内部容器无法继承html窗口高度 | 前进后退无法记录滚动条位置 |
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 布局Angular / Django应用程序的最佳实践
- PyQt5的PyQtGraph实践系列1:添加图形到PyQt5布局
- css经典布局系列三——三列布局(圣杯布局、双飞翼布局)
- 四种方法实现──三栏布局(圣杯布局、双飞翼布局)
- 浅谈CSS三栏布局(包括双飞翼布局和圣杯布局)
- css经典布局——圣杯布局
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
How to Solve It
Zbigniew Michalewicz、David B. Fogel / Springer / 2004-03-01 / USD 59.95
This book is the only source that provides comprehensive, current, and detailed information on problem solving using modern heuristics. It covers classic methods of optimization, including dynamic pro......一起来看看 《How to Solve It》 这本书的介绍吧!