細說移動端 經典的REM佈局 與 新秀VW佈局

和以往同樣,本次項目也放到了 Github 中,歡迎圍觀 star ~css

 

1. 前言html

2. 基本概念前端

3. REM佈局android

4. VW佈局css3

 實現單邊邊框1pxgit

 實現多邊邊框1pxgithub

    實現邊框圓角web

 實現容器固定縱橫比瀏覽器

5. REM + VW佈局app

6. 對比選擇

    方案選擇

    食用方式

 

1、前言

說到前端頁面的佈局方案,能夠從遠古時代的Table佈局提及,而後來到 DIV+CSS佈局,以後有了Float佈局,Flex佈局,Column佈局,Grid佈局等等。

而另外一方面,還有一些 佈局概念

1. 靜態佈局

直接使用px做爲單位

2. 流式佈局

寬度使用%百分比,高度使用px做爲單位

3. 自適應佈局

建立多個靜態佈局,每一個靜態佈局對應一個屏幕分辨率範圍。使用 @media媒體查詢來切換多個佈局

4. 響應式佈局

一般是糅合了流式佈局+彈性佈局,再搭配媒體查詢技術使用

5. 彈性佈局

一般指的是rem或em佈局。rem是相對於html元素的font-size大小而言的,而em是相對於其父元素(非font-size的是相對於自身的font-size)

 

本文不對這些概念作太多的解釋說明,主要記錄一下整理過程當中比較重要的點

現在移動端佈局中免不了要支持高清設備,機型也比較複雜,須要一套比較完善的佈局方案來支持(在總體結構上解決多設備寬的適配問題)。

淘寶的 Flexible 讓REM佈局得以流行開來,而此Flexible實現也有一些不足,此外,也涌現出了多種實現REM佈局的方案

好比直接使用  html{ font-size:625%; } 基準值,配合JS來設置根元素字體大小

或者使用媒體查詢來設置根元素字體大小

  @media screen and (min-width: 320px) { html,body,button,input,select,textarea { font-size:12px!important;
        } } @media screen and (min-width: 374px) { html,body,button,input,select,textarea { font-size:14px!important;
        } }

 

但使用rem來佈局的方案並不太正統,它有一些hack的特色

比較規範的方式是使用vw單位,隨之而來的就是後起之秀 VW佈局

 

花了一些時間整理了REM佈局和VW佈局在實際頁面中是如何運用的,若是你有興趣,就往下看吧~

項目地址,歡迎圍觀~

 

2、基本概念

物理像素(physical pixel)

物理像素又被稱爲設備像素,它是顯示設備中一個最微小的物理部件。每一個像素能夠根據操做系統設置本身的顏色和亮度。正是這些設備像素的微小距離欺騙了咱們肉眼看到的圖像效果。

設備獨立像素(density-independent pixel)

設備獨立像素也稱爲密度無關像素,能夠認爲是計算機座標系統中的一個點,這個點表明一個能夠由程序使用的虛擬像素(好比說CSS像素),而後由相關係統轉換爲物理像素。

CSS像素

CSS像素是一個抽像的單位,主要使用在瀏覽器上,用來精確度量Web頁面上的內容。通常狀況之下,CSS像素稱爲與設備無關的像素(device-independent pixel),簡稱DIPs。

屏幕密度

屏幕密度是指一個設備表面上存在的像素數量,它一般以每英寸有多少像素來計算(PPI)。

設備像素比(device pixel ratio)

設備像素比簡稱爲dpr,其定義了物理像素和設備獨立像素的對應關係。它的值能夠按下面的公式計算獲得:

設備像素比 = 物理像素 / 設備獨立像素

在Javascript中,能夠經過 window.devicePixelRatio 獲取到當前設備的dpr。

在css中,能夠經過 -webkit-device-pixel-ratio-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio進行媒體查詢,對不一樣dpr的設備,作一些樣式適配。

或者使用 resolution | min-resolution | max-resolution 這些比較新的標準方式

 

 

上圖中, Retina爲高清設備屏幕,它的一個css像素對應 了4個物理像素

 

位圖像素

一個位圖像素是柵格圖像(如:png, jpg, gif等)最小的數據單元。每個位圖像素都包含着一些自身的顯示信息(如:顯示位置,顏色值,透明度等)。

理論上,1個位圖像素對應於1個物理像素,圖片才能獲得完美清晰的展現

如上圖:對於dpr=2的retina屏幕而言,1個位圖像素對應於4個物理像素,因爲單個位圖像素不能夠再進一步分割,因此只能就近取色,從而致使圖片模糊(注意上述的幾個顏色值)。

因此,對於圖片高清問題,比較好的方案就是兩倍圖片(@2x)。

如:200×300(css pixel)img標籤,就須要提供400×600的圖片。

縮放比 scale

縮放比:scale = 1/dpr

視窗 viewport

簡單的理解,viewport是嚴格等於瀏覽器的窗口。在桌面瀏覽器中,viewport就是瀏覽器窗口的寬度高度。但在移動端設備上就有點複雜。

移動端的viewport太窄,爲了能更好爲CSS佈局服務,因此提供了兩個viewport:虛擬的visualviewport和佈局的layoutviewport。

viewport的內容比較深,推薦閱讀PPK寫的文章,以及中文翻譯

視窗縮放 viewport scale

在開發移動端頁面,咱們能夠設置meta標籤的viewport scale來對視窗的大小進行縮放定義

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

rem單位

font size of the root element.

rem就是相對於根元素<html>font-size來作計算

視窗單位

  • vw : 1vw 等於視窗寬度的1%
  • vh : 1vh 等於視窗高度的1%
  • vmin : 選取 vw 和 vh 中最小的那個
  • vmax : 選取 vw 和 vh 中最大的那個

 

兼容性:在移動端 iOS 8 以上以及 Android 4.4 以上得到支持

能夠去 Can I usecss3test 查看兼容狀況

 

3、REM佈局

講的太亂了?本身去看代碼

rem佈局的核心是設置好根html元素的font-size

通常來講,爲了防止在高清屏幕下像素不夠用致使模糊,咱們拿到的設計稿是640px(iphone5 設備寬爲320px)或750px的兩倍稿(iphone6 設備寬爲375px),按照設備寬度作了兩倍的大小。

那開發的時候在CSS中要設置什麼尺寸呢,如何作到一份設計稿適配到不一樣機型中

最佳方案是:在photoshop或其餘工具中量出某個元素或圖片或文字的尺寸,而後直接寫到代碼中。額外的適配不須要理會。

width: px2rem(200);

基於此,可使用SCSS來提供一系列的基礎支持

/* 移動端頁面設計稿寬度 */ $design-width: 750; /* 移動端頁面設計稿dpr基準值 */ $design-dpr: 2; /* 將移動端頁面分爲10塊 */ $blocks: 10; /* 縮放所支持的設備最小寬度 */ $min-device-width: 320px; /* 縮放所支持的設備最大寬度 */ $max-device-width: 540px; /* rem與px對應關係,1rem表明在JS中設置的html font-size值(爲一塊的寬度),$rem即爲$px對應占多少塊 $px $rem ------------- === ------------ $design-width $blocks */

/* 單位px轉化爲rem */ @function px2rem($px) { @return #{$px / $design-width * $blocks}rem; } /* 單位rem轉化爲px,可用於根據rem單位快速計算原px */ @function rem2px($rem) { @return #{$rem / $blocks * $design-width}px; }

爲了便於計算,咱們將頁面分爲10個塊,根據映射關係,咱們只須要計算某個元素在頁面中佔了多少塊($rem),結合html中font-size的大小,就能在頁面上設置好正確的元素大小

在對應的JS文件中

var docElem = document.documentElement, metaElem = document.querySelector('meta[name="viewport"]'), dpr = window.devicePixelRatio || 1, // 將頁面分爲10塊
        blocks = 10, // 須要限制的最小寬度
        defaultMinWidth = 320, // 須要限制的最大寬度
        defaultMaxWidth = 540, // 計算的基準值
        calcMaxWidth = 9999999;

將頁面按照clientWidth進行分割成塊,和CSS對應起來

// 設置docElem字體大小
    function setFontSize() { var clientWidth = docElem.clientWidth; clientWidth = Math.max(clientWidth, defaultMinWidth * dpr) // 調整計算基準值
        if (calcMaxWidth === defaultMaxWidth) { clientWidth = Math.min(clientWidth, defaultMaxWidth * dpr); } docElem.style.fontSize = clientWidth / blocks + 'px'; } setFontSize(); window.addEventListener(window.orientationchange ? 'orientationchange' : 'resize', setFontSize, false);

 

1px在高清屏幕中的顯示問題

上圖左邊設置了css爲1px的效果,實際上咱們須要的是右邊的效果

明顯左邊的粗了一些,由於此時1個css像素包含了4個(dpr爲2)物理像素,實際須要的是1px的物理像素,而非css像素

爲了解決這個問題,有不少方法

在REM佈局中廣泛採用的是viewport scale 視窗縮放的方式

視窗縮放很簡單,其實就是直接將meta標籤中的scale進行更改。好比dpr爲3,則scale爲

但縮放在某些安卓設備中支持度不太好,咱們還須要作其餘檢測(檢測了現用的一些機型,應該還不完整哈)

// 大部分dpr爲2如下的安卓機型不識別scale,需設置不縮放
    if (navigator.appVersion.match(/android/gi) && dpr <= 2) { dpr = 1; } setScale(dpr); // 企業QQ設置了scale後,不能徹底識別scale(此時clientWidth未收到縮放的影響而翻倍),需設置不縮放
    if (navigator.appVersion.match(/qq\//gi) && docElem.clientWidth <= 360) { dpr = 1; setScale(dpr); } docElem.setAttribute('data-dpr', dpr); // 設置縮放
    function setScale(dpr) { metaElem.setAttribute('content', 'initial-scale=' + 1 / dpr + ',maximum-scale=' + 1 / dpr + ',minimum-scale=' + 1 / dpr + ',user-scalable=no'); }

同時將最終計算的dpr放到html中,供css作一些特殊適配。看看頁面效果

 

設置容器的最大最小寬度

上圖中,隨着拉伸,內容區愈來愈大,各元素尺寸也愈來愈大。已經進行了最小寬度的處理。

要控制縮放的程度,關鍵有兩個點:尺寸計算基準、容器寬度

<!DOCTYPE html>
<html>
    <head>
        <title>REM佈局</title>
        <meta charset="utf-8">
        <meta lang="zh-CN">
        <meta name="viewport" data-content-max content="width=device-width,initial-scale=1,user-scalable=no">
        <link rel="stylesheet" href="./rem.css">
        <script src="./rem.js"></script>
    </head>

    <body data-content-max>
        <section class="container">

尺寸計算基準位於 meta標籤中的 data-content-max,容器寬度位於 body標籤中

在JS中進行匹配控制,須要注意的是,由於咱們已經進行了視窗的縮放,clientWidth將會比設備寬度大,要記得以dpr進行翻倍

// 須要限制的最小寬度
    var defaultMinWidth = 320, // 須要限制的最大寬度
        defaultMaxWidth = 540, // 計算的基準值
        calcMaxWidth = 9999999; if (metaElem.getAttribute('data-content-max') !== null) { calcMaxWidth = defaultMaxWidth; } ... // 設置docElem字體大小
    function setFontSize() { var clientWidth = docElem.clientWidth; clientWidth = Math.max(clientWidth, defaultMinWidth * dpr) // 調整計算基準值
        if (calcMaxWidth === defaultMaxWidth) { clientWidth = Math.min(clientWidth, defaultMaxWidth * dpr); } docElem.style.fontSize = clientWidth / blocks + 'px'; }

在CSS中,簡單地調用一下,核心方法已經抽離

html { @include root-width(); }
/* html根的寬度定義 */ @mixin root-width() { body { @include container-min-width(); &[data-content-max] { @include container-max-width(); } } /* 某些機型雖然設備dpr大於1,但識別不了scale縮放,這裏須要從新設置最小寬度防止出現橫向滾動條 */ &[data-dpr="1"] body { min-width: $min-device-width;
    } } /* 設置容器拉伸的最小寬度 */ @mixin container-min-width() { margin-right: auto; margin-left: auto; min-width: $min-device-width; @media (-webkit-device-pixel-ratio: 2) { min-width: $min-device-width * 2;
    } @media (-webkit-device-pixel-ratio: 3) { min-width: $min-device-width * 3;
    } } /* 設置容器拉伸的最大寬度 */ @mixin container-max-width() { margin-right: auto; margin-left: auto; max-width: $max-device-width; @media (-webkit-device-pixel-ratio: 2) { max-width: $max-device-width * 2;
    } @media (-webkit-device-pixel-ratio: 3) { max-width: $max-device-width * 3;
    } }

要注意的是,這裏的max-width也要配上dpr係數

看當作果圖

 

若是僅僅限制計算基準值,容器不限制(將body標籤中的屬性去掉),就能夠實現某種流式效果(另外一種方案)

 

 文本大小是否用rem單位

有時咱們不但願文本在Retina屏幕下變小,另外,咱們但願在大屏手機上看到更多文本,以及,如今絕大多數的字體文件都自帶一些點陣尺寸,一般是16px和24px,因此咱們不但願出現13px和15px這樣的奇葩尺寸。

咱們能夠選擇使用px直接定義

/* 設置字體大小,不使用rem單位, 根據dpr值分段調整 */ @mixin font-size($fontSize) { font-size: $fontSize / $design-dpr; [data-dpr="2"] & { font-size: $fontSize / $design-dpr * 2;
    } [data-dpr="3"] & { font-size: $fontSize / $design-dpr * 3;
    } }
@include font-size(30px);

固然了,若是要求不嚴格,也能夠直接使用rem單位

 

4、VW佈局

講的太亂了?本身去看代碼

REM佈局中用到了JS來動態設置html的font-size,可能形成頁面的抖動。

能夠考慮比較新的VW佈局,無需使用JS,雖然說在移動端 iOS 8 以上以及 Android 4.4 以上纔得到支持,不過仍是值得一用的。若是須要兼容,能夠嘗試 viewport-units-buggyfill

在REM佈局中處理1px問題是用了視窗縮放的方案,在VW佈局中就不用了,轉而使用容器縮放(transform)的方案

 

調用方式形如

height: px2vw(300);

一樣的,咱們須要寫個轉換方法

/* 移動端頁面設計稿寬度 */ $design-width: 750; /* 移動端頁面設計稿dpr基準值 */ $design-dpr: 2; /* vw與px對應關係,100vw爲視窗寬度,$vw即爲$px對應占多寬 $px $vw ------------- === ------------ $design-width 100vw */

/* 單位px轉化爲vw */ @function px2vw($px) { @return ($px / $design-width) * 100vw; }

/* 單位vw轉化爲px,可用於根據vw單位快速計算原px */ @function vw2px($vw) { @return #{($vw / 100) * $design-width}px; }

對於高清屏幕邊框1px問題,有三個方面須要考慮

1. 單邊邊框

2. 多邊邊框

3. 邊框的圓角

 

1. 單邊邊框比較簡單,本質是在目標元素上加個僞類,設置寬度(左|右邊框)或高度(上|下邊框)爲1px,而後在高清屏幕下對齊進行縮放

transform-origin: 0 0; transform: scaleY(.5);

 

2. 要讓僞類支持設置多邊邊框,已經不能僅僅使用寬度或高度,而應該在這個僞類上設置多邊邊框,而後設置dpr倍的寬高,再進行縮放(自左上方)

width: 200%; height: 200%; transform-origin: top left; transform: scale(.5, .5);

 

3. 邊框圓角通常做用於多邊邊框,使用了僞類設置邊框以後,元素自己並無邊框,因此咱們須要對僞類設置圓角,此外,也須要對元素自己設置圓角

不然就會出現這種尷尬的狀況

 

若是隻是須要設置圓角,其實也能夠不設置邊框,可使用背景顏色來營造出這種「邊框」的分界,在VW佈局中,顯示地設置邊框可能會形成代碼量太多

另外要注意的是,圓角若是設置爲像素值(好比50px),在不一樣的dpr下它產生的圓角效果仍是有區別的,因此最好也把dpr做爲係數放在圓角中

 

針對上面三種狀況,咱們須要寫好一個scss的1px邊框生成器

先來看看怎麼調用

/* 底部單個邊框 */ .f-border-bottom { @include border( $direction: bottom, $size: 1px, $color: #ddd, $style: solid );
}
/* 常規多邊邊框 */ .f-border { @include border( $direction: all, $size: 1px, $color: #ddd, $style: solid );
}
/* 多個邊框不一樣的屬性 */ &.hover { @include border( $direction: (top, right, bottom, left), $size: (3px, 2px, 1px), $color: (#0f0, #ddd), $style: dotted );
    }

 

/* 圓角邊框百分比 */ .f-border-radius { @include border( $direction: all, $radius: 50% );
}
/* 圓角邊框自定義多個角,順序 */ .f-border-radius { @include border( $radius: (10px, 20px, 30px, 40px) );
}
/* 多個邊框調用 */ &:not(.info-item__tel) { @include border( $direction: all, $size: 1px, $color: #ddd, $style: solid, $radius: 50px );
    }

看起來調用方式仍是有點複雜的,不過應該也還好吧,實在是實現不了像scale縮放那樣直接寫原生border屬性,除非使用構建工具了

這個 border生成器 是怎麼實現的呢? Show you the code ..

/** * 元素邊框 * @param {string|list} $direction: all 爲all或列表時表示多個方向的邊框,不然爲單個邊框 * @param {string|list} $size: 1px 邊框尺寸,爲列表時表將按照direction的順序取值 * @param {string|list} $style: solid 邊框樣式,高清設備下僅支持solid,同上 * @param {string|list} $color: #ddd 邊框顏色,同上 * @param {string} $position: relative 元素定位方式,通常爲relative便可 * @param {string} $radius: 0 邊框圓角 */ @mixin border( $direction: all, $size: 1px, $style: solid, $color: #ddd, $position: relative, $radius: 0 ) {
    /* 多個邊框 */ @if $direction == all or type-of($direction) == list { /* 普通設備 */ @media not screen and (-webkit-min-device-pixel-ratio: 2) { @include border-radius($radius); @if $direction == all { border: $size $style $color;
            } @else { @for $i from 1 through length($direction) { $item: nth($direction, $i); border-#{$item}: getBorderItemValue($size, $i) getBorderItemValue($style, $i) getBorderItemValue($color, $i); } } } /* 高清設備 */ @media only screen and (-webkit-min-device-pixel-ratio: 2) { @include border-multiple( $direction: $direction, $size: $size, $color: $color, $position: $position, $radius: $radius );
        } } /* 單個邊框 */ @else {
        /* 普通設備 */ @media not screen and (-webkit-min-device-pixel-ratio: 2) { border-#{$direction}: $size $style $color; } /* 高清設備 */ @media only screen and (-webkit-min-device-pixel-ratio: 2) { @include border-single( $direction: $direction, $size: $size, $color: $color, $position: $position );
        } } }

入口 mixin 判斷設備的dpr,而後選擇直接生成border代碼,或者分發到 border-single 和 border-multiple 中進行高清屏幕的處理

 

/* 實現1物理像素的單條邊框線 */ @mixin border-single( $direction: bottom, $size: 1px, $color: #ddd, $position: relative ) { position: $position; &:after { content: ""; position: absolute; #{$direction}: 0; pointer-events: none; background-color: $color; @media only screen and (-webkit-min-device-pixel-ratio: 2) { -webkit-transform-origin: 0 0; transform-origin: 0 0;
        }

        /* 上下 */ @if ($direction == top or $direction == bottom) { left: 0; width: 100%; height: $size; @media only screen and (-webkit-device-pixel-ratio: 2) { -webkit-transform: scaleY(.5); transform: scaleY(.5);
            } @media only screen and (-webkit-device-pixel-ratio: 3) { -webkit-transform: scaleY(.333333333333); transform: scaleY(.333333333333);
            } } /* 左右 */ @elseif ($direction == left or $direction == right) { top: 0; width: $size; height: 100%; @media only screen and (-webkit-device-pixel-ratio: 2) { -webkit-transform: scaleX(.5); transform: scaleX(.5);
            } @media only screen and (-webkit-device-pixel-ratio: 3) { -webkit-transform: scaleX(.333333333333); transform: scaleX(.333333333333);
            } } } }
/* 實現1物理像素的多條邊框線 */ @mixin border-multiple( $direction: all, $size: 1px, $color: #ddd, $position: relative, $radius: 0 ) { position: $position; @include border-radius($radius); &:after { content: ""; position: absolute; top: 0; left: 0; pointer-events: none; box-sizing: border-box; -webkit-transform-origin: top left; @media only screen and (-webkit-device-pixel-ratio: 2) { width: 200%; height: 200%; @include border-radius($radius, 2); -webkit-transform: scale(.5, .5); transform: scale(.5, .5);
        } @media only screen and (-webkit-device-pixel-ratio: 3) { width: 300%; height: 300%; @include border-radius($radius, 3); -webkit-transform: scale(.333333333333, .333333333333); transform: scale(.333333333333, .333333333333);
        } @if $direction == all { border: $size solid $color;
        } @else { @for $i from 1 through length($direction) { $item: nth($direction, $i); border-#{$item}: getBorderItemValue($size, $i) solid getBorderItemValue($color, $i); } } } }

在多邊邊框中,pointer-events: none 的使用屬於核心。爲了可以看到僞類的邊框,僞類將會被置於元素上方,如此便致使了元素被覆蓋不可點擊,這個css屬性就解除了這個障礙。

圓角若是使用了百分比,就不須要設置dpr係數了

能夠看到,不過這麼一來,會形成代碼比較冗餘的問題,特別是當咱們須要再次覆蓋以前的邊框屬性時。

 

實現容器固定縱橫比

縱橫比其實仍是第一次據說,作方案調研設計就一併整合過來了

它主要是用於響應式設計中的iframe、img 和video之類的元素,實現縱橫比有不少方法

 這裏使用 padding-top 百分比的方法,實現一下容器內文本區的固定縱橫比

 

/** * 實現固定寬高比 * @param {string} $position: relative 定位方式 * @param {string} $width: 100% 容器寬度 * @param {string} $sub: null 容器的目標子元素 * @param {number} $aspectX: 1 容器寬 * @param {number} $aspectY: 1 容器高 */ @mixin aspect-ratio( $position: relative, $width: 100%, $sub: null, $aspectX: 1, $aspectY: 1 ) { overflow: hidden; position: $position; padding-top: percentage($aspectY / $aspectX); width: $width; height: 0; @if $sub == null { $sub: "*";
    } & > #{$sub} { position: absolute; left: 0; top: 0; width: 100%; height: 100%;
    } }
/* 容器寬高比 */ .header { @include aspect-ratio( // $width: px2vw(600), // $sub: ".header-content", $aspectX: 375, $aspectY: 150 ) }

padding的百分比是基於元素寬度的,將容器高度設爲0,根據盒子模型,則整個元素最終的高度有padding-top來決定

子元素設置絕對定位防止被擠壓,同時撐滿父級容器,便可實現

 

從效果圖可以看出,美中不足是沒法設置容器最大最小寬度,vw是根據設備寬度進行計算的,因此沒法解決。

 

5、REM + VW佈局

講的太亂了?本身去看代碼

爲了解決純VW佈局不能設置最大最小寬度的問題,咱們引入REM。

經過配置html根元素的font-size爲vw單位,而且配置最大最小的像素px值,在其餘css代碼中能夠直接使用rem做爲單位

調用方式炒雞簡單

html { @include root-font-size(); }
line-height: px2rem(300);

而scss裏面的實現,一樣是先定義一個映射關係。將頁面寬度進行分塊(只是爲了防止值太大)

/* 移動端頁面設計稿寬度 */ $design-width: 750; /* 移動端頁面設計稿dpr基準值 */ $design-dpr: 2; /* 將移動端頁面分爲10塊 */ $blocks: 10; /* 縮放所支持的設備最小寬度 */ $min-device-width: 320px; /* 縮放所支持的設備最大寬度 */ $max-device-width: 540px; /* rem與px對應關係,1rem表明html font-size值(爲一塊的寬度),$rem即爲$px對應占多少塊 $px $rem ------------- === ------------ $design-width $blocks */

/* html根元素的font-size定義,簡單地將頁面分爲$blocks塊,方便計算 */ @mixin root-font-size() { font-size: 100vw / $blocks; body { @include container-min-width(); }

    /* 最小寬度定義 */ @media screen and (max-width: $min-device-width) { font-size: $min-device-width / $blocks;
    }

    /* 最大寬度定義 */ &[data-content-max] { body[data-content-max] { @include container-max-width(); } @media screen and (min-width: $max-device-width) { font-size: $max-device-width / $blocks;
        } } }
/* 設置容器拉伸的最小寬度 */ @mixin container-min-width() { margin-right: auto; margin-left: auto; min-width: $min-device-width;
}

/* 設置容器拉伸的最大寬度 */ @mixin container-max-width() { margin-right: auto; margin-left: auto; max-width: $max-device-width;
}

這裏的max-width直接使用寬度值,由於使用的是vw,視窗未縮放

而在頁面標籤(html和body)中,簡單地配上屬性表明是否須要限制寬度便可。

<!DOCTYPE html>
<html data-content-max>
    <head>
        <title>VW-REM佈局</title>
        <meta charset="utf-8">
        <meta lang="zh-CN">
        <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
        <link rel="stylesheet" href="./vw-rem.css">
    </head>

    <body data-content-max>

一樣是計算基準值和容器寬度兩個方面。

 

若是僅僅限制計算的基準值,也能實現「流式效果」

 

6、對比選擇

1. 方案選擇

方案是挺多的,可能也不夠完善。要選哪一種方案呢?

每一個方案都能保證在不一樣機型下作到必定的適配。

1. 通常來講,可用直接考慮使用REM佈局

2. 因REM使用了JS動態設置html的font-size,且scale對安卓機型不太友好,要求極致的能夠選用VW

3. 純VW佈局不支持設置容器最大最小寬高,若是須要此功能則選用 REM + VW佈局

 

 

2. 食用方式

怎麼使用呢?

可在Github中對應目錄的 html,js,css文件,看看是怎麼調用的

常規方式是引入公共基礎代碼,而後在業務代碼中調用

在html文件中能夠配置 data-content-max 參數來限制最大最小寬度

在scss基礎部分還能夠自定義這幾個值(若是是REM佈局的,修改這些值還須要在rem.js 文件中同步修改)

/* 移動端頁面設計稿寬度 */ $design-width: 750; /* 移動端頁面設計稿dpr基準值 */ $design-dpr: 2; /* 將移動端頁面分爲10塊 */ $blocks: 10; /* 縮放所支持的設備最小寬度 */ $min-device-width: 320px; /* 縮放所支持的設備最大寬度 */ $max-device-width: 540px;
相關文章
相關標籤/搜索