DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> CSS入門知識 >> CSS特效代碼 >> 淺談css的柵格布局
淺談css的柵格布局
編輯:CSS特效代碼     

柵格布局想必大家都很了解,我們做頁面開發的時候,往往對頁面板式的要求很高,如何對各個區域的內容排版,並使之對齊是我們的一大難題。而柵格系統就是我們排版的利器,他支持自動對齊、自動計算邊距、流式布局等優點,簡單好用的特性使得柵格布局成為所有主流框架的必備的功能。

我們簡單分析一下柵格布局的原理:

容器/行/列/柵間距

一個柵格布局需要3部分組成——容器(container)行(row)列(column,也可稱為柵)。容器是用於確定寬度的,行需要放到容器中;行是將列分組,並把一組列合並為一個行;列是正真的顯示內容的元素,我們的內容就寫在列裡面。具體可參考下圖

如果僅是行與列來布局,自適應布局也能滿足需求,柵格布局的高明之處在於它還提供了列與列之間存的間距,我們稱之為柵間距(gutter),柵間距僅存在列與列之間,列和容器之間是不應該存在柵間距的。柵間距的存在使得我們不用自己去計算padding,設置布局更加簡單,對齊也更加容易。

列寬

完善的柵格布局框架,都會提供一個類似自適應布局一樣的聲明列寬的class類。首先系統把容器分為若干份,這個總份數一般都是3、4的倍數,這樣利於排版。然後再提供若干代表份數的類,讓列去繼承,這樣列就會占據容器總寬度的指定份數(span)了。如上面我們的例圖,容器的總份數是9,各個列繼承不同的份值,並保證了一行裡面的所有列的份值相加也是9。

柵格嵌套

同時柵格系統是可以嵌套的,即列裡面也可以作為容器,裡面可以再聲明一行,然後繼續聲明子列,這種行為我們稱之為柵格嵌套,如下圖:

 

列的換行行為

早期的柵格系統框架,列與列之間是不能換行的,即一行中的所有列都必須確保在同一行中。但是隨著響應式布局的興起,一行中的列也需要出現換行行為,而且換行後也沒不能出現顯示錯誤,這種行為我們稱為列的換行行為,如下圖。因為涉及柵間距的計算,所以不是每一個柵格系統都可以支持“列的換行行為”的。列的換行行為對於完成響應式布局非常重要的,最為明顯的例子就是bootstrap3的響應式功能要遠遠比bootstrap2強大,原因就是因為bootstrap3的柵格支持“列的換行行為”。

列寬的計算

根據上面我們對原理的分析,可以看出,如何計算柵間距是柵格系統的核心。沒有了柵間距,柵格布局也就成了普通的自適應布局,那麼如何去計算柵間距、列寬、行寬的關系呢?從柵格系統的表現形式可以看出,一行中柵間距的個數等於總份數減一。如果容器的寬度是width,總份數是n,列間距的寬度是gutter,列的份數是span,列寬是colwidth。那麼有:

colwidth = (width + gutter) / n * span - gutter

這個計算並不復雜,但是想要通過css2去自動計算幾乎是不可能的。

同時柵格系統還有一個難點,就是如何控制哪個列有柵間距,哪個列沒有。css中控制元素與元素之間的間隔用的是margin,而且柵格與容器之間是沒有柵間距的,因此每個列的margin計算就是另一個難題。

這兩個問題很難直接用css2解決,但是使用一些黑科技還是可以解決這兩個問題。如果是面向的浏覽器支持css3,利用css3的語法解決這兩個計算問題也是可行的。根據市面上的幾個流行框架,筆者大致總結出了確定列寬、柵間距的幾種方法:

1.固定container寬度法

這個方法比較簡單,首先框架要確定容器的寬度,這樣因為容器的寬度是固定的,就可以計算出列寬了。

至於柵間距的確定也十分簡單,就是讓開發人員自己去設置。框架在每一列都設置一個向左或者向右的margin,然後再定義一個最後一列或者第一列的樣式類(如“.first”或者“.last”),通過開發人員手動設置這個樣式類,將最後一列(或者第一列)多出來的margin去除掉。

如果浏覽器支持css3,可以用css3的偽類“:last”和“:first”代替人工設置法的“.last”和“.first”,這樣更加自動化一些。

這種方法是不支持“列的換行行為”,因為一旦出現了一行被擠到了第二行,他的柵間距的計算就會出現問題。即便是用偽類去輔助計算行間距,仍然無法去除換行後元素的多出來的柵間距。

總結:這種方法好處是簡單,兼容性好。缺點是僅支持固定的container,適用性很差,同時還不支持列的換行行為。

代表框架:藍圖(blueprint)

2.行單向偏移法

這個方法非常巧妙,使用很簡單的方法將列寬度和柵間距的確定問題解決列,思路上是這樣的,因為一行中柵間距的個數等於總份數減一,如果把讓行寬等於容器的寬度加上一個柵間距,那麼一行能容納的行間距的個數剛好等於總份數,這樣計算列寬也簡單了。具體可參考下圖

這個方法巧妙在通過擴充行的寬,並使-margin的方法使之再偏移之一個柵間距的距離,這樣多出一個不影響列顯示的柵間距,使整個柵格系統的計算變得非常簡單。

使用這個方法的另一個好處就是,他支持“列的換行行為”。我們之前說過“列的換行行為”是完成柵格的響應式布局的重要特性,使用行偏移法,我們不需要去控制個別列的padding或者margin的行為,這樣使得列在換行後仍能正常顯示成為可能。

當然這種方法也存在缺點,就是如何確定擴偏移後的行的寬度。因為偏移後的行的寬度要正好等於柵間距加上容器寬度,如果不使用css3的calc是很難的,也只能在用在固定容器寬度的情況下才能算出。

另外一個問題就是列寬的計算要使用padding和box-sizing屬性,這使得我們需要多聲明一個元素用於布局,這樣一個柵格布局中就會多聲明兩層元素去用於布局,文檔的語義化會減弱,而且一旦柵格嵌套,就會產生更多的無用的dom。

代表類庫:bootstrap2的柵格就是使用這個方式,因為bootstrap2的柵格系統容器是定寬的,所以列寬就可以通過less事先計算好,這樣就可以省去列通過padding計算列寬的步驟,使得柵格系統更加簡潔。

3.行雙向偏移法

這個方法是目前最流行方法,相當於利用了一個黑科技來完成這個艱巨的任務。這個方法和上一個“行單向偏移法”非常相似,只是因為行單向偏移法存在難以計算實際行寬的問題,而雙向偏移法就是為了解決這個問題而誕生的。

方法是向左右各偏移半個柵間距,利用偏移後的效果由浏覽器自動去計算行實際的行寬,而不是指定行寬。我們知道塊級元素的寬度表現特性為:塊級元素的寬度默認會占滿整個容器,如果元素定義了margin,那麼寬度將是父容器寬度去除margin後的寬度。即使margin是負值,這個計算方法同樣適用,這其實是個hack,但是這樣就可以利用來解決行寬的計算問題。具體方法如下圖:

目前很多流行框架都使用這個方法,不過這個方法筆者很不喜歡,因為這樣列也成為了一個布局元素,想要完成一個布局,要多生成三層元素,感覺這樣做很不值得。不妨我們看看bootstrap3中文官網的dom結構,看看他那復雜的令人發狂的dom樹你就會對這個方法的感到失望。不過不管怎麼說他都很棒的解決列柵格系統的兩大難題

代表類庫:妹子ui、bootstrap3、Foundation

4.使用calc計算法

calc屬性是css3中最令人著迷的屬性之一,以往ie浏覽器也提供過類似calc這種可計算的屬性的方法,但是因為效率低下並且是非標准語法,一直被大家拒之門外。而calc的到來,終於讓css中運用數值運算來計算尺寸成為可能。

我們之前分析出的公式直接使用calc上運算就行,因為calc是支持百分比與有單位的數值進行運算的。

當然,這僅是解決列列寬的問題,例如如何實現“列的換行行為”的問題還是沒有解決,因此這個方法可以和“行單向偏移法”一起使用。

當然calc方法的最大缺點就是兼容性問題,ie低版本和諸多移動端浏覽器都不支持這個屬性,因此目前還沒見過哪個主流框架是使用calc來實現柵格系統的。不過未來在各大主流浏覽器均支持calc後,使用calc開發柵格系統必將成為主流,因為這個方法比起上面的hack方法更加簡單。

5.使用flex布局

一些移動框架開始使用flex來提供柵格布局,不過flex布局並沒有和上述幾種方法有什麼不同,原理上也是上述的4種形式,僅是用flex代替列float而已。不過在垂直方向上,flex利用自身特性,提供了一套垂直對齊的模式,算是對柵格系統進一步的補充。

代表類庫:ionic

總結

柵格布局的實現方法主要就是上述的幾種,了解列這些方法,我們就可以自己開發屬於簡單的柵格系統,從而不再依賴那些又大又笨的樣式框架,使我們的項目更加堅定干淨。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved