首頁 > web前端 > H5教程 > 知名網站的行動前端自適應解決方案與比較

知名網站的行動前端自適應解決方案與比較

PHPz
發布: 2017-04-03 14:52:42
原創
2311 人瀏覽過

網路上的自適應方案到底有幾種呢?就我個人實踐所知,有這麼多方案:

  1. 固定一個某些寬度,使用一個模式,加上少許的媒體查詢方案

  2. 使用flexbox解決方案

  3. 使用百分比加媒體查詢

  4. #使用rem

淘寶最近開源的一個框架和網易的框架有同工之異。都是採用rem實作一稿解決所有設定自適應。在沒出來這種方案之前,第一種做法的人數也不少。類似以下說到的拉鉤網。看一下流雲諸葛的文章。

以下摘自:從網易與淘寶的font-size思考前端設計稿與工作流程

1. 簡單問題簡單解決

#我覺得有些web app並一定很複雜,例如拉勾網,你看看它的頁面在iphone4,iphone6,ipad下的樣子就知道了:

知名網站的行動前端自適應解決方案與比較知名網站的行動前端自適應解決方案與比較

知名網站的行動前端自適應解決方案與比較

它的頁面有一個特點,就是:

  • #頂部與底部的bar不管解析度怎麼變,它的高度和位置都不變

  • 中間每則招募資訊不管解析度怎麼變,招募公司的圖示等資訊都位於條目的左邊,薪資都位於右邊

#這種app是一種典型的彈性佈局:關鍵元素高寬和位置都不變,只有容器元素在做伸縮變換。對於這類app,記住一個開發原則就好:文字流式,控制彈性,圖片等比縮放。以圖描述:

知名網站的行動前端自適應解決方案與比較

這個規則是一套基本的適配規則,對於這種簡單app來說已經足夠,同時它也是後面要說的 rem佈局的基礎。另外對於拉勾這種app可能需要額外媒介查詢對佈局進行調整的就是小螢幕裝置。舉例來說,因為現在很多設計稿是根據iphone6的尺寸來的,而iphon6設備寬的邏輯的像素是375px,而iphone4的邏輯像素是320個像素,所以如果你根據設計稿做出來的東西,在iphone4裡面可能顯示不下,比如說拉鉤網底部那個下載框,你比較看下就知道了,這是4:

知名網站的行動前端自適應解決方案與比較

這是6:

知名網站的行動前端自適應解決方案與比較

6下面兩邊的間距比4多很多,說明拉勾對4肯定是做過適配的,從程式碼也可以證實這一點:

知名網站的行動前端自適應解決方案與比較

不過如果你拿到的是根據4的設計稿,那就沒有問題,比4解析度大的設備肯定能顯示根據4的尺寸做出來的東西。

還有一點,這種情況css尺寸單位用px就好,不要用rem,避免增加複雜度。

2. 網易的做法

先來看看網易在不同解析度下,呈現的效果:

知名網站的行動前端自適應解決方案與比較知名網站的行動前端自適應解決方案與比較

知名網站的行動前端自適應解決方案與比較知名網站的行動前端自適應解決方案與比較

#

從上面幾張圖可以看出,隨著解析度的增加,頁面的效果會明顯變化,主要體現在各個元素的寬高與間距。 375*680的比320*680的導覽列明顯要高。能夠達到這種效果的根本原因就是因為網易頁面裡除了font-size之外的其它css尺寸都使用了rem作為單位,例如你看導航欄的高度設定代碼:

知名網站的行動前端自適應解決方案與比較

可是在本文第1部分提到,使用rem佈局結合在html上根據不同解析度設定不同font-size有很多不好解決的麻煩,網易是如何解決的呢?最根本的原因在於,網易頁面上html的font-size不是預先透過媒介查詢在css裡定義好的,而是透過JS計算出來的,所以當解析度改變時,html的font-size就會變,不過這得在你調整解析度後,刷新頁面才能看到效果。看程式碼就知道為啥font-size是直接寫到html的style上面的了(js設定的原因):

知名網站的行動前端自適應解決方案與比較

它是根據什麼計算的,這就跟設計稿有關了,拿網易來說,它的設計稿應該是基於iphone4或者iphone5來的,所以它的設計稿豎直放時的橫向分辨率為640px,為了計算方便,取一個100px的font-size為參照,那麼body元素的寬度就可以設定為width: 6.4rem,於是html的font-size=deviceWidth / 6.4。這個deviceWidth就是viewport設定中的那個deviceWidth。根據這個計算規則,可得出本部分開始的四張截圖中html的font-size大小如下:


#
deviceWidth = 320,font-size = 320 / 6.4 = 50px
deviceWidth = 375,font-size = 375 / 6.4 = 58.59375px
deviceWidth = 414,font-size = 414 / 6.4 = 64.6875px
deviceWidth = 500,font-size = 500 / 6.4 = 78.125px
登入後複製

事實上網易就是這麼幹的,你看它的程式碼就知道,body元素的寬是:

知名網站的行動前端自適應解決方案與比較

根據這個可以肯定它的設計稿豎起時的橫向解析度為640。然後再看看網易在解析度為320*680,375*680,414*680,500*680時,html的font-size是不是與上面計算的一致:

知名網站的行動前端自適應解決方案與比較#320 *680

知名網站的行動前端自適應解決方案與比較375*680

知名網站的行動前端自適應解決方案與比較414*680

知名網站的行動前端自適應解決方案與比較500*680

#這個deviceWidth透過document.documentElement .clientWidth就能取到了,所以當頁面的dom ready後,做的第一件事就是:


document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 + 'px';
登入後複製
登入後複製

這個6.4怎麼來的,當然是根據設計稿的橫向解析度/100得來的。以下總結下網易的這個做法:

  • (1)先拿設計稿豎起的橫向解析度除以100得到body元素的寬度:


    #
    如果设计稿基于iphone6,横向分辨率为750,body的width为750 / 100 = 7.5rem
    如果设计稿基于iphone4/5,横向分辨率为640,body的width为640 / 100 = 6.4rem
    登入後複製
  • (2)佈局時,設計圖示註的尺寸除以100得到css中的尺寸,例如下圖:

  • 知名網站的行動前端自適應解決方案與比較

  • 播放器高度為210px,寫樣式的時候css應該這麼寫:height: 2.1rem。之所以取一個100作為參照,就是為了這裡計算rem的方便!

  • (3)在dom ready以後,透過以下程式碼設定html的font-size:


    document.documentElement.style.fontSize = document.documentElement.clientWidth / 6.4 + 'px';
    登入後複製
    登入後複製
  • 6.4只是舉個例子,如果是750的設計稿,應該除以7.5。

  • (4)font-size可能需要額外的媒介查詢,而font-size不能使用rem,如網易的設定:


    @media screen and (max-width:321px){
        .m-navlist{font-size:15px}
    }
    
    @media screen and (min-width:321px) and (max-width:400px){
        .m-navlist{font-size:16px}
    }
    
    @media screen and (min-width:400px){
        .m-navlist{font-size:18px}
    }
    登入後複製

最後還有2個情況要說明:

第一,如果採用網易這種做法,視口要如下設定:


<meta>
登入後複製
登入後複製

第二,當deviceWidth大於設計稿的橫向解析度時,html的font-size總是等於橫向解析度/body元素寬:

知名網站的行動前端自適應解決方案與比較640*680

知名網站的行動前端自適應解決方案與比較641*680

之所以这么干,是因为当deviceWidth大于640时,则物理分辨率大于1280(这就看设备的devicePixelRatio这个值了),应该去访问pc网站了。事实就是这样,你从手机访问网易,看到的是触屏版的页面,如果从pad访问,看到的就是电脑版的页面。如果你也想这么干,只要把总结中第三步的代码稍微改一下就行了:


var deviceWidth = document.documentElement.clientWidth;
if(deviceWidth > 640) deviceWidth = 640;
document.documentElement.style.fontSize = deviceWidth / 6.4 + 'px';
登入後複製

3. 淘宝的做法

看看淘宝在不同分辨率下,呈现的效果:

知名網站的行動前端自適應解決方案與比較知名網站的行動前端自適應解決方案與比較知名網站的行動前端自適應解決方案與比較

淘宝的效果跟网易的效果其实是类似的,随着分辨率的变化,页面元素的尺寸和间距都相应变化,这是因为淘宝的尺寸也是使用了rem的原因。在介绍它的做法之前,先来了解一点关于viewport的知识,通常我们采用如下代码设置viewport:


<meta>
登入後複製
登入後複製

这样整个网页在设备内显示时的页面宽度就会等于设备逻辑像素大小,也就是device-width。这个device-width的计算公式为:

设备的物理分辨率/(devicePixelRatio * scale),在scale为1的情况下,device-width = 设备的物理分辨率/devicePixelRatio 。

devicePixelRatio称为设备像素比,每款设备的devicePixelRatio都是已知,并且不变的,目前高清屏,普遍都是2,不过还有更高的,比如2.5, 3 等,我魅族note的手机的devicePixelRatio就是3。淘宝触屏版布局的前提就是viewport的scale根据devicePixelRatio动态设置:

知名網站的行動前端自適應解決方案與比較在devicePixelRatio为2的时候,scale为0.5

知名網站的行動前端自適應解決方案與比較在devicePixelRatio为3的时候,scale为0.3333

这么做目的当然是为了保证页面的大小与设计稿保持一致了,比如设计稿如果是750的横向分辨率,那么实际页面的device-width,以iphone6来说,也等于750,这样的话设计稿上标注的尺寸只要除以某一个值就能够转换为rem了。通过js设置viewport的方法如下:


var scale = 1 / devicePixelRatio;
document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
登入後複製
登入後複製

淘宝布局的第二个要点,就是html元素的font-size的计算公式,font-size = deviceWidth / 10:

知名網站的行動前端自適應解決方案與比較

接下来要解决的问题是,元素的尺寸该如何计算,比如说设计稿上某一个元素的宽为150px,换算成rem应该怎么算呢?这个值等于设计稿标注尺寸/该设计稿对应的html的font-size。拿淘宝来说的,他们用的设计稿是750的,所以html的font-size就是75,如果某个元素时150px的宽,换算成rem就是150 / 75 = 2rem。总结下淘宝的这些做法:

  • (1)动态设置viewport的scale


    var scale = 1 / devicePixelRatio;
    document.querySelector('meta[name="viewport"]').setAttribute('content','initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
    登入後複製
    登入後複製
  • (2)动态计算html的font-size


    document.documentElement.style.fontSize = document.documentElement.clientWidth / 10 + 'px';
    登入後複製
  • (3)布局的时候,各元素的css尺寸=设计稿标注尺寸/设计稿横向分辨率/10

  • (4)font-size可能需要额外的媒介查询,并且font-size不使用rem,这一点跟网易是一样的。

最后还有一个情况要说明,跟网易一样,淘宝也设置了一个临界点,当设备竖着时横向物理分辨率大于1080时,html的font-size就不会变化了,原因也是一样的,分辨率已经可以去访问电脑版页面了。

知名網站的行動前端自適應解決方案與比較

知名網站的行動前端自適應解決方案與比較

关于这种做法的具体实现,淘宝已经给我们提供了一个开源的解决方案,具体请查看:

https://github.com/amfe/lib-flexible

之前没有找到这相关的资料,实在不好意思:(

4. 比较网易与淘宝的做法

共同点:

  • 都能适配所有的手机设备,对于pad,网易与淘宝都会跳转到pc页面,不再使用触屏版的页面

  • 都需要动态设置html的font-size

  • 布局时各元素的尺寸值都是根据设计稿标注的尺寸计算出来,由于html的font-size是动态调整的,所以能够做到不同分辨率下页面布局呈现等比变化

  • 容器元素的font-size都不用rem,需要额外地对font-size做媒介查询

  • 都能应用于尺寸不同的设计稿,只要按以上总结的方法去用就可以了

不同点

    • 淘宝的设计稿是基于750的横向分辨率,网易的设计稿是基于640的横向分辨率,还要强调的是,虽然设计稿不同,但是最终的结果是一致的,设计稿的尺寸一个公司设计人员的工作标准,每个公司不一样而已

    • 淘宝还需要动态设置viewport的scale,网易不用

    • 最重要的区别就是:网易的做法,rem值很好计算,淘宝的做法肯定得用计算器才能用好了 。不过要是你使用了less和sass这样的css处理器,就好办多了,以淘宝跟less举例,我们可以这样编写less:


//定义一个变量和一个mixin
登入後複製
@baseFontSize: 75;//基于视觉稿横屏尺寸/100得出的基准font-size
.px2rem(@name, @px){
    @{name}: @px / @baseFontSize * 1rem;
}
登入後複製
//使用示例:
登入後複製
.container {
    .px2rem(height, 240);
}
登入後複製
//less翻译结果:
.container {
    height: 3.2rem;
}
登入後複製

5. 如何与设计协作

前端与设计师的协作应该是比较简单的,最重要的是要规范设计提供给你的产物,通常对于前端来说,我们需要设计师提供标注尺寸后的设计稿以及各种元素的切图文件,有了这些就可以开始布局了。考虑到Retina显示屏以及这么多移动设备分辨率却不一样的问题,那么设计师应该提供多套设计稿吗?从网易和淘宝的做法来看,应该是不用了,我们可以按照设计稿,先做出一套布局,按照以上方法做适配,由于是等比适配,所以各个设备的视觉效果差异应该会很小,当然也排除不了一些需要媒介查询特殊处理的情况,这肯定避免不了的。下面这张图是淘宝设计师分享的他们的工作流程:

知名網站的行動前端自適應解決方案與比較

解释一下就是:

第一步,视觉设计阶段,设计师按宽度750px(iphone 6)做设计稿,除图片外所有设计元素用矢量路径来做。设计定稿后在750px的设计稿上做标注,输出标注图。同时等比放大1.5倍生成宽度1125px的设计稿,在1125px的稿子里切图。

第二步,输出两个交付物给开发工程师:一个是程序用到的@3x切图资源,另一个是宽度750px的设计标注图。

第三步,开发工程师拿到750px标注图和@3x切图资源,完成iPhone 6(375pt)的界面开发。此阶段不能用固定宽度的方式开发界面,得用自动布局(auto layout),方便后续适配到其它尺寸。

第四步,适配调试阶段,基于iPhone 6的界面效果,分别向上向下调试iPhone 6 plus(414pt)和iPhone 5S及以下(320pt)的界面效果。由此完成大中小三屏适配。

注意第三步,就要使用我们以上介绍的网易跟淘宝的适配方法了。假如公司设计稿不是基于750的怎么办,其实很简单,按上图做一些相应替换即可,但是流程和方法还是一样的。解释一下为什么要在@3x的图里切,这是因为现在市面上也有不少像魅蓝note这种超高清屏幕,devicePixelRatio已经达到3了,这个切图保证在所有设备都清晰显示。

以上是知名網站的行動前端自適應解決方案與比較的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板