CSS響應式設計之柵格系統

說到柵格系統(grid system),你也許見過這樣的概念:
2015728163915616.png (300×336)css

像這樣,經過固定的格子結構,來進行佈局設計。這是一種設計風格,並且一直以來很普遍地應用於網頁設計領域。這樣的風格清晰、工整,可讓網頁具備更友好的瀏覽體驗。前端

而隨着響應式設計(responsive design)的流行,柵格系統開始被賦予新的意義,那就是,一種響應式設計的實現方式。sass


柵格與響應式前端框架

響應式的要點是爲同一個頁面設計多種佈局形態,分別適配不一樣屏幕尺寸的設備。通常來講,是這樣的感受:
2015728163939460.png (400×173)框架

能夠看到,一個頁面能夠拆分紅多個區塊來理解,而正是這些區塊共同構成了這個頁面的佈局。根據不一樣的屏幕尺寸狀況,調整這些區塊的排版,就能夠實現響應式設計。另外,屏幕寬度較大的時候,區塊傾向於水平分佈,而屏幕寬度較小的時候,區塊傾向於豎直堆疊。工具

這些方方正正的區塊是否是和柵格系統的格子挺類似?對的,爲了讓響應式設計更簡單易用,因而有了不少稱爲「柵格」(grid)的樣式庫。佈局

柵格樣式庫通常是這樣作的:將頁面劃分爲若干等寬的列(column),而後推薦你經過等寬列來建立響應式的頁面區塊。測試

雖然看起來都是這樣的思路,但不一樣的柵格樣式庫,在作法上倒是各有各的點子。下面,本文將介紹幾個比較有表明性的柵格樣式庫,講述它們的簡要原理和用法(正確的打開方式)。字體


Bootstrap中的柵格

Bootstrap把它的柵格放在CSS這個分類下,並稱它爲Gird system。默認分爲12列。ui


容器、行與列

要理解Bootstrap中的柵格,最好從掌握正確的使用方法開始。這其中有2個要點。

第1個要點是容器(container),行(row)和列(column)之間的層級關係。一個正確的寫法示例以下:

<div class="container">  
    <div class="row">  
        <div class="col-md-6"></div>  
        <div class="col-md-6"></div>  
    </div>  
</div>  

Bootstrap柵格的容器有兩種,.container(固定像素值的寬度)和.container-fluid(100%的寬度),在這裏,把它們都稱爲container。須要注意的是,row(.row)必須位於container的內部,column(如.col-md-6)必須位於row的內部。也就是說,container、row、column必須保持特定的層級關係,柵格系統才能夠正常工做。

爲何須要這樣?查看這些元素的樣式,會發現container有15px的水平內邊距,row有-15px的水平負外邊距,column則有15px的水平內邊距。這些邊距是故意的、相互關聯的,也所以就像齒輪齧合那樣,限定了層級結構。這些邊距其實也是Bootstrap柵格的精巧之處,若是你想進一步瞭解,推薦閱讀The Subtle Magic Behind Why the Bootstrap 3 Grid Works。

若是要嵌套使用柵格,正確的作法是在column內直接續接row,而後再繼續接column,而再也不須要container:

<div class="container">   
    <div class="row">   
        <div class="col-md-8">   
            <div class="row">   
                <div class="col-md-6"></div>   
                <div class="col-md-6"></div>   
            </div>   
        </div>   
        <div class="col-md-4"></div>   
    </div>   
</div>  

 

斷點類型

第2個要點,是不一樣的斷點類型的意義及其搭配。

Bootstrap柵格的column對應的類名形如.col-xx-y。y是數字,表示該元素的寬度佔據12列中的多少列。而xx只有特定的幾個值可供選擇,分別是xs、sm、md、lg,它們就是斷點類型。

在Bootstrap柵格的設計中,斷點的意義是,當視口(viewport)寬度小於斷點時,column將豎直堆疊(display: block的默認表現),而當視口寬度大於或等於斷點時,column將水平排列(float的效果)。按照xs、sm、md、lg的順序,斷點像素值依次增大,其中xs表示極小,即認爲視口寬度永遠不小於xs斷點,column將始終水平浮動。

有時候,會須要將多種斷點類型組合使用,以實現更細緻的響應式設計。此時不一樣的斷點類型之間會有怎樣的相互做用呢?

先看看Bootstrap的sass源碼是如何定義柵格的:

@include make-grid-columns;   
@include make-grid(xs);   
@media (min-width: $screen-sm-min) {   
  @include make-grid(sm);   
}   
@media (min-width: $screen-md-min) {   
  @include make-grid(md);   
}   
@media (min-width: $screen-lg-min) {   
  @include make-grid(lg);   
}  

能夠看到,用了min-width的寫法,並且斷點像素值越大的,對應代碼越靠後。因此,若是有這樣的一些元素:

<div class="container">   
    <div class="row">   
        <div class="col-sm-6 col-lg-3">1</div>   
        <div class="col-sm-6 col-lg-3">2</div>   
        <div class="col-sm-6 col-lg-3">3</div>   
        <div class="col-sm-6 col-lg-3">4</div>   
    </div>   
</div>  

 

那麼它們應該是這樣的效果:
2015728164305988.png (450×172)

結合前面的源碼,能夠想到,在上面這樣視口寬度由小變大的過程當中,首先是保持默認的豎直堆疊,而後超過了sm的斷點,sm的樣式生效,變爲一行兩列的排版,再繼續超過lg的斷點後,lg的樣式也生效,因爲lg的樣式代碼定義在sm以後,因此會覆蓋掉sm的樣式,從而獲得一行四列的排版。

因此,結合使用多個斷點類型,就能夠引入多個斷點變化,把響應式作得更加細緻。
適度使用

Bootstrap柵格雖然很強大,但也不該過分使用。例如,當你須要一個佔據一整行寬度的元素時,請不要也想着讓Bootstrap柵格參和進來,加入相似.col-xs-12這樣的元素。實際上,你不須要任何柵格類,你須要的只是一個塊元素。


Foundation中的柵格

Foundation柵格叫作Grid,它和Bootstrap柵格的設計十分近似,只是在類名和結構上有所差別。Foundation柵格一樣默認12列。


行與列

類比以前Bootstrap柵格的例子,Foundation柵格的一個正確的寫法示例以下:

<div class="row">   
    <div class="medium-6 columns"></div>   
    <div class="medium-6 columns"></div>   
</div>  

Foundation柵格的行用.row表示,而列由至少兩個類名組成,一是.columns或.column(2種寫法徹底相同,單純爲了支持語法偏好)代表這是列元素,二是.medium-6這種用於表示斷點類型和對應寬度。在默認狀況下,Foundation柵格的斷點類型從小到大依次是small、medium、large,其中small相似Bootstrap柵格的xs,也是指任意屏幕尺寸下都水平排列。

Foundation柵格沒有container,只須要row和column,所以顯得比Bootstrap柵格更簡單一些。其中row定義了最大寬度(能夠認爲承擔了container的部分功能),column定義了0.9375rem的水平內邊距。若是要嵌套,仍然是column內續接row,再繼續接column。

組合使用多個斷點類型,其方法也和Bootstrap柵格相同。須要注意的是,Foundation柵格的斷點值是用的em而不是px,對應的,它們轉換後的像素值也有別於Bootstrap柵格。


Block Grid

做爲柵格系統的補充,Foundation還提供了另一個叫作Block Grid的柵格。不過,它並非一個超出傳統柵格的新東西,而只是一個針對特定柵格應用場景的方法糖。

下面是一個Block Grid的示例:

<ul class="small-block-grid-2 medium-block-grid-3 large-block-grid-4">   
  <li></li>   
  <li></li>   
  <li></li>   
  <li></li>   
  <li></li>   
  <li></li>   
</ul>  

其中,ul和li這樣的特定標籤組合是必須的。在這個示例中,屏幕寬度從小到大的變化過程當中,列元素將依次是一行兩列、一行三列、一行四列的排版方式。

能夠看到,Block Grid的結構也是行和列,但只須要在行上有一個類名。和Foundation的Grid相比,它的確有一些不一樣。一方面,Block Grid的行並無定義最大寬度。另外一方面,Block Grid的列必定是等寬的(畢竟li不須要任何類名)。


Toast柵格

前面介紹的兩個柵格樣式庫都來源於流行前端框架,並非獨立的。本文接下來要介紹的Toast,則是一個獨立的、頗有想法的柵格樣式庫。
特別的實現方式

爲何說頗有想法呢?請看它的一個正確的寫法示例:

<div class="grid">   
    <div class="grid__col grid__col--1-of-2"></div>   
    <div class="grid__col grid__col--1-of-2"></div>   
</div>  

相似的,這也是一行均分兩列的排版。能夠看到,Toast柵格的結構一樣是行(.grid)與列(.grid__col)。可是,不一樣於始終以12列爲參考的模式,它能夠用1-of-2這樣更爲直觀的類名。事實上,這裏用3-of-六、6-of-12等也能夠,它們是相同的。

固然,這並非Toast最特別的地方。如今,請想一下,Bootstrap及Foundation的柵格系統的column本來都是塊元素,它們是如何實現水平排列的?

對的,用的是float。但Toast是如何作的呢?它想法獨特,選用了display: inline-block;。若是你有了解過這個屬性,你應該知道inline-block的元素會彼此之間存在縫隙。Toast在選擇這個屬性的基礎之上,巧妙使用了負外邊距(例如margin-right: -.25em;),消除了縫隙對柵格column水平排列的影響。在我作了一些測試和應用後,我只能說,這個強行完成的策略要給個贊。


非Mobile First

在前面Toast柵格的示例中,並無相似md、medium這樣體現斷點類型的詞。這是由於,Toast採用了「存在默認」的風格。絕大部分狀況下,只須要使用形如.grid__col--x-of-y的類名。Toast已經爲這個類設置了斷點(默認700px),低於這個斷點爲display: block;,高於這個斷點爲display: inline-block;。

意外的是,不一樣於Bootstrap和Foundation默認取block的mobile first原則(豎直堆疊更符合小尺寸屏幕的排版要求),Toast則是把display: inline-block;放在了@media範圍以外,當作默認屬性。這應該只是風格偏好差別,就我我的而言,我仍是更贊同mobile first的設計風格的。

有關mobile first的響應式設計的實現,推薦閱讀Grid。

若是要加入多個斷點變化,Toast是這樣作:

<div class="grid">   
    <div class="grid__col grid__col--1-of-4 grid__col--m-1-of-2">   
    </div>   
</div>  

上面這段代碼的效果是,該柵格列在480px如下爲block,佔據滿寬,481px~700px之間爲inline-block,佔據1/2寬度,701px以上爲inline-block,佔據1/4寬度。


對柵格系統的補充

前面介紹的這些柵格樣式庫,源碼都使用Less、Sass這些css預編譯工具,所以其中的12列、斷點值、列間距等都是可配置的,只不過大部分狀況下默認的就足夠使用。

雖然柵格樣式庫很棒,但它們並非響應式設計的所有。要使同一個應用在不一樣屏幕尺寸的設備上都具備較好的瀏覽體驗,還有不少其餘手段可用(好比在尺寸更大的屏幕上使用更大的字體),柵格系統只是方式之一。


結語

藉助css柵格系統,咱們能夠很容易地建立響應式的頁面佈局。但在這個過程當中,理解各種柵格樣式庫的工做原理,正確使用它們,才能作出穩定、可靠的頁面結構。

相關文章
相關標籤/搜索