前言
随着移动设备的普及,移动web在前端工程师们的工做中占有愈来愈重要的位置。移动设备更新速度频繁,手机厂商繁多,致使的问题是每一台机器的屏幕宽度和分辨率不同。这给咱们在编写前端界面时增长了困难,适配问题在当下显得愈来愈突出。记得刚刚开始开发移动端产品的时候向设计MM要了不一样屏幕的设计图,结果可想而知。本篇文章分享了一些处理多屏幕自适应的经验,但愿有益于各位。
特别说明:在开始这一切以前,请开发移动界面的工程师们在头部加上下面这条meta:javascript
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
简单事情简单作-宽度自适应
所谓宽度自适应严格来讲是一种pc端的自适应布局方式在移动端的延伸。在处理pc端的前端界面时候须要用到全屏布局时采用的就是此种布局方式。它的实现方式也比较简单,将外层容器元素按照百分比铺满的方式,里面的子元素固定或者左右浮动。css
.div { width:100%; height:100px; } .child { float: left; } .child { float:right; }
因为父级元素采用百分比的布局方式,随着屏幕的拉伸,它的宽度会无限的拉伸。而子元素因为采用浮动,那么它们的位置也会固定在两端。该宽度自适应在新的时代有了新的方法,随着弹性布局的普及,它常常被flex的伸缩性布局方式替代,变得愈来愈“弹性”十足。须要了解弹性布局,请前往flex布局教程。html
大小之辨-完成自适应前端
这种解决方案相对前一种来讲进步很多,不只仅宽度实现了自适应,并且界面全部的元素大小和高度都会根据不一样的分辨率和屏幕宽度的设备来调整元素、字体、图片、高度等属性的值。简单来讲就是在不一样的屏幕下,你看到的字体和元素高度的大小是不同的。在这里,有人就会说利用的是媒体查询属性,根据不一样的屏幕宽度,调整样式。我以前也是这样想的,可是你须要考虑到界面上的许多元素须要设置字体,若是用media query为每一个元素在不一样的设备下都设置不一样的属性的话,那么有多少中屏幕咱们的css就会增长多少倍。实际上在这里,咱们采用的是js和css属性rem来解决这个问题的。
REM属性指的是相对于根元素设置某个元素的字体大小。它同时也能够用做为设置高度等一系列能够用px来标注的单位。java
html { font-size: 10px; } div { font-size: 1rem; height: 2rem; width: 3rem; border: .1rem solid #000; }
采用以上写法,div继承到了html节点的font-size,为自己定义了一系列样式属性,此时1em计算为10px,即根节点的font-size值。因此,这时div的高度就是20px,宽度是30px,边框是1px,字体大小则是10px;一旦有了这样的方法,咱们天然能够根据不一样的屏幕宽度设置不一样的根节点字体大小。假设咱们如今设计的标准是iphone5s,iphone5系列的屏幕分辨率是640。为了统一规范,咱们将iphone5 分辨率下的根元素font-size设置为100px;web
<!--iphone5--> html { font-size: 100px; }
那么以此为基准,能够计算出一个比例值6.4。咱们能够得知其余手机分辨率的设备下根元素字体大小:bootstrap
/* 数据计算公式 640/100 = device-width / x 能够设置其余设备根元素字体大小 ihone5: 640 : 100 iphone6: 750 : 117 iphone6s: 1240 : 194 */ var deviceWidth = window.documentElement.clientWidth; document.documentElement.style.fontSize = (deviceWidth / 6.4) + 'px';
在head中,咱们将以上代码加入,动态地改变根节点的font-size值。
接下来咱们能够根据根元素的字体大小用rem设置各类属性的相对值。固然,若是是移动设备,屏幕会有一个上下限制,咱们能够控制分辨率在某个范围内,超过了该范围,咱们就再也不增长根元素的字体大小了:浏览器
var deviceWidth = document.documentElement.clientWidth > 1300 ? 1300 : document.documentElement.clientWidth; document.documentElement.style.fontSize = (deviceWidth / 6.4) + 'px';
通常的状况下,你是不须要考虑屏幕动态地拉伸和收缩。固然,假如用户开启了转屏设置,在网页加载以后改变了屏幕的宽度,那么咱们就要考虑这个问题了。解决此问题也很简单,监听屏幕的变化就能够作到动态切换元素样式:前端工程师
window.onresize = function(){ var deviceWidth = document.documentElement.clientWidth > 1300 ? 1300 : document.documentElement.clientWidth; document.documentElement.style.fontSize = (deviceWidth / 6.4) + 'px'; };
为了提升性能,让代码开起来更加完美,能够为它加上节流阀函数:app
window.onresize = _.debounce(function() { var deviceWidth = document.documentElement.clientWidth > 1300 ? 1300 : document.documentElement.clientWidth; document.documentElement.style.fontSize = (deviceWidth / 6.4) + 'px'; }, 50);
顺带解决高保真标注与实际开发值比例问题
若是大家设计稿标准是iphone5,那么拿到设计稿的时候必定会发现,彻底不能按照高保真上的标注来写css,而是将各个值取半,这是由于移动设备分辨率不同。设计师们是在真实的iphone5机器上作的标注,而iphone5系列的分辨率是640,实际上咱们在开发只须要按照320的标准来。为了节省时间,不至于每次都须要将标注取半,咱们能够将整个网页缩放比例,模拟提升分辨率。这个作法很简单,为不一样的设备设置不一样的meta便可:
var scale = 1 / devicePixelRatio; document.querySelector('meta[name="viewport"]').setAttribute('content', 'initial-scal')
这样设置一样能够解决在安卓机器下1px像素看起来过粗的问题,由于在像素为1px的安卓下机器下,边框的1px被压缩成了0.5px了。总之是一劳永逸!淘宝和网易新闻的手机web端就是采用以上这种方式,自适应各类设备屏幕的,你们有兴趣能够去参考参考。下面是完整的代码:
<!DOCTYPE html> <html> <head> <title>测试</title> <meta name="viewport" content="width=device-width,user-scalable=no,maximum-scale=1" /> <script type="text/javascript"> (function() { // deicePixelRatio :设备像素 var scale = 1 / devicePixelRatio; //设置meta 压缩界面 模拟设备的高分辨率 document.querySelector('meta[name="viewport"]').setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); //debounce 为节流函数,本身实现。或者引入underscoure便可。 var reSize = _.debounce(function() { var deviceWidth = document.documentElement.clientWidth > 1300 ? 1300 : document.documentElement.clientWidth; //按照640像素下字体为100px的标准来,获得一个字体缩放比例值 6.4 document.documentElement.style.fontSize = (deviceWidth / 6.4) + 'px'; }, 50); window.onresize = reSize; })(); </script> <style type="text/css"> html { height: 100%; width: 100%; overflow: hidden; font-size: 16px; } div { height: 0.5rem; widows: 0.5rem; border: 0.01rem solid #19a39e; } ........ </style> <body> <div> </div> </body> </html>
让元素飞起来-媒体查询
运用css新属性media query 特性也能够实现咱们上说到过的布局样式。为尺寸设置根元素字体大小:
@media screen and (device-width: 640px) { /*iphone4/iphon5*/ html { font-size: 100px; } } @media screen and (device-width: 750px) { /*iphone6*/ html { font-size: 117.188px; } } @media screen and (device-width: 1240px) { /*iphone6s*/ html { font-size: 194.063px; } }
这种方式也是可行的,缺点是灵活性不高,取每一个设备的精确值须要本身去计算,因此只能取范围值。考虑设备屏幕众多,分辨率也良莠不齐,把每一种机型的css代码写出来是不太可能的。可是它也有优势,就是无需监听浏览器的窗口变化,它会跟随屏幕动态变化。媒体查询的用法固然不只仅像在此处这么简单,相对于第二种自适应来讲有不少地方是前者所远远不及的。最明显的就是它能够根据不一样设备显示不一样的布局样式!请注意,这里已经不是改变字体和高度那么简单了,它直接改变的是布局样式!
@media screen and (min-width: 320px) and (max-width: 650px) { /*手机*/ .class { float: left; } } @media screen and (min-width: 650px) and (max-width: 980px) { /*pad*/ .class { float: right; } } @media screen and (min-width: 980px) and (max-width: 1240px) { /*pc*/ .class { float: clear; } }
此种自适应布局通常经常使用在兼容PC和手机设备,因为屏幕跨度很大,界面的元素以及远远不是改改大小所能知足的。这时候须要从新设计整界面的布局和排版了。
许多css框架常常用到这样的多端解决方案,著名的bootstrap就是采用此种方式进行栅格布局的。