1. 固定宽度(320)作法:这样前端却是爽了,但是大页面两边有留白,小页面图标文字又会缩的很小,用户体验极其很差。css
2. 流式布局:其实就是用%,这样宽度倒还差很少,高度怎么搞?因此这种布局通常都是宽度自适应高度写死,显的很不协调,另外对设计也有很大的限制,另外还有兼容性方面的问题。html
3. 响应式布局:说白了就是利用CSS3中的Media Query(媒介查询),喊的很火,谁用谁知道,简直累死人不要命。前端
4. 设置viewport进行缩放:以320宽度为基准,进行缩放,最大缩放为320*1.3 = 416,基本缩放到416都就能够兼容iphone6 plus的屏幕了。<meta name="viewport" content="width=320,maximum-scale=1.3,user-scalable=no">git
5. 利用vh、vw适配:兼容性太差。github
rem是一个相对根元素html字体大小的单位,因此它的大小是由html的fontSize大小决定的,假如我把html的fontSize设置为10px,此时的1rem就等于10px,假如我把html的fontSize设置为100px,此时的1rem就等于100px,这也正是咱们能用rem作移动端适配的根本缘由,就是经过不一样屏幕下改变根元素fontSize的大小,从而让以rem为单位的各类元素自动随着改变。web
经过下面这句话得到理想视口(ideal viewport):chrome
<meta name="viewport" content="width=device-width">
既然要适配,就要选一个理想视口作基准,而后才能在此基础上等比缩放(这里等比缩放最好不包括文字,后面讲缘由),咱们通常选择iphone6的375,为何选它呢?浏览器
由于市场上的Android机五花八门(理想视口宽通常在320-480之间),且没有任何一款的占有率能和iphone相比,选取iphone中的iphone6能更好的向下适配iphone5和向上适配iphone6 plus等,关于各机型的理想视口(ideal viewport)详见VIEWPORT SIZESsass
上面说了咱们要以iphone6为基准,那么设计图咱们作成多大呢?dom
设计图作成750px宽,由于iphone6的物理像素是750(上面咱们说的375是它的设备独立像素,又是理想视口),咱们要想作到高清就要1个设计像素对应一个物理像素才成,他们之间的关系见下表:
iPhone6 plus | iPhone6 | iPhone5 | |
物理像素(physical pixel) | 看公式 | 看公式 | 看公式 |
设备独立像素(density-independent pixel) | 414x736 | 375×667 | 320x568 |
设备像素比(device pixel ratio ) | 3 | 2 | 2 |
设备像素比(dpr),咱们能够经过JavaScript获取的办法是:window.devicePixelRatio
;用CSS获取的办法是-webkit-device-pixel-ratio
。咱们能够用-webkit-min-device-pixel-ratio
和-webkit-max-device-pixel-ratio
进行媒体查询,以达到适配不一样dpr的需求。
原理:用媒体查询理想视口(上面咱们把width=device-width了,因此查询width便可),不一样理想视口设置不一样的根元素fontSize。
一张750的设计稿,假如其根元素为100px(为何是100px而不是其余的呢?),此时我想表示一个750px*100px的div,我只须要写成:
div{width:7.5rem; height:1rem;}
那么问题来了,我在iphone6下把根元素字体设为多大才能让这个div等比显示呢?要想等比显示那么他们之间有这样一个关系:
100px / 750 = iphone6 根元素fontSize / iphone6理想视宽(375)
根据上面公式算出iphone6 根元素fontSize = 50px,也就是在iphone6下咱们只须要改变根元素fontSize为50px就能够作到等比缩放啦~~
那么问题又来了,手机那么多,各类机型的理想宽度也数不胜数(其实大多都在320到480之间,上面有说),那么其对应根元素fontSize我该怎么写呢?
做为一个CSSer,咱们最早想到的是媒体断点查询,例如像下面这样:
@media screen and (min-width:321px) and (max-width:375px){ html{font-size:42px} } @media screen and (min-width:376px) and (max-width:414px){ html{font-size:50px} } @media screen and (min-width:415px) and (max-width:639px){ html{font-size:55px} } @media screen and (min-width:640px) and (max-width:719px){ html{font-size:85px} } @media screen and (min-width:720px) and (max-width:749px){ html{font-size:95x} } @media screen and (min-width:750px) and (max-width:800px){ html{font-size:100px} }
上面的缺点一目了然,就是不够精细嘛,例如415-639理想视宽的手机显示的东西倒是同样大,对于像素级要求的咱们这怎么能成呢?
因而乎我用sass把从320到750所有算一遍不就能够啦,就像下面这样:
@media (max-width: 320px){ html{ font-size: 266.66667%; } } @for $i from 320 through 750 {@media (width:#{$i}px){ html{font-size: $i/1.2 * 1%}} } @media (min-width: 750px){ html{ font-size: 625%; } }
Sass生成结果(景象过于壮观慎入),大功告成,这样咱们不用JavaScript也能实现和其同样的精细效果了。使用时只需在头部引用这样一个CSS文件便可,假如750上你量出的div大小为width:85px;height:100px;
,写的时候只需除以100便可,即width:.85rem;height:1rem;
你要嫌除的麻烦sublime中能够装这么一个转换插件。
这时确定会有人吐槽性能问题洛,压缩后的media100px.css大概10几kb的样子,我看了下我们移动网站的一个普通商品图大概是它的2倍,固然拿两个东西进行比较是有点不太稳当,具体增长这么些样式会影响多大性能暂未验证。
之因此在750下把根元素设为100而不是其余,是由于方便计算嘛,1rem等于100px,.2rem就等与20px这样多好算啊,有人会问你丫设为10不同好算啊,话说通常浏览器显示的最小字号是12px,因此就100啦,固然数学好的你用其余值也是能够的。
上面用Sass生成的css根元素字体大小我是用%号表示的,就是100px,我写的是625%,有人可能会问你这干吗画蛇添足呢,625%不就是100px嘛,有人给出了下面几个理由,我抄下来共你们参考:
上面直接引用直接media100px.css的确不是最好的方案,你知道我要说什么啦,那就是用JavaScript适配,其实咱们把上面的Sass循环改为用JS写就行了,就像下面这样:
!(function(doc, win) { var docEle = doc.documentElement, evt = "onorientationchange" in window ? "orientationchange" : "resize",//区分Mobile和PC以加载不一样的事件 fn = function() { var width = docEle.clientWidth; if( width < 320 ) { docEle.style.fontSize = 42.6667 + "px"; } else if( width > 750 ) { docEle.style.fontSize = 100 + "px"; } else { //以750设计稿宽度为基准设置fontSize:100px;这样保证iPhone6如下是高清 docEle.style.fontSize = 100 * (width / 750) + "px"; } }; win.addEventListener(evt, fn, false); //load事件是在页面全部元素都加载完后触发; //DOMContentLoaded,它是指dom tree加载完就触发,页面引用的样式表和图像文件可能尚未加载完成 doc.addEventListener("DOMContentLoaded", fn, false); }(document, window));
在使用的时候你能够单独引用这样一段JS (看上面我又不用%而用px啦,测试(chrome模拟手机测试的)后发现%和px最终造成网页效果并没有差异),不使用不引用便可;或者把这段JS放在公共JS文件里,而对于不想使用rem的同窗只需覆盖JS设置的样式便可,例如像下面这样:
html{font-size:20px!important;}//这里移动端默认字体大小根据状况本身设置
1.文字最好不要用rem表示,由于:
其一:设计师通常但愿是文字在移动设备上的显示大小是同样的,也就是咱们所说的等比适配(注意是等比适配不包括,不是适配)是不该包括文字的;
其二:咱们用rem后文字会很小(虽然这正是等比缩放的结果),固然这也和设计有关(理论上字体须要等比适配的话750px设计图上是不该该有小于24px字体出现的,既然有也说明字体不该该等比适配),例如我在设计图上量取的文字大小是24px,那么其iphone6下的显示大小就是.24rem*50=12px,而设计图上哪些24如下的字体此时也会显示12px(假如最小字体是12的话),这也会有另一个问题,就是设计图上明明是不一样字体大小表示的文案,在手机上显示的大小倒是同样的,起不到设计师想要表达的区分或者强调的做用;
其三:网上有说会变模糊之类的,我暂时未发现(暴漏了我依然表示字体用rem表示的...)。
解决办法:能够分断点区间,设置不一样的fontSize大小,能够参考点我
2.1px和2px不要写成.01rem和.02rem,由于:
以750适配的方案为例,当理想视口为320时,其对应font-size: 266.66667%; 而后乘以默认字体大小16px,最后为42.6666672px,也就是43px,若写为.01rem或.02rem表示分别对应.42px或.96px,在直接取整的浏览器下是显示不出来的。因此对于1像素边框的就不要写.01rem啦。
3.当咱们写1px时,实际在dpr为2的手机下显示的是2个物理像素,看起来会粗一点,解决方案能够参照淘宝的flexible,其原理是根据dpr的不一样动态设置initial-scale的值,也能够用下面方法实现:
.scale { position: relative; height: 50px; line-height: 50px; background-color: #ccc;
} .scale:after { position: absolute; content: ''; width: 100%; left: 0; bottom: 0; height: 1px; background-color: red; -webkit-transform: scale(1,.5); transform: scale(1,.5); -webkit-transform-origin: center bottom; transform-origin: center bottom;
}
注:JavaScript适配方案是一种思路或者中心思想,在实际使用中会有其余一些问题须要注意,例如JS的加载时机以及其余有一些安卓机的奇怪问题,具体能够参考淘宝的flexible解决方法,或者参考咱们目前在用的方案:flexible精简版下载。
以上文字友好阅读方式:点我下载