题外话
突然被要求教学妹怎么做移动端适配的问题,上一次我写移动端的东西过去好久了,于是又面向百度了一波,网上感觉还是零零散散的,于是决定整理下来,虽有拾人牙慧之嫌,但是总归会清晰省事不少,嘻!(我真是个暖心学长)
Ps:
解决方案概括在最下面"总结"中,上面的都是详细解释,不想看长篇大论者可以直接拖到最下面看解决方案
设置html中meta标签
首先在移动端开发中,需要在前端html的<head></head>
标签中加入
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=10.0,user-scalable=no">
viewport是专为手机浏览器设计的一个meta标签
先看看如果html代码不用这个meta标签的情况下:
css代码跟面条一样长,就不贴了,简述一下:上面的三块每块100px宽,下面的是100%宽
但是由调试的iPhone手机界面来看,理想视口是375px宽
那么问题来了,上面三个块宽度加起来为300px,却不到iPhone375px宽的一半,为什么?
因为有些屏幕很小的智能手机,但分辩率却可以做得很大,传统桌面网站直接放到手机上阅读时,同时该网站没有做移动端优化的网站时,浏览器会尽可能缩小这个网站让用户看到网站的全部内容
所以前端html需要加上meta标签,加上后:
然后用Chrome devTools可以发现下面的100%宽度的div就是375px了,nice!
(弱弱吐槽一句:html代码不加这个meta标签在火狐浏览器中调试也没有问题,它会直接根据理想视图等参数显示出来,但是谷歌浏览器就不会……)
meta中content参数:
- width = device-width:应用程序的宽度和屏幕的宽度是一样的,也可定死,可以自定义试试看效果
- height = device-height:应用程序的高度和屏幕的高是一样的
- initial-scale = 1.0:应用程序启动时候的缩放尺度(1.0表示不缩放)
- minimum-scale = 1.0:用户可以缩放到的最小尺度(1.0表示不缩放)
- maximum-scale = 1.0:用户可以放大到的最大尺度(1.0表示不缩放)
- user-scalable = no:用户是否可以通过他的手势来缩放整个应用程序,使应用程序的尺度发生一个改变(yes/no)
当然,在<meta name="viewport" ……>
的背后关于视图及其属性,如布局视图,视觉视图,理想视图……可以参考这篇博客: 深入理解viewport及相关属性的关系
适配不同机型,设置rem单位长度
一般由于移动端各个不同型号手机其宽度不同
所以如果采用px固定住元素:比如你定义了一个div,里面定义了很多子元素,然后在iPhone6浏览器页面上面显示刚好是一行,但是一到iPhone5上各元素就突然换行了,乱成了一只皮皮虾
这是因为iPhone6的手机宽度是750px,iPhone5的宽度是640px,所以把一个750px的东西塞进640px宽的容器中肯定会出问题
(当年本人在实习做移动端页面开发的时候,每每切换到iPhone5总是一阵慌张,因为这个它页面宽度太小了,就很有可能会出现排版混乱的问题)
什么?你说Chrome devTools中显示的iPhone6宽度是375px,iPhone5宽度是320px,这就是另一个问题了,这牵扯到了css逻辑像素和手机物理像素的比例问题了,也就是关于DPR的问题:移动web开发之像素和DPR详解,可以点击这篇博客了解学习
人家珠玉在前,我也就不再长篇累牍地解释了
所以为了解决移动端页面宽高标准繁多的问题,就有这么一个解决思想:
整体布局可以采用百分比、flex布局,一些设计图上固定长度的元素,如按钮等可以使用rem布局
- 什么是rem呢?
rem:root em,这是一个相对单位,相对于HTML根元素font-size
属性大小决定其大小
举个例子:在css样式中设置html{font-size:20px}
那么 1rem=20px,所以当一个按钮宽度为10px时,可以换算为width: 0.5rem
- rem怎么做到适配的呢?
举个例子:在iPhone6中定义html{font-size:40px}
,然后设置一个按钮为width: 0.5rem
,这时候它的宽度是20px,然后你切换成iPhone5,在iPhone5中定义了html{font-size:30px}
,于是这个按钮宽度就变成了15px,因为iPhone5的宽度比较小,所以这个按钮宽度变小后在iPhone5中就不会撑出父元素
所以只要随着设备的不同改变根元素的font-size
属性大小,就能让所有以rem作为单位的元素自适应页面宽度 - 那么,什么时候使用rem布局呢?
根据大佬们的思想,宽度小于页面50%可以使用rem布局,再大就用百分比布局
因为rem不是万能的,当子元素在父元素中的宽度占比很大时,使用rem,当切换设备时候也有可能会出现排版混乱的情况 - 那么怎么设置改变根元素的
font-size
属性大小从而改变rem大小来适配不同机型呢?
这里有两种方案:
- 通过媒体查询来改变
font-size
,进而改变rem
举个例子:
html {
font-size: 62.5%
}
@media only screen and (min-width: 481px) { //当屏幕宽度小于481px
html {
font-size:94%!important
}
}
@media only screen and (min-width: 561px) { //当屏幕宽度小于561px
html {
font-size:109%!important
}
}
@media only screen and (min-width: 641px) { //当屏幕宽度小于641px
html {
font-size:125%!important
}
body {
max-width: 640px
}
}
这些屏幕最小宽度参数和 font-size
都是根据项目实际需求改变,并不唯一
- 通过js动态改变
font-size
,进而改变rem
当页面一加载的时候,js就获取当前设备的宽度,进而设置font-size
<script>
function refreshRem() {
var d= document.documentElement;
var width =d.getBoundingClientRect().width; //获取当前设备的宽度
if (width > 640 ){ // 640不固定,根据设计稿的宽度定
width = 640;
}
rem = width / 6.4;
console.log(rem);
d.style.fontSize = rem + "px"
}
refreshRem();
window.addEventListener("resize", function() { //监听横竖屏切换
refreshRem()
}, false);
</script>
这个script
代码可以直接粘贴到html <body></body>
标签的后面,直接可以使用
640这个宽度参数可以根据设计稿自定义,这里width取640,是根据iPhone5的宽度设置的,将devTools移动设备切换到iPhone5可以看到1rem=50px
总结
关于移动端适配的问题,当然还有其他的一些解决方案,像是淘宝,网易都有自己的解决方案,都比较好,也可以去搜搜且看看他们的解决思想
本文的移动端适配解决思想:
- 先在html
<head></head>
中设置meta标签:
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=10.0,user-scalable=no">
2.使用rem作为长度单位, 利用css媒体查询或者js动态设置根据页面宽度设置 font-size
从而改变rem,使得页面元素做到最大自适应,代码已经贴在上面了 (*´∀`)skr~