談一談響應(yīng)式布局的技巧

寫(xiě)在前面的話


響應(yīng)式(responsive),顧名思義,就是物體自身具備能夠適應(yīng)各種不一樣環(huán)境的能力,而網(wǎng)頁(yè)的響應(yīng)式布局就好比把一杯液態(tài)的網(wǎng)頁(yè)倒進(jìn)各種大小不一樣的玻璃瓶里,不管是從哪個(gè)角角度上看去,頁(yè)面的形態(tài)都是那么的自然,那么的合理。響應(yīng)式的網(wǎng)頁(yè)看上去會(huì)比傳統(tǒng)的pc頁(yè)面“聰明”一點(diǎn),它們知道如何把自己體面的塞進(jìn)各種尺寸不一樣的移動(dòng)端設(shè)備里面,用更親民的呈現(xiàn)方式,讓拇指一族們愛(ài)不釋手。它們可以“偽裝”得像原生手機(jī)App那樣展現(xiàn)出同樣流暢,華麗的交互體驗(yàn),甚至還能披上App的外衣,為了hybrid app的榮譽(yù)與native app一戰(zhàn)!響應(yīng)式的潮流還在不斷的前進(jìn),趁著這個(gè)熱度,就來(lái)談一談響應(yīng)式布局的技巧。

打開(kāi)響應(yīng)式門(mén)的鑰匙


The key, 一般都是在講某個(gè)概念的關(guān)鍵核心部分,那么the key of responsive一定離不開(kāi)CSS3里面的Media Query,也就是常說(shuō)的“媒體查詢”。所有接下來(lái)要提到的布局技巧都是在media query的基礎(chǔ)上建立的,當(dāng)然你完全也可以通過(guò)代碼的方式來(lái)做到和媒體查詢同樣的效果{if(你不嫌麻煩)}。媒體查詢的工作原理很簡(jiǎn)單:設(shè)置斷點(diǎn),分不同區(qū)間,以像素為單位,設(shè)備的寬度屬于哪個(gè)區(qū)間就套用哪個(gè)區(qū)間的樣式。舉個(gè)栗子:

@media screen and (min-width: 320px) and (max-width: 768px) {
  .submit {
    ......
  }   
}

上面設(shè)了兩個(gè)斷點(diǎn),理論上是可以有三個(gè)區(qū)間,即[0,320]、[320,768]、[768,沒(méi)上限],而上面的樣式則會(huì)套用在寬度在[320,768]范圍里的設(shè)備中,這些設(shè)備一般包括iphone,ipod以及ipad豎屏。通過(guò)media query我們完全可以針對(duì)不同尺寸的屏幕大小,來(lái)定制我們想要的布局。

響應(yīng)式布局的幾種方法


頁(yè)面元素寬度基于百分比的響應(yīng)式

這是最常見(jiàn)也是最基礎(chǔ)的做法。在非響應(yīng)式的pc端網(wǎng)頁(yè)中,從設(shè)計(jì)圖開(kāi)始,頁(yè)面中的每個(gè)元素都被設(shè)置好了固定的寬度,無(wú)論怎樣改變窗口的大小,頁(yè)面中各元素的布局與大小始終保持與設(shè)計(jì)稿設(shè)一致。而到了移動(dòng)端的尺寸,我們需要通過(guò)設(shè)置斷點(diǎn),基于移動(dòng)端的設(shè)計(jì)稿,重新改變pc端原有的布局。但問(wèn)題是,移動(dòng)端的設(shè)計(jì)稿往往只出一份(基于一個(gè)通用的尺寸),然而市面上移動(dòng)端設(shè)備的尺寸、分辨率參差不齊,設(shè)計(jì)師也不可能細(xì)微到為每個(gè)不同的設(shè)備出一份精確的設(shè)計(jì)圖。因此,為了能夠讓頁(yè)面得體的顯示,頁(yè)面元素的寬度會(huì)被設(shè)置成百分之多少,以確保各個(gè)元素的大小可以基于一個(gè)比例輸出。

1.png

上圖看做是一個(gè)在768px寬度(ipad豎屏)下的一個(gè)頁(yè)面,其中包含了 頂部導(dǎo)航(灰色)、頁(yè)面頭圖(藍(lán)色)、頁(yè)面主體(紅色)以及頁(yè)腳(棕色)。每個(gè)色塊的寬度都設(shè)置成百分比的寬度,這使得元素在其他的尺寸下同樣可以以這個(gè)比例顯示:

iphone5:
iphone5.png
iphone6:
iphone6.png

而每個(gè)色塊的高度則以其包含的內(nèi)容的主體來(lái)做對(duì)應(yīng)的調(diào)整:

  • 如果色塊里面包含的是圖片,例如圖中的藍(lán)色部分,其高度可以是基于原圖寬高比保持比例輸出的。
  • 如果色塊里面包含的只有文字,例如藍(lán)色部分里面都是文字,在這種情況下,高度不需要保持比例,讓里面的文字自適應(yīng)填充就好。
  • 如果色塊的主要作用是用于布局,里面還包含例如圖片、文字等其他元素,其寬高比,最好保持與設(shè)計(jì)稿的比例一致,這里就需要用到媒體查詢,來(lái)維護(hù)一致的寬高比。例如,假設(shè)ipad下顯示紅色塊的寬高比就是設(shè)計(jì)圖上的比例,那么iphone下為了保持一致,紅色塊就不應(yīng)該那么‘扁高’了。

元素寬度基于百分比的布局保證了頁(yè)面的響應(yīng)式,然而在設(shè)置這些百分比的數(shù)值時(shí),我們需要根據(jù)色塊所占據(jù)每行的列數(shù),來(lái)計(jì)算他們各自所占的百分?jǐn)?shù),這其中可能還會(huì)考慮到彼此之間的間距。例如圖中紅色部分的色塊,在設(shè)置寬度百分比的時(shí)候,我們甚至還要把其中的間距也要用百分比來(lái)表示,這其中的計(jì)算難免會(huì)出現(xiàn)錯(cuò)誤。倘若我們不把這些常用到的比例歸納成常用的class使用,而是直接寫(xiě)上數(shù)值(代碼中會(huì)出現(xiàn)大量%單位的數(shù)值),這不僅會(huì)顯得繁瑣,且大大降低代碼的維護(hù)性。此外,我們可能希望這種百分比的布局更加靈活,譬如上圖紅色塊里,在如此狹小的手機(jī)屏幕上顯示2列甚至是3列已經(jīng)是相當(dāng)擁擠了,這時(shí)候我想制定一套規(guī)則,讓這些元素的布局可以在狹小的空間里顯示一列,而在更寬的空間里才顯示2列、甚至3列。有沒(méi)有什么方法,可以讓隨心所欲的去定制這么一套規(guī)則,而不需要去計(jì)算這些百分比寬度與間距,能不能只需把關(guān)注點(diǎn)放在每行顯示多少列,而這一列該占多少比例就可以了?答案是有的,bootstrap的柵格系統(tǒng)正是為了解決這些問(wèn)題而應(yīng)運(yùn)而生。

柵格系統(tǒng)

bootstrap的柵格系統(tǒng)天生就是為響應(yīng)式布局而生的。這個(gè)系統(tǒng)會(huì)隨著屏幕尺寸的變化,自動(dòng)為占據(jù)屏幕的每一行分為最多12列。

柵格系統(tǒng)用于通過(guò)一系列的行(row)與列(column)的組合來(lái)創(chuàng)建頁(yè)面布局,你的內(nèi)容就可以放入這些創(chuàng)建好的布局中。柵格系統(tǒng)非常貼切網(wǎng)頁(yè)的內(nèi)容以一種從上到下一行一行排布的形式,以格子為單位拼湊成你需要的布局。換句話說(shuō),任何網(wǎng)頁(yè)里的布局,都可以將其柵格化,除此之外,我們甚至可以利用柵格系統(tǒng)來(lái)制定其在不同尺寸下的不一樣的布局。

關(guān)于柵格系統(tǒng)的具體用法,可以參考下bootstrap里的官方介紹,在這里我舉個(gè)簡(jiǎn)單的例子用來(lái)展示其強(qiáng)大之處:
首先看一段代碼:

<div class="row"> 
  <div class="col-xs-12 col-sm-6 col-md-8">.col-xs-12 .col-sm-6 .col-md-8</div> 
  <div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
</div>
<div class="row"> 
  <div class="col-xs-6 col-sm-4">.col-xs-6 .col-sm-4</div> 
  <div class="col-xs-6 col-sm-4">.col-xs-6 .col-sm-4</div> 
  <div class="col-xs-6 col-sm-4">.col-xs-6 .col-sm-4</div>
</div>

首先說(shuō)明的一點(diǎn),上面代碼里出現(xiàn)的類(lèi)名如果需要其生效,必須要引用到bootstrap的css代碼。接下來(lái)有人一定會(huì)吐槽,尼瑪這些帶類(lèi)名都是些神馬,放那么類(lèi)名用來(lái)布局,你在逗我玩?不急不急,待我慢慢道來(lái):

  • 首先,柵格系統(tǒng)的基本框架是這個(gè)樣子的:
    <div class="container">
      <div class="row">
        <div class="col-..."></div>
        ...
      </div>
    </div>
    
    也就是說(shuō),柵格里的每一行必須要被包裹在一個(gè)container的類(lèi)里,和列相關(guān)的類(lèi)只能被包含在row的類(lèi)里。
  • 接著,讓我們徹底剖析下這個(gè)類(lèi)名col-xs-12,從左到右來(lái)吧:
    col:表示該項(xiàng)是一個(gè)列
    xs:是bootstrap柵格系統(tǒng)里用于表示適用于小屏幕尺寸的一個(gè)斷點(diǎn)(<768px)標(biāo)識(shí)符,也就是說(shuō),類(lèi)前綴為.col-xs的樣式會(huì)在小于768px的屏幕寬度下生效。除了xs,柵格系統(tǒng)里還有sm、md、lg,它們對(duì)應(yīng)的斷點(diǎn)分別是:>=768px,>=992px,>=1200px。因此,只有在滿足這些斷點(diǎn)條件的情況下,其對(duì)應(yīng)的類(lèi)前綴的樣式才能夠生效。
    12:后面的數(shù)字就是表示其樣式生效的呈現(xiàn)效果。之前提到,柵格系統(tǒng)會(huì)隨著屏幕尺寸的變化,自動(dòng)為占據(jù)屏幕的每一行分為最多12列,col-xs-12直譯過(guò)來(lái)就是表示:在小于768px的設(shè)備尺寸下,套用這個(gè)類(lèi)的div(也就是這一列)占據(jù)了這一行的12個(gè)格子,也就是它以100%的寬度占滿了一整行。

基于以上的粗略解釋,再來(lái)看看一開(kāi)始列出來(lái)的代碼在不同尺寸寬度下的表現(xiàn),我想其強(qiáng)大之處應(yīng)該是一目了然:

<768px(xs生效):
400.png
>=768px(sm生效):
780.png
>=992px(md生效)
1030.png

我覺(jué)得有必要引用下官方對(duì)柵格參數(shù)的介紹,以便對(duì)其工作效果會(huì)有一個(gè)更詳盡的描述:
通過(guò)下表可以詳細(xì)查看 Bootstrap 的柵格系統(tǒng)是如何在多種屏幕設(shè)備上工作的:

args.png

Flex-box 軟盒子模式布局

比起前面兩種介紹的方法,軟盒(又稱作伸縮盒)模式的布局則是一種完全不一樣方法,前者的響應(yīng)式方式是基于寬度百分比,而后者則是通過(guò)控制設(shè)置其彈性屬性flex來(lái)達(dá)到響應(yīng)式的效果,而我認(rèn)為軟盒模式在布局上除了支持響應(yīng)式的布局之外,其自身布局的方式,以及它對(duì)包裹在其內(nèi)部元素之間的間距、顯示順序的控制大大顛覆了原來(lái)的頁(yè)面流布局方式,軟盒布局一定會(huì)是日后網(wǎng)頁(yè)布局的一大潮流。有關(guān)flex-box的詳細(xì)用法可以參照大漠兄翻譯的一篇譯文,而我日后也會(huì)貼出自己在使用軟盒布局方面的一些心得,畢竟最近項(xiàng)目都是在用flex-box來(lái)做響應(yīng)式,我想以后只要待ie完全退出江湖,flex-box將定會(huì)成為網(wǎng)頁(yè)布局的首選項(xiàng)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容