移動開發中更好的圖片自適應

一直以來,咱們在 PC 端開發中,都要求給圖片寫上一個寬高,以免圖片加載後形成的 reflow 。但在移動端開發中,爲了能適配各類各樣的屏幕尺寸,咱們都不會像在PC端中同樣給圖片設定固定的寬高,美其名曰:響應式圖片javascript

通常作法是:css

img{width: 100%;}

更好的寫法是:html

img{max-width: 100%;}

更好的寫法好處是避免當圖片尺寸小於屏幕尺寸時,拉伸形成圖片失真,影響體驗。java

按上面的方式處理,圖片就能根據屏幕大小自動等比縮放,達到響應式的效果。大多數狀況下已經知足咱們平常的開發需求,但在一些特殊需求裏,如圖片後面有內容,圖片作按需加載,或者圖片作一個進場動畫,這時,當圖片加載前和加載後,會形成 reflow,在視覺體驗上咱們就看到內容在圖片出來先後有一個跳動,必定程度上影響了咱們的體驗。做爲一名新時代的切圖仔,咱們應該解決這個問題。瀏覽器

咱們要的其實很簡單,就是在不一樣屏幕大小,圖片能等比縮放顯示,單位 px 確定是不行的了,咱們須要一個相對的單位,上面的 % 是一個,但會有 reflow 問題。目前較好的選擇是 rem, 它是相對於根元素的相對單位,也就是說,若是咱們根據屏幕等比動態地更新根節點的 font-size 值,經過 rem 就能自動更新圖片的大小。因此,以下方案:iphone

更好的自適應: js + rem

  • JS 動態給 html 設置一個跟屏幕寬度成正比的 font-size
  • 圖片寬高用 rem 作單位

** 與屏幕寬度成正比的 font-size **測試

var docEl = document.documentElement;
docEl.style.fontSize = docEl.getBoundingClientRect().width / 16;

如上 JS ,咱們用瀏覽器的默認字體大小做爲基數(這裏沒有絕對關係,能夠用任意數值)。
假設咱們的設計稿是按 640 寬來設計的,圖片爲 600x300。 那麼,獲得的 font-size 是 40,也就是說,在樣式裏,咱們須要將圖片的寬高除以 40 轉換成相應的 rem 單位,獲得的值爲 width: 15rem; height: 7.5rem,在 iphone4 下效果如圖:字體

Alt text

圖片顯示的寬高爲等比,測試連接: http://jsbin.com/qirifadiyu/1/flex

這樣子,圖片既可以自適應,又有大小,就不會有 reflow 形成的跳動現象。一切看起來很美好,但其實有必定限制。動畫

** 限制: ** 按 640 寬來設計的頁面,理論上咱們切出來的圖片不會大於 640,但若是必定要用大於 640 的圖片,這樣子換算後圖片的寬度就會大於屏幕寬度,就達不到咱們要的效果了。這時能夠以屏幕寬度爲基值,如 height = 圖片高度 * 16 / 圖片寬度。

完整的 JS 以下:

;(function(win){
    var docEl = document.documentElement,
        timer = null,
        rem;

    function setUnit(){
        rem = docEl.getBoundingClientRect().width / 16;
        docEl.style.fontSize = rem + 'px';
    }

    win.addEventListener('resize', function() {
        clearTimeout(timer);
        timer = setTimeout(setUnit, 300);
    }, false);
    win.addEventListener('pageshow', function(e) {
        if (e.persisted) {
            clearTimeout(timer);
            timer = setTimeout(setUnit, 300);
        }
    }, false);

    setUnit();
})(window);

純CSS更好的解決方案

** html **

<div class="pic-wrap">
    <img src="http://ww3.sinaimg.cn/mw690/69243898gw1emmeiydzvrj20go08cglu.jpg" alt=""/>
</div>

** css **

.pic-wrap{position: relative; padding-top: 50%;}
.pic-wrap img{position: absolute; left: 0; top: 0; width: 100%; max-width: 640px;}

此方法依賴於必定的結構,但相對於上一個方法來講,不須要依賴 JS。由於 padding 的百分比值是相對於寬度的,也就是有了跟屏幕寬度成正比的條件,因此利用 padding-top 設置與寬高等比的百分比值佔位,就實現了一樣的效果。

計算公式: padding-top: 圖片高度 * 100% / 圖片寬度。

測試連接: http://jsbin.com/cexazepuvi/1/

參考文檔

手機淘寶的flexible設計與實現

相關文章
相關標籤/搜索