html5 的 rem、px、viewport 在页面布局中的作
2017-08-17 本文已影响322人
rayman_v
viewport
1. 没有 viewport
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
*{margin: 0; padding: 0;}
#full{background-color: red; width: 100%; height: 100px; font-size: 40px;}
</style>
</head>
<body>
<div id="full"></div>
<script>document.getElementById('full').textContent = document.documentElement.clientWidth;</script>
</body>
</html>

- 没有设置
viewport
的情况下,不同尺寸下的手机屏幕默认宽度都是980宽;
2. 设置 viewport
为固定的 width
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=360">
<style>
*{margin: 0; padding: 0;}
#full{background-color: red; width: 100%; height: 100px; font-size: 40px;}
</style>
</head>
<body>
<div id="full"></div>
<script>document.getElementById('full').textContent = document.documentElement.clientWidth;</script>
</body>
</html>

- 设置
<meta name="viewport" content="width=360">
后,会使页面在不同设备上显示相同宽度,事例中不管iPhone 5
或iPhone 6
页面都会变成360px
宽;
3. 设置 viewport
为设备的 width
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style>
*{margin: 0; padding: 0;}
#full{background-color: red; width: 100%; height: 100px; font-size: 40px;}
</style>
</head>
<body>
<div id="full"></div>
<script>document.getElementById('full').textContent = document.documentElement.clientWidth;</script>
</body>
</html>

- 设置
<meta name="viewport" content="width=device-width">
后,页面宽度会识别为硬件设备最优的宽度显示,这是使用最广泛的设置方式。
px 布局
1. viewport
为固定宽度下的 px
布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=360">
<style>
*{margin: 0; padding: 0;}
#full{background-color: red; height: 100px; font-size: 0;}
.item{background-color: yellow; height: 100px; width: 120px; display: inline-block; margin: 0 3px 0 0; font-size: 40px;}
</style>
</head>
<body>
<div id="full">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</body>
</html>

- 因为指定了宽度
360
,页面在任何设备上都可以横向布满3个.item
;
2. viewport
为设备宽度下的 px
布局
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style>
*{margin: 0; padding: 0;}
#full{background-color: red; height: 100px; font-size: 0;}
.item{background-color: yellow; height: 100px; width: 120px; display: inline-block; margin: 0 3px 0 0; font-size: 40px;}
</style>
</head>
<body>
<div id="full">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</body>
</html>

- 由于
<meta name="viewport" content="width=device-width">
页面在不同设备的宽度不同,导致在 iPhone 5 下为320px
,导致换行,而在 iPhone 6 下为375px
,横放3个框有余;
rem 布局
1. device-width
下的 rem
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style>
*{margin: 0; padding: 0;}
#full{background-color: red; height: 100px; font-size: 0;}
.item{background-color: yellow; height: 100px; width: 1rem; display: inline-block; margin: 0 3px 0 0; font-size: 14px;}
</style>
</head>
<body>
<div id="full">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</body>
</html>

-
rem
是以<html>
元素的font-size
为基数转化成的px
值,例如<html>
标签默认值font-size: 16px
,1rem
即等于16px
;
2. 手动设置 rem
基数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<style>
*{margin: 0; padding: 0;}
@media (max-width: 375px) {
html {font-size: 100px;}
}
@media (max-width: 320px) {
html {font-size: 50px;}
}
#full{background-color: red; height: 100px; font-size: 0;}
.item{background-color: yellow; height: 100px; width: 1rem; display: inline-block; margin: 0 3px 0 0; font-size: 14px;}
</style>
</head>
<body>
<div id="full">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</body>
</html>

- 通过媒体查询,我们可以分别为 iPhone 5 和 iPhone 6 设置不同的
rem
基数,实现不同设备宽度下,布局不同;
3. 动态设置 rem
基数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<script>
(function(doc,win,wid){
var rootEle = doc.documentElement,
wid = wid || 750;
recalc();
function recalc(){
rootEle.style.fontSize = 100*(rootEle.clientWidth/wid)+"px"
}
win.addEventListener('orientationchange',recalc,false);
win.addEventListener('resize',recalc,false);
})(document,window,750);</script>
<style>
*{margin: 0; padding: 0;}
#full{background-color: red; font-size: 0;}
.item{background-color: yellow; height: 2rem; width: 2rem; display: inline-block; margin: 0 3px 0 0; font-size: 14px;}
</style>
</head>
<body>
<div id="full">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
</body>
</html>


- 当使用
js
动态计算<html>
的font-size
再加上使用rem
布局,最终结果就跟<meta name="viewport" content="width=360">
加上px
布局的效果是一样的,就是不同设备宽度能够显示的页面宽度一样; - 这段
js
代码的意思是,传入的 750 为设计图总宽度,在任何屏幕宽度内,1rem
等于设计图中的100px
; - 举例:设计图总宽度为
640px
的情况下,应该在调用该js
时,把750
替换成640
,当设计图中有一个44px * 44px
的按钮,css
应为width: 0.44rem; height: 0.44rem
;
总结
-
<meta name="viewport" content="width=360">
能应付大部分h5
活动页面布局,但不被广泛使用; -
rem
虽然原理有点繁琐,但被广泛推广使用,这是有原因的,假设一种开发需求:
- 上面的
banner
需要在不同手机上,等比缩放展示同样的内容,而下面的text
则需要越大的屏幕,一行显示的文字越多,这种情况下,就需要px
和rem
能同时使用在同一页面内。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<script>
(function(doc,win,wid){
var rootEle = doc.documentElement,
wid = wid || 750;
recalc();
function recalc(){
rootEle.style.fontSize = 100*(rootEle.clientWidth/wid)+"px"
}
win.addEventListener('orientationchange',recalc,false);
win.addEventListener('resize',recalc,false);
})(document,window,750);</script>
<style>
*{margin: 0; padding: 0;}
.banner{background-color: red; width: 7.5rem; height: 4rem;}
.text{background-color: yellow; font-size: 16px;}
</style>
</head>
<body>
<div class="banner"></div>
<div class="text">“我们一定不负重托,不辱使命。”这是习近平总书记上任伊始作出的庄严承诺。五年过去,中国发展站到新的历史起点上,中国特色社会主义进入新的发展阶段,实现了从站起来、富起来到强起来的历史性飞跃,世界越来越看好中国。</div>
</body>
</html>