之前做了很多移动端布局,今天为大家总结一些经验。
一. viewport
如今可以绝大部分浏览器里(即主流的安卓浏览器和ios),都支持对viewport的一个控制了。一般的,我们会这么写。
viewport默认有6个属性
- 设置viewport的宽度(即之前所提及到的,浏览器的宽度详),这里可以为一个整数,又或者是字符串"width-device"
- initial-scale: 页面初始的缩放值,为数字,可以是小数
- minimum-scale: 允许用户的最小缩放值,为数字,可以是小数
- maximum-scale: 允许用户的最大缩放值,为数字,可以是小数
- height: 设置viewport的高度(我们一般而言并不能用到)
- user-scalable: 是否允许用户进行缩放,'no'为不允许,'yes'为允许
如:<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=0.5,minimum-scale=0.5,maximum-scale=0.5">
二. 关于我们的设备
-
需要了解的以下三个概念:
- PPI:Pixels Per Inch缩写,表示的是每英寸所拥有的像素数目
- DPR: 默认缩放为100%的情况下,设备物理像素和CSS像素(逻辑像素)的比值,即物理像素/逻辑像素
- Resolution: 就是我们常说的分辨率
-
物理像素与逻辑像素
看了我们上面内容,或许有些人会有些疑问,我的安卓手机,或者iphone6plus(目前应该仅限于这一款机型吧),买回来的是1920x1080的或者其他更高的,比我之前所谓的那个viewport默认的980px要大。
这样的问题,也就是我之前所说的物理像素与逻辑像素的关系了(即DPR)。以1920x1080为例,1080为物理像素,而我们在viewport中,获取到的,比如"width-device",是逻辑像素。所以之前viewport的默认值,所比对的大小,其实是逻辑像素的大小,而非物理像素的大小。
以iphone6为例,在不做任何缩放的条件下,iphone6的获取到的'width-device'为375px,为屏幕的逻辑像素。而购买时我们所知的750px,则为屏幕的物理像素。
-
CSS的问题
有了上面第二点的一些基础,还是以iphone6为例,我们可以知道,其实我们所写的1px,在iphone6上为2px的物理像素。所以,最后的,给出一个结论。就是我们写的1px,在移动端,是逻辑像素的1px,而非物理像素的1px。
三. 使用rem布局
这里先了解一下常用的一些单位:
px: 绝对单位,固定值
%:相对单位 在宽度计算上还是不错的,但是高度上就比较麻烦
em:相对单位 根据自身或者父级字体大小进行计算
rem:相对单位 r = root -> html 依赖简单,只受html的字体大小的影响。
到这里就是我们的重点,rem是相对根元素,所以我们可以根据屏幕宽度 来设置根元素html 的字体大小,从而使用rem 单位进行布局:
动态获取屏幕宽度设置字体大小的代码:
<script>
var initScale = 1 / window.devicePixelRatio;
document.write('<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale='+ initScale +',minimum-scale='+ initScale +',maximum-scale='+ initScale +'">')
console.log(window.document.documentElement.clientWidth);
var initWidth = window.document.documentElement.clientWidth;
document.getElementsByTagName('html')[0].style.fontSize = initWidth / 10 + 'px';
</script>
然后,我们就可以在页面布局中使用rem 为单位,实现动态布局,以适应屏幕尺寸。
最后,再给大家一个案例。
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script> var initScale = 1 / window.devicePixelRatio; document.write('<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=' + initScale + ',minimum-scale=' + initScale + ',maximum-scale=' + initScale + '">') var initWidth = window.document.documentElement.clientWidth; document.getElementsByTagName('html')[0].style.fontSize = initWidth / 10 + 'px'; </script> <style> html { height: 100%; overflow: hidden; } body { height: 100%; margin: 0; overflow: auto; } header, footer { position: absolute; 100%; height: 1.5625rem; background: orange; } header { top: 0; left: 0; } footer { bottom: 0; left: 0; } .content { overflow: hidden; margin: 1.5625rem 0; } div { 4.6875rem; height: 4.6875rem; margin: 0.15625rem; background: plum; float: left; } a { -webkit-tap-highlight-color: transparent; } input { -webkit-appearance: none; } </style> <!-- 目标(测量)元素 / rem大小 = 实际rem的值 在符合设计图和设备尺寸时: 1rem = 64px position: fixed; 在部分老系统或低版本浏览器中不支持 position: absolute; 兼容非常ok,但是滑动非常卡,需通过js配合 --> </head> <body> <header></header> <section class="content"> <a href="http://www.cnblogs.com/leeyen/">leeyen</a> <input type="button" value="btn"> <hr> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> </section> <footer></footer> </body> </html>
都是个人经验总结,如有问题,及时反馈,谢谢大家支持