关于移动端适配的三种方案.
移动端适配,主要是适配手机和一些平板设备.
为什么需要适配呢?
在客观条件上,这些设备的物理宽度都是不一致的.
比如手机的宽度就有 3xx
| 4xx
| 5xx
等.
如果按照我们常用的 width = xxxpx
肯定是不行的.
比如我们在一个 320
宽度的设备上,设置某个元素的宽度是 80px
我们这么设置的理由是: 希望在屏幕上可以横向摆列4个这样的元素.
但是在在不是320
宽度的设备上,这么写直接写80px
是肯定不行的.
移动端适配方案一 --- 百分比适配
在移动端适配的方案里,百分比适配方案是最容易理解的一种.
我们都知道设置某个元素的宽高百分比,是根据其父容器的宽高来进行的(局限:父元素宽高已知).
比如,我们在一个希望在所有的移动端设备里,不管屏幕宽度是多少,都希望一行能排列4个元素,并刚好占满.
我们只需要设置每个元素的宽度是 25%
即可.
* {
margin: 0;
padding: 0;
}
div {
width: 25%;
float: left;
height: 100px;
}
.box1 {
background-color: red;
}
.box2 {
background-color: yellow;
}
.box3 {
background-color: green;
}
.box4 {
background-color: orange;
}
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
在 3xx 4xx 5xx 里面宽度显示都没问题.
宽度百分比适配但是问题来了.
对于宽度的计算,百分比确实能够做到非常完美的适配(父容器宽度已知的情况下).
**但是高度呢?**
比如在 320 屏幕里,我设置的高度是 `100px`.
根据比例计算
+ 在 375 宽度的屏幕设备里,高度应该是 375 * 100 / 320 = 117.19px
+ 在 414 宽度的屏幕设备里,高度应该是 414 * 100 / 320 = 129.375px
像上述那样写死 100px 的高度,肯定就不行了.
**所以使用百分比适配,可以适配元素的宽度,但是高度无法适配.**
且即使是宽度,也只能是在父容器宽度已知的条件下,百分比设置宽度才有效果.
移动端设备适配方案二 --- viewport 视口适配
说 viewport 视口适配之前,先来说说什么是viewport.
viewport 是移动端开发中,非常重要的一个 meta 设置标签.它用于初始化当前移动端设备的宽度,初始缩放比例,用户是否可缩放等一系列指令.
如果,我们在移动端开发的情况下,没有加这个标签,来指定设备的宽度.
// 只要是 width=device-width
<meta name="viewport" content="width=device-width, initial-scale=1.0">
那么,基本上所有移动端设备的宽度会被设置成 980px
..
我们又一般有PC的经验,会把字体设置成16px.
所以,在一个移动端设备由于没有加 viewport ,默认宽度是 980 px, 字体又被我们习惯性的设置成 16px. 就会出现字体非常小,根本无法阅读的情况.
移动端不设置viewport,默认宽度是980pxviewport 视口适配的方案的核心在于:给定一个目标的屏幕宽度,然后根据当前设备实际的屏幕宽度进行缩放比例的设置.
- 按照一个固定的屏幕宽度来进行适配.
- 比如,我写的设备宽度就是320.
- 那么一个1/4屏幕的宽度就是80px.(我像素就写80px)
- 如果正好在一个320,那么刚好就是1/4.没毛病.
- 如果是在一个屏幕宽度为640的设备上,写死80px,就只能占1/8. 解决办法就是,把640设备的初始比例设置成2倍.(对,没错,就是放大两倍显示)
- 对于一个160宽度屏幕的设备,我们就缩小两倍显示.
上述那个比例计算,是根据当前设备的屏幕宽度来的.所以肯定需要动态计算.
(function () {
let screenW = window.screen.width // 获取当前设备屏幕宽度
let targetWidth = 320 // 目标宽度
let scale = screenW / targetWidth // 当前设备屏幕宽度 / 目标宽度 = 缩放比例 (640=2,160=0.5)
// 然后根据计算出来的结果,初始化当前设备的缩放比例.
let meta = document.createElement('meta')
meta.name = 'viewport' // 视口设置的meta
meta.content = 'user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}'
document.head.appendChild(meta)
})()
有了上述这段代码,在所有的设备里,都会进行比例缩放.
所以,我们可以安心的在自己的css代码里写死像素了(反正小了就放大,大了就缩小).
* {
margin:0;
padding: 0;
}
div {
width: 80px; /* 宽度80px 写死 */
float: left;
height: 100px; /* 高度 100px 写死 */
}
.box1 {
background-color: red;
}
.box2 {
background-color: yellow;
}
.box3 {
background-color: green;
}
.box4 {
background-color: orange;
}
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div class="box4"></div>
pixel2
pixel2iPhone 4
iPhone 4iPad
iPad注意:
使用 viewport 进行初始比例的设置进行适配,千万不好在 viewport 里设置
width=device-width
.
移动端适配方案三 --- rem 适配.
rem 是什么 ?
Relative to font-size of root Element
相对于根元素的字体大小.
在一个HTML元素中,根元素就是 <html> 标签.
所以 rem 等于设置到 html 上 font-size 的大小.
比如:
- html 的 font-size 设置成了 16 px, 那么 1rem = 16px.
- html 的 font-size 设置成了 100px , 那么 1rem = 100px.
这么粗看一下,好像觉得这个rem很无聊.
但是实际上, font-size = 16 px , 这里其实指的更多的是一个字的宽度.一个字的宽度是16px.
宽度是什么? 宽度是屏幕的尺寸单位!!
如果有一个设备的宽度是160px. 我设置html.font-size=16px.
那么我就可以理解成,利用rem,将这个屏幕的宽度按比例的分割成了10份.
Rem如果是 320 宽度的设备,想平分成10分呢? html.font-size = 32px
所以,对于 rem 的设置仍然是先获取当前设备的宽度,并动态计算.
(function () {
// 根据不同设备,将屏幕按照比例分割成10份.
let screenWidth = document.documentElement.clientWidth || window.screen.width
let oneRem = screenWidth / 10
document.documentElement.style.fontSize = `${oneRem}px`
})()
查看结果:
iPhone 5
iPhone 5iPad
iPad现在已经成功的将设备按照屏幕宽度平均分成了10分.
那么接下来的所有布局,就可以完全按照屏幕宽度的刻度来进行了.
比如,有这么一个布局.
元素的宽度是屏幕宽度的一半(5rem),高度是屏幕宽度的1/5(2rem)
* {
padding: 0;
margin: 0;
}
div {
width: 5rem; /* 比例=当期那设备宽度的一半 */
height: 2rem; /* 比例=当前设备宽度的1/5 */
float: left;
}
.box1 {
background-color: red;
}
.box2 {
background-color: orange;
}
<div class="box1"></div>
<div class="box2"></div>
查看结果:
iPad
iPadiPhone 4
iPhone 4未完待续...