在我看來,CSS3模塊家族中,CSS3網格布局模塊是最有趣的一個。W3C官網自發布草案到今天不到一年時間。有一點必須注意,早在2007年 宣布的WD版本中,有些名稱和語法有一些變化,但是他們具有相同的本質。今天模塊正在前速向前,在IE10中已經初步實現,希望新的特性在將來能得到支持以及其他流行浏覽器也將支持這個模塊。
CSS3網格布局模塊的一個任務是幫助我們處理非常簡單和清晰的任何web-imposer(不僅),很有可能是一個內容塊在一個虛擬的網絡位置。
與舊的表格方法相比,表格是基於一個使用的表,這裡的具有清晰的文檔語義和內容與結構的分離。在一個模板中使用不同的結構標簽,使用多個浮動和手動計算實現一個布局是困難的,這裡介紹的方法變得非常簡單和清晰。與絕對定位相比,網格更具靈活性。與當今天流行的CSS/JS庫相比,這些庫使用網格都需要指定相應的類名(作為一個示例,比如bootstrap和yui CSS grids),而在網格布局模塊中是不需要額外增添這些類名。
太爽了!現在就等浏覽器廣泛的支持了。然而,如果你想去做一個Win8那樣Metro風格的應用,還在使用Html/JS,更為關鍵的是,你可使用CSS3網格布局模塊來制作布局,這樣可以兼容移動端,使用簡單,而且實用。
首先讓我們從示例中了解網格布局。想像一下,你需要制作一個經典的三列布局,這樣的布局大約需要一個以下的標記:
<section> <header>Title</header> <nav>Menu</nav> <article>Content</article> <aside>Notes</aside> <footer>Footer</footer> </section>
我們需要一個如下圖所示的三列布局:
這是一個經典的布局,因此我們將不太關注傳統的方法實現這個多列布局采用的是什麼標記。我們關注的是使用CSS3網格布局我們能做些什麼?(在個實例中,我跳過了浏覽器前綴,在實踐中應該為例子添加IE的前綴“-ms-”)。
下面是這個例子中使用的CSS代碼:
section { display: -ms-grid; grid-columns: 150px 1fr 200px; grid-rows: 50px 1fr 50px; } section header { grid-column: 2; grid-row: 1; } section nav { grid-column: 1; grid-row: 2; } section article { grid-column: 2; grid-row: 2; } section aside { grid-column: 3; grid-row: 2; } section footer { grid-column: 2; grid-row: 3; }
你要指定一個容器(section)為網格,裡面的內容都位於網格上和使用grid-columns、grid-rows屬性設置一個虛擬網格(下面會介紹這些屬性的作用)。進一步我們應該為容器內的元素指定位置。
整個包括:
現在讓我們來看看這些細節和更多的可能性。
為了能放置元素,需要創建一個虛擬網格。因此我們有必要的描述一下網格軌跡中的行和列:
#grid { display: grid; grid-columns: 150px 1fr; /* 兩列 */ grid-rows: 50px 1fr 50px; /* 三行 */ }
網格軌道介於兩網格線之間,圍著他自身轉,每個網格軌道在他自身的上面、下面、左面和右面都有一個網格線。
如何設置元素放置在網格哪個位置,需要明確指定從哪條水平線和垂直線開始。
#item { grid-column: 2; grid-row: 2; }
默認情況之下,元素占據的空間都是在指定的網格線之下。(這樣看起來像是數單元格數一樣,我們元素就類似放置在單元格中)。
擴展元素占據幾個網格單元格,我們一般都是使用grid-now-span和grid-column-span屬性來實現:
#item { grid-column: 2; grid-column-span: 3; grid-row: 2; grid-row-span:2; }
默認情況,這兩個屬性的值都是“1”。可以根據需求在這上面進行擴展。
經常根據容器結構模板需要選擇網格。
#grid { display: grid; grid-columns: 24px 120px 24px 120px 24px 120px 24px 120px 24px; grid-rows: 1fr 24px 1fr 24px 1fr 24px; }
它將更清楚的描述一個更清晰的網格,上面的例子我們可以用這樣的方法來描述:
#grid { display: grid; grid-columns: 24px (120px 24px)[4]; grid-rows: (1fr 24px)[3]; }
模板本身的參數放在括號中,後面用方括號指定重復的次數。
現在,當我們知道網格線的基本描述,接下來我們再次回到網格的軌道和嘗試理解一些具體的度量單位。
正如你所注意到的,這裡使用一個特殊的單位為指定一些列和行的大小——1fr。現在,我們將討論這個和其他可能的值用來指定長度。
在描述列寬和行高,可以使用下面的單位和值:
讓我們試著理解,分數值是如何工作的?一個網格占據了一定寬度和高度的空間。這可能取決於內容,嚴格上說是固定的或占據所外部容器所有可以訪問的空間。進一步的說,你的網格軌道的列數和行數是可以明顯設置的。如何設置他們的尺寸,對於其他的一些部分取決於內容的長度。
現在我們訪問了一個網格容器,他的橫向和縱向的寬度減去內容的寬度和高度。額外的空間按照數值的比例進行劃分。
在上面的示例中,顯示了三列按寬度的2:1:1和兩行按高度的5:2劃分列寬度和行高度。
從規范草案中復制過來的一個示例,讓我看到不同類型的關鍵詞和值:
#grid { display: grid; grid-columns: 100px 1fr max-content minmax(min-content, 1fr) }
具體描述如下:
這裡有細微的差別,用戶內部出現最大和小值,他們正在考慮一個分數值作為最大位置。分數標志著最低的位置被認為是等於0,詳細的細節請參考規范。
下一步我們將試圖找出元素代替它們位置之間的網格線(網格內的單元格)。
現在,把元素綁定到網格行中會出現一個問題:他們是如何放在網絡線之間?
綁定元素在網格的邊緣是依靠grid-column-align和grid-row-align屬性來控制的。他們的屬性值主要包括:
這些值從名稱上就告訴我們他們的展示行為是什麼。我只會注意到,在每個案例的問題是關於定位元素與其容器之間的距離。這兩個屬性的默認值是stretch,表示拉伸元素至容器一樣大小。
元素綁定在列(水平方向)對應的是文本方向(例如一些阿拉伯語,是從右邊開始到左邊結束)。元素綁定在行(垂直方向)對應是塊的方向(順便說一句,這意味著一些東亞語言,行和列可以改變他們的位置)。
下一個重點來了,元素的位置在網格內如何布置。如果兩個元素都綁定在同一行中,或者擴展排列到相同的單元格,那麼會發生些什麼?
最重要的需要理解一些細微的差別,元素放置在網格中不會直接影響彼此的位置。如果你將十個元素都綁定到網格的水平方向第二條網格線和垂直方向第三條網格線起始處。那麼默認情況他們都將取代他們的位置,層疊放在一起。每個元素都綁定到網格相對應的角落。這些元素可以影響的只有網格軌道,如果他們被綁定,那麼它將會影響內容的尺寸。
要控制這些層的顯示順序,當前規范版本使用的是z-index屬性,允許管理網格內元素的層級。
備注:在基於IE10的前一個版本規范,使用一個grid-layer屬性來指定網格內元素層級關系,而沒有使用z-index。然而,進一步的討論過程中,工作組決定重新考慮使用z-index這個屬性。
看一個例子:
#grid { display: grid; grid-columns: (1fr)[3]; grid-rows: (1fr)[4]; } #A { grid-column:1; grid-row:3; grid-column-span:2; } #B { grid-column:1; grid-row:1; grid-row-span:2; /* grid-layer: 10; */ z-index:10; margin-top:10px; } #C { grid-column:1; grid-row:1; grid-column-span:2; margin-left:50px; } #D { grid-column:2; grid-row:3; grid-row-span:2; grid-column-span:2; margin:10px 0 0 10px; } #E { grid-column:2; grid-row:2; /* grid-layer: 5; */ z-index:5; margin: -20px; }
到目前為止,僅在IE10+的浏覽器可以支持網格布局模塊,其他浏覽器還不支持。但是它可以使用JS庫eCSStender和擴展的網格對齊,他們支持下面的屬性:
可以查看這個實例。
最後,讓我們稍微了解一下,CSS3網格布局模塊在未來會有哪些的變化。
以下提到的可能性是在草稿規范中提到的,但現在還沒有浏覽器支持這些特性。將來能否支持取決於W3C組織。
可以對元素占據的網格的開始網格線,還可以指定他們的結束網格線:
#item { grid-column: 2; grid-row: 2 4; }
和“span”機制不一樣,他指定了一個元素在水平方向和垂直方向必須跨越多少單元格,可以明確的為元素指定從哪行開始到哪行結束。它也可以輕松的使用網格線名稱。
為了方便行,可能會為其命名。它是通過在適當的位置插入字符串值,用來描述網格軌道。(如果實際需要,可以定義向個名稱,比如說從語義的角度出發,定義不同的名稱):
#grid { display: grid; grid-columns: "nav" "first" 150px "content" 1fr "last"; grid-rows: "header" 50px "content" 1fr "footer" 50px; }
在元素上可以引用這些名稱:
#menu { grid-column: "nav"; grid-row: "content"; } #header { grid-column: "content"; grid-row: "header"; } #article { grid-column: "content"; grid-row: "content"; }
還有一個規范,預先命名了四個網格線名稱——垂直和水平方現的start和end,實際上他們構建了整個網格。例如,導航菜單在第一列,從第一行到最後一行,而footer元素從第二列到最後一列,不需要統計有多少行和多少列,就可以實現。
#menu { grid-column: 1; grid-row: start end; } #footer { grid-column: 2 end; grid-row: 3; }
將來還有另一個方法,可以給單元格根據模板元素名稱命名,用以創建一個虛擬結構模板:
#grid { display: grid; grid-template: "ln" "ma" "ba" "ff"; grid-columns: auto minmax(min-content, 1fr); grid-rows: auto minmax(min-content, 1fr) auto auto; }
因此,將一個元素綁定到一個或另一個虛擬的網格中也可以使用這樣的規則:
#article { grid-cell: "a"; }
如果根據不同的條件,比如說根據屏幕分辨率改變元素的位置,甚至改變網格本身。那麼這種方法是很爽的:
@media (orientation: portrait) { #grid { display: grid; grid-template: "ln" "ma" "ba" "ff"; grid-columns: auto minmax(min-content, 1fr); grid-rows: auto minmax(min-content, 1fr) auto auto; } } @media (orIEntation: landscape) { #grid { display: grid; grid-template: "ln" "ma" "mb" "sf"; grid-columns: auto minmax(min-content, 1fr); grid-rows: auto minmax(min-content, 1fr) auto auto; } } #a grid-cell: "a"; }
注意,本文用來命名單元格的名稱不會改變。(雖然現在還無法使用這些屬性,但我們會等到浏覽器支持這些特性)。
在這篇文章中,我想嘗試給大家介紹CSS3網格布局模塊關鍵部分。我希望可以激勵大家知道的比我多。
我將提醒大家,模塊在不斷的更新,W3C組織在不斷的收集評論和修改意見。在Internet Explorer 10中可以看到一些基本功能的實現。這裡提供了幾個有興的例子:IEtestdrive.com:The Grid System和Hands On: CSS3 Grid Layout。
我也會繼續觀注CSS3網格布局模塊的更新,現在支持網格布局模塊的游覽器只有IE10,也有可能將來會使用網格布局模塊和Html/JS來開發Windows8的Metro風格。
譯者手語:整個翻譯依照原文線路進行,並在翻譯過程略加了個人對技術的理解。如果翻譯有不對之處,還煩請同行朋友指點。謝謝!
如需轉載煩請注明出處:
英文原文:http://www.splashnology.com/article/introduction-into-CSS3-grid-layout-workingwith-grids/5762/