優雅地進行移動端開發,端開發

來源:互聯網
上載者:User

優雅地進行移動端開發,端開發

對於移動端開發而言,為了做到頁面高清的效果,視覺稿的規範往往會遵循以下兩點:

1)選取一款手機的螢幕寬高作為基準(比如 iphone6的375×667)。

2)對於高清螢幕,為了達到高清效果,視覺稿的畫布大小會是基準的2倍(對iphone6而言:原先的375×667,就會變成750×1334)。

 

問題1:對於dpr=2的手機,為什麼畫布大小×2,就可以解決高清問題?

首先,我們要先瞭解一下 dpr 是什嗎?

  • 裝置像素比(簡稱dpr)定義了物理像素和裝置獨立像素的對應關係,它的值可以按如下的公式的得到:
裝置像素比 = 物理像素 / 裝置獨立像素    // 在某一方向上,x方向或者y方向
  • 一個物理像素是顯示器(手機螢幕)上最小的物理顯示單元,在作業系統的調度下,每一個裝置像素都有自己的顏色值和亮度值。
  • 裝置獨立像素,這個點代表一個可以由程式使用的虛擬像素(比如: css像素),然後由相關係統轉換為物理像素。  

 總而言之,就是不同的裝置(不同的系統),他們有不同的dpr,這些裝置在拿到前端寫好的頁面(即css像素布局)之後,會根據dpr佔用不同數量的物理像素。但是,它們最終顯示(肉眼識別)的大小是一樣的。

 盜用一張圖:

那這和一開始的問題:對於dpr=2的手機,為什麼畫布大小×2,就可以解決高清問題? 有什麼關係? 再盜用一張圖~

這樣子就非常清晰了,對於dpr=2的高清(retina)螢幕而言,1個位元影像像素對應於4個物理像素,由於單個位元影像像素不可以再進一步分割,所以只能就近取色,從而導致圖片模糊(注意上述的幾個顏色值)。

因為這樣,我們乾脆就使用2倍大的圖片,比如:200*300的圖片,在高清屏上,就使用400*600的圖片,但是顯示的大小仍然設定為200*300,這樣子的話,一個物理像素仍然是顯示一個位元影像像素,完美。

 

 

問題2:類似於下面的布局,在使用最少標籤的情況下,如何適配所有移動端螢幕?並且儲存一定的寬高比,不失真。

1. 使用百分比 % 進行布局

假如你使用%對該塊進行布局,很快,你就會覺得非常的‘苦逼’,由於每一塊有margin值,而margin的百分比你很難去計算得到,並且,你可能需要用到各種不同的媒體查詢 

@media(max-width:320px){    div{margin-right: 1%;}}

每一個螢幕你都可能需要微調,並且,當以後需要修改樣式的時候,你又需要每個@media都重新走一遍,想想就後怕

 

2.使用 rem 布局

正所謂,原理大家都懂,rem是根據根項目html的font-size的大小,直接看例子吧~

1 html{font-size: 16px;}2 body{3      font-size: 0.5rem;  /*16px * 0.5 = 8px;*/4 }

基於rem的原理,我們要做的就是:  針對不同手機螢幕尺寸和dpr動態改變根節點html的font-size大小(基準值)。

回到題目上,那怎麼使用rem去實現該布局?並且,在設定rem的過程都非常愉快,不需要經過各種惱人的計算?

根據當前viewport的尺寸來改變html的字型大小,一般分為媒體查詢和js動態計算兩種。

前者必須針對市面上較為主流的解析度作媒體查詢的區間分界點,缺點是只有設定為分界點的尺寸完美縮放,分界點之間的尺寸會出現斷層。

js根據螢幕尺寸去動態計算則能令所有尺寸完美縮放,缺點則是要在頁面頭部插入一小段js代碼。

根據這2個的優缺點,在日常開發中,h5運營頁面經常使用js動態計算的方法,而平常的頁面(購物,網頁)則使用媒體查詢的方法。

 

一般在開發中,我們會選擇一個螢幕作為基準(比如 iphone6 的 375) ,在該螢幕下,font-size基準設定為20px

先上一個非常巧妙,極大地提高了開發效率但是原理卻很簡單的方法。

$rem_grid: 20 !default;  //使用 rem(10)即在375螢幕中代表10px@function rem($val){    $rem : $val / $rem_grid;   //由於rem是先乘以font-size得出px,所以這裡先把rem()傳進來的數除以20,最後乘以html的20,其實就是參數的本來值    @if $rem == 0 {        @return #{$rem} ;    }@else{        @return $rem / ($rem * 0 + 1) * 1rem; // 帶不帶px單位都支援    }}

好了,方便計算的做了,接下來是媒體查詢,覆蓋常見機型?

原理:根據裝置的寬度(與基準裝置寬度375的比值)進行縮放。廢話不多說,直接上代碼

@mixin query( $limit ) {    @media screen and ( min-width: $limit) {  //媒體查詢        & {            @content;        }    }}@mixin _mod_cross( $width, 375 ) {    @include query( $width * 1px ) {        font-size:  $width / 375 * 20 * 1px;  //這裡是關鍵    }}@include _mod_cross(320, 375);   //iPhone5

按照上面實現之後,當然,你要@include _mod_cross 常見的機型,這樣之後,你就終於終於可以,只在iphone6下,愉快地用rem()進行布局了,無須每一個螢幕都去做適配,也無須每一次都多一步計算,大大提高開發效率。

 

寫完媒體查詢的方法,再上一份用js動態計算的代碼:

原理是一樣的,只是使用 document.documentElement.clientWidth 擷取更加精確的裝置寬度,再對html的font-size進行設定。

<script type="text/javascript">    !function(){      var maxWidth=750;      document.write('<style id="o2HtmlFontSize"></style>');      var o2_resize=function(){          var cw,ch;          if(document&&document.documentElement){              cw=document.documentElement.clientWidth,ch=document.documentElement.clientHeight;          }          if(!cw||!ch){              if(window.localStorage["o2-cw"]&&window.localStorage["o2-ch"]){                  cw=parseInt(window.localStorage["o2-cw"]),ch=parseInt(window.localStorage["o2-ch"]);              }else{                  chk_cw();//定時檢查                  return ;//出錯了              }          }          var zoom=maxWidth&&maxWidth<cw?maxWidth/375:cw/375,zoomY=ch/603;//由ip6 weChat          window.localStorage["o2-cw"]=cw,window.localStorage["o2-ch"]=ch;          //zoom=Math.min(zoom,zoomY);//保證ip6 wechat的顯示比率          window.zoom=window.o2Zoom=zoom;          document.getElementById("o2HtmlFontSize").innerHTML='html{font-size:'+(zoom*20)+'px;}.o2-zoom,.zoom{zoom:'+(zoom/2)+';}.o2-scale{-webkit-transform: scale('+zoom/2+'); transform: scale('+zoom/2+');} .sq_sns_pic_item,.sq_sns_picmod_erea_img{-webkit-transform-origin: 0 0;transform-origin: 0 0;-webkit-transform: scale('+zoom/2+');transform: scale('+zoom/2+');}';      },      siv,      chk_cw=function(){          if(siv)return ;//已經存在          siv=setInterval(function(){              //定時檢查              document&&document.documentElement&&document.documentElement.clientWidth&&document.documentElement.clientHeight&&(o2_resize(),clearInterval(siv),siv=undefined);          },100);      };      o2_resize();//立即初始化      window.addEventListener("resize",o2_resize);  }();  </script>

 

rem的應用情境:

由於 rem 布局是相對於視口寬度,因此任何需要根據螢幕大小進行變化的元素(width、height、position 等)都可以用 rem 單位。

但 rem 也有它的缺點——不精細,其實這涉及到了瀏覽器渲染引擎的處理。因此,對於需要精細處理的地方(如通過 CSS 實現的 icon),可以用 px 等絕對單位,然後再通過 transform: scale() 方法等比縮放。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.