對移動端兼容適配的分析

1、思考
在移動端愈來愈重要的背景下,每位web開發者對移動適配都有本身的想法。是移動優先,仍是PC優先,仍是二者兼得?在實際開發中這個問題是和項目產品定位有關的,也涉及到UI的設計,不是開發者能決定。但無論產品如何定位,做爲開發者老是要提供最優的解決方案,是用一套樣式仍是多套樣式?網上一搜,有靜態佈局、流式佈局,響應式佈局,自適應佈局,彈性佈局等一堆,雲裏霧裏,到底要怎麼選呢?看完這篇文章相信心中就有數了。css

2、viewport的使用
一、最多見的設置,大多數的框架(如bootstrap)和知名的站點基本是這個配置html

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />

二、這個配置重點在width=device-width,就是讓視窗口等於設配寬度,也就是咱們開發中能用document的寬度,其它幾個「初始縮放大小」「最大縮放大小」「最小縮放大小」和「是否容許用戶縮放」能夠理解爲用來「固定」這個設置不被破壞的。
三、這個設置很簡單,但同時也會帶來一些須要解決的問題。
a、如今的手機都是兩倍三倍的Retina高清屏,1px實際的效果是不止一個像素的,對不一樣的設備設置不一樣
的initial-scale能夠有比較好的效果,好比在2倍Retina的iphone6(6s,7,8)中設置爲0.5。一旦
動態設置這個,也就意味這視窗口不一樣了,須要不一樣樣式適配。這也是分配樣式的一套基準,如何分配樣式
後面會有更詳細的講解。
b、在PC端若是有最小寬度的限制,一樣須要配置不一樣的width值。android

3、單位的使用
一、css中單位不少,這裏只介紹最經常使用的幾種:
(1) px:這個能夠理解爲「基準」單位,就是無論在什麼設備中其值是不會變的,就像cm,kg這些同樣
(2) em:這個是相對父容器的單位,通常用在字體font-size中比較好。如父容器font-size爲16px,則
1em=16px
(3) rem:相對於根元素html的單位,如html的font-size爲16px,則1rem=16px
(4) vw/vh: 視口寬高爲100vw/100vh,這個和百分比相似,只是百分比是相對於父容器,其相對於視口
二、移動適配最經常使用的應該是rem,不少框架和淘寶的flexible適配都是基於這個單位,而本身作的話,通常
在首頁加載時全局js設置html的font-size便可,代碼以下:ios

(function (doc, win) {
  var docEl = doc.documentElement,
    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
    recalc = function () {
      var clientWidth = docEl.clientWidth;
      if (!clientWidth) return;
      //這裏根據設計稿爲750,設置1rem=100px,
      docEl.style.fontSize = 100 * (clientWidth / 375) + 'px';
    };

  // Abort if browser does not support addEventListener
  if (!doc.addEventListener) return;
  win.addEventListener(resizeEvt, recalc, false);
  doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

3.若是用了sass/less等預編譯語言能夠更靈活的配置的,在上面方法內配置(設計稿爲750的狀況下):
docEl.style.fontSize = 40 * (clientWidth / 750) + 'px';
在編譯函數中配置:
@function px2rem($px, $base-font-size: 20px) {
@return ($px / $base-font-size) * 1rem;
}
這樣咱們就能夠直接使用設計稿的尺寸,如:px2rem(100px),省去了本身計算,若是沒用預編譯語言(推
薦使用),編輯器也有插件支持單位轉化。
4.上面是基於屏幕寬度來設置根元素font-size,若是設置不一樣的initial-scale,咱們須要基於設備像素比設置,經過window.devicePixelRatio獲取。css3

4、頁面佈局方式
1.理解html的文檔流方式,其實就是流式佈局,即橫向須要咱們設置,縱向自動疊加。這個和移動端的設計體驗方式是比較像的。在寬度中就要用自適應的方式,如百分比,有設置相對單位的,可用相對單位,靈活使用,css3的display:flex也是很好的選擇,現代瀏覽器和移動設備基本都支持了。
2.剛纔說到體驗,很明顯移動端和pc端的體驗真的很不一樣,因此光有上面的自適應是遠遠不夠,是否是須要對這兩個徹底不一樣的體驗方式響應不一樣的佈局和樣式。web

5、媒體查詢
1.咱們除了能夠用js來判斷不一樣的設備,設置相對單位所用的根元素。另外一個強大的方式是能夠經過css3強大的媒體查詢來指定不一樣的樣式。
2.媒體查詢的規則bootstrap

@media all and ([min-width|max-width|orientation|min-device-width|...]) { ... }

中括號[]中表示須要添加的條件,可匹配寬高/橫豎屏/設備類型等,好比min-width:750px,表示最小寬度爲750px,{}是在匹配模式下的樣式。也有邏輯判斷and/or/not鏈接不一樣的規則瀏覽器

3.要是引入整個文件,能夠在link標籤中使用sass

<link rel="stylesheet" media="screen and (min-width:900px)" href="big.css" type="text/css" />

表示:當屏幕大於或等於900px時,將採用big.css樣式來渲染Web頁面。app

4.Bootstrap響應式設計這類柵格佈局採用的就是這套方式。

6、1px像素邊框問題
1.除了上面說到在viewport中設置縮放外,直接設置一個空元素縮放也是能夠的

p{
    width: 100px;
    height: 1px;
    background: red;
    display: block;
    transform: scaleY(.5);
}

不足:圓角沒法實現,實現4條邊框比較麻煩,而且只能單獨實現,若是嵌套,會對包含的效果產生不想要的效果,因此此方案配合:after和before獨立使用較多

2.利用CSS對陰影處理的方式實現0.5px的效果

box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5);

不足:顏色很差處理, 黑色 rgba(0,0,0,1) 最深的狀況了。有陰影出現,很差用大量使用box-shadow可能會致使性能瓶頸。四條邊框實現效果不理想。
3.圖片實現,使用 background-image 實現1px有兩種方式: 漸變 linear-gradient 或直接使用圖片(base64)。漸變 linear-gradient (50%有顏色,50%透明)

div{
    height: 1px;
    background-image:-webkit-linear-gradient(top,transparent 50%,#000 50%);
    background-position: top left;
    background-repeat: no-repeat;
    background-size: 100% 1px;
}

不足:大量使用漸變可能致使性能瓶頸,代碼量大,多背景圖片有兼容性問題

7、圖片高清化
1.可使用srcset屬性設置,使用看https://www.zhangxinxu.com/wordpress/2014/10/responsive-images-srcset-size-w-descriptor/
2.背景圖高清
a.使用上面介紹的媒體查詢,如:

/* 普通顯示屏(設備像素比例小於等於1)使用1倍的圖 */
  .css{
      background-image: url(img_1x.png);
  }

  /* 高清顯示屏(設備像素比例大於等於2)使用2倍圖  */
  @media only screen and (-webkit-min-device-pixel-ratio:2){
      .css{
    background-image: url(img_2x.png);
      }
  }

  /* 高清顯示屏(設備像素比例大於等於3)使用3倍圖  */
  @media only screen and (-webkit-min-device-pixel-ratio:3){
      .css{
    background-image: url(img_3x.png);
      }
  }

b.image-set 實現高清化

.css {
      background-image: url(1x.png);    /*不支持image-set的狀況下顯示*/
      background: -webkit-image-set(
        url(1x.png) 1x,/* 支持image-set的瀏覽器的[普通屏幕]下 */
        url(2x.png) 2x,/* 支持image-set的瀏覽器的[2倍Retina屏幕] */
        url(3x.png) 3x/* 支持image-set的瀏覽器的[3倍Retina屏幕] */
      );
  }

c.不少網頁端對圖片的要求仍是沒那麼高的,不像app那樣,圖片通常用一張2倍高清圖就行,最新的設備對以上屬性的支持仍是能夠的,對於要求高的應用使用

8、移動端click屏幕產生300ms的延時響應
1.緣由:在瀏覽器須要如何判斷快速點擊上,當用戶在屏幕上單擊某一個元素時候,例如跳轉連接<a href="#"></a>,此處瀏覽器會先捕獲該次單擊,但瀏覽器不能決定用戶是單純要點擊連接仍是要雙擊該部分區域進行縮放操做,因此,捕獲第一次單擊後,瀏覽器會先Hold一段時間t,若是在t時間區間裏用戶未進行下一次點擊,則瀏覽器會作單擊跳轉連接的處理,若是t時間裏用戶進行了第二次單擊操做,則瀏覽器會禁止跳轉,轉而進行對該部分區域頁面的縮放操做。那麼這個時間區間t有多少呢?在IOS safari下,大概爲300毫秒。這就是延遲的由來。形成的後果用戶純粹單擊頁面,頁面須要過一段時間才響應,給用戶慢體驗感受,對於web開發者來講是,頁面js捕獲click事件的回調函數處理,須要300ms後才生效,也就間接致使影響其餘業務邏輯的處理。
2.解決方案:
(1)使用fastclick.js,只要全局加入該文件並設置以下:

FastClick.attach(document.body);

(2) zepto的touch模塊,tap事件也是爲了解決在click的延遲問題

9、更改默認樣式

//使用appearance改變webkit瀏覽器的默認外觀
input,select { -webkit-appearance:none; appearance: none; }

//winphone下,使用僞元素改變表單元素默認外觀
//1.禁用select默認箭頭,::-ms-expand修改表單控件下拉箭頭,設置隱藏並使用背景圖片來修飾
select::-ms-expand { display:none; }

//2.禁用radio和checkbox默認樣式,::-ms-check修改表單複選框或單選框默認圖標,設置隱藏並使用背景圖片來修飾
input[type=radio]::-ms-check,
input[type=checkbox]::-ms-check { display:none; }

//3.禁用pc端表單輸入框默認清除按鈕,::-ms-clear修改清除按鈕,設置隱藏並使用背景圖片來修飾
input[type=text]::-ms-clear,
input[type=tel]::-ms-clear,
input[type=number]::-ms-clear { display:none; }
// 禁止長按連接與圖片彈出菜單
a,img { -webkit-touch-callout: none }    

// 禁止ios和android用戶選中文字
html,body {-webkit-user-select:none; user-select: none; }

// 改變輸入框placeholder的顏色值
::-webkit-input-placeholder { /* WebKit browsers */
color: #999; }
:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
color: #999; }
::-moz-placeholder { /* Mozilla Firefox 19+ */
color: #999; }
:-ms-input-placeholder { /* Internet Explorer 10+ */
color: #999; }
input:focus::-webkit-input-placeholder{ color:#999; }

// android上去掉語音輸入按鈕
input::-webkit-input-speech-button {display: none}

10、總結1.網站適配的終端能夠用js或媒體查詢的方式獲取,分配對應的樣式。2.佈局上採用相對單位,百分比和flex的彈性方式。3.對移動端的特殊性進行適配,如1px問題,默認樣式等。

相關文章
相關標籤/搜索