移动端适配经验分享
2021-12-09 本文已影响0人
该帐号已被查封_才怪
一、rem时代
18年做过一个移动端排行榜的需求,当时考虑到兼容性,采用rem兼容方案,也就是:
<html lang="en">
<head>
<meta charset="utf-8">
<title>排行榜</title>
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<script src="./js/amfe-flexible.js"></script>
//amfe-flexible.js
(function flexible (window, document) {
var docEl = document.documentElement
var dpr = window.devicePixelRatio || 1
// adjust body font size
function setBodyFontSize () {
if (document.body) {
document.body.style.fontSize = (12 * dpr) + 'px'
}
else {
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit () {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
然后css根据设计稿直接写px,再用postcss-px2rem的npm包及gulp构建工具直接打包成rem单位即可。这样没什么问题。
二、vw、vh时代
后来由于vw、vh兼容性都不错且amfe-flexible不再维护了,因此后面的项目慢慢采用了vw、vh适配方案。使用vw、vh还原美术图简直爽歪歪。最近接到一个需求有一些输入信息,当时想都没想就使用了vw、vh适配方案。把页面写完后,在各个屏幕上适配都很ok,但是,在ios上没有问题,但是当在安卓机点击输入框时,发现软键盘(输入法)弹出后整个页面的高度变为手机屏幕的高度减去软键盘的高度,也就是页面高度被压缩了。在网上找方法发现如下方法可解决手机自带的浏览器出现的上述问题,但是在TBS 内核的webview中不适用:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,user-scalable=no"
name="viewport" id="viewportMeta">
var innerHeightNum=0;
var initViewport = function(height){
var metaEl = document.querySelector("#viewportMeta");
var content = "width=device-width,initial-scale=1.0,user-scalable=no,minimum-scale=1.0,maximum-scale=1.0,height=" + height;
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', content);
}
window.onload = function() {
$("html,body").height(window.innerHeight);
$('#allWrap').height(window.innerHeight);
innerHeightNum=window.innerHeight;
initViewport(window.innerHeight);
}
window.addEventListener('resize',()=>{
initViewport(innerHeightNum);
})
在webview中不奏效是因为vh单位的缘故,因此两种方案可以解决:
1、将vh单位全部转换给vw
2、在页面onload后记住vh单元的元素高度,然后在页面resize时重新赋值即可。
第2种方案太过繁琐且不友好只能采用第1种方案。
因此在这里给大家的建议是如果有涉及到输入类的移动端页面适配,不要采用vh单位而是全部采用vw。
另外100vh页面的页脚会被ios的Safari菜单栏遮挡,如下图
image.png
解决方案是
body {
min-height: 100vh;
/* mobile viewport bug fix */
min-height: -webkit-fill-available;
}
html {
height: -webkit-fill-available;
}
具体详见:https://allthingssmitty.com/2020/05/11/css-fix-for-100vh-in-mobile-webkit/