移动端项目的布局
viewport
移动设备上的viewport
就是设备的屏幕上能用来显示我们的网页的那一块区域,在具体一点,就是浏览器上(也可能是一个app
中的webview
)用来显示网页的那部分区域,但viewport
又不局限于浏览器可视区域的大小,它可能比浏览器的可视区域要大,也可能比浏览器的可视区域要小。
在默认情况下,移动设备上的浏览器都会把自己默认的viewport
设为980px
或1024px
,但带来的后果就是浏览器会出现横向滚动条,因为浏览器可视区域的宽度是比这个默认的viewport
的宽度要小的。下图列出了一些设备上浏览器的默认viewport
的宽度。
layout viewport
如果把移动设备上浏览器的可视区域设为viewport
的话,某些网站会因为viewport
太窄而显示错乱,所以这些浏览器就默认会把viewport
设为一个较宽的值,比如 980px,使得即使是那些为PC
浏览器设计的网站也能在移动设备浏览器上正常显示。这个浏览器默认的viewport
叫做layout viewport
。layout viewport
的宽度可以通过document.documentElement.clientWidth
来获取。
visual viewport
layout viewport
的宽度是大于浏览器可视区域的宽度的,所以还需要一个viewport
来代表浏览器可视区域的大小,这个viewport
叫做visual viewport
。visual viewport
的宽度可以通过document.documentElement.innerWidth
来获取。
ideal viewport
ideal viewport
是一个能完美适配移动设备的viewport
。首先,不需要缩放和横向滚动条就能正常查看网站的所有内容;其次,显示的文字、图片大小合适,如14px的文字不会因为在一个高密度像素的屏幕里显示得太小而无法看清,无论是在何种密度屏幕,何种分辨率下,显示出来的大小都差不多。这个viewport
叫做 ideal viewport
。
css中的1px并不等于设备的1px
在早先的移动设备中,屏幕像素密度都比较低,如iphone3
,它的分辨率为 320x480,在iphone3
上,一个css
像素确实是等于一个屏幕物理像素的。后来随着技术的发展,移动设备的屏幕像素密度越来越高,从iphone4
开始,苹果公司便推出了所谓的Retina
屏,分辨率提高了一倍,变成 640x960,但屏幕尺寸却没变化,这就意味着同样大小的屏幕上,像素却多了一倍,这时,一个css
像素是等于两个物理像素的。
在移动端浏览器中以及某些桌面浏览器中,window
对象有一个devicePixelRatio
属性,它的官方的定义为:设备物理像素和设备独立像素的比例,也就是 devicePixelRatio
= 物理像素 / 独立像素。
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
rem自适应原理
rem
(font size of the root element
)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。看到rem
大家一定会想起em
单位,em
(font size of the element
)是指相对于父元素的字体大小的单位。它们之间其实很相似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。
@media
html {
font-size : 20px;
}
@media only screen and (min-width: 401px){
html {
font-size: 25px !important;
}
}
@media only screen and (min-width: 428px){
html {
font-size: 26.75px !important;
}
}
@media only screen and (min-width: 481px){
html {
font-size: 30px !important;
}
}
@media only screen and (min-width: 569px){
html {
font-size: 35px !important;
}
}
@media only screen and (min-width: 641px){
html {
font-size: 40px !important;
}
}
REM自适应JS
//designWidth:设计稿的实际宽度值,需要根据实际设置
//maxWidth:制作稿的最大宽度值,需要根据实际设置
//这段js的最后面有两个参数记得要设置,一个为设计稿实际宽度,一个为制作稿最大宽度,例如设计稿为750,最大宽度为750,则为(750,750)
;(function(designWidth, maxWidth) {
var doc = document,
win = window,
docEl = doc.documentElement,
remStyle = document.createElement("style"),
tid;
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
maxWidth = maxWidth || 540;
width>maxWidth && (width=maxWidth);
var rem = width * 100 / designWidth;
remStyle.innerHTML = 'html{font-size:' + rem + 'px;}';
}
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(remStyle);
} else {
var wrap = doc.createElement("div");
wrap.appendChild(remStyle);
doc.write(wrap.innerHTML);
wrap = null;
}
//要等 wiewport 设置好后才能执行 refreshRem,不然 refreshRem 会执行2次;
refreshRem();
win.addEventListener("resize", function() {
clearTimeout(tid); //防止执行两次
tid = setTimeout(refreshRem, 300);
}, false);
win.addEventListener("pageshow", function(e) {
if (e.persisted) { // 浏览器后退的时候重新计算
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
}, false);
if (doc.readyState === "complete") {
doc.body.style.fontSize = "16px";
} else {
doc.addEventListener("DOMContentLoaded", function(e) {
doc.body.style.fontSize = "16px";
}, false);
}
})(750, 750);