一篇全面的CSS佈局學習指南 [譯]

本文來自SmashingMagazine上一篇很是不錯的CSS佈局綜述類文章,彙總了各種CSS佈局技術,並提供了這些技術深度閱讀的連接。故而翻譯過來和你們分享,原文連接在文末,感謝做者Rachel Andrew。css

引言

不管你是一個想要學習CSS佈局的新手,仍是一個比較有經驗但想要進一步鞏固與瞭解最新CSS佈局知識的前端開發者,這篇指南都能幫你全面瞭解現在CSS佈局發展的現狀。html

在過去的許多年中,正如翻天覆地的前端開發通常,CSS佈局也產生了巨大的變化。如今咱們有須要可選的CSS佈局方式來開發咱們的網站,這也就要求咱們對這些方式做出選擇。在這片文章裏,我會介紹各類CSS佈局的基本使用方式以及使用的目的。前端

若是你仍是CSS方面的新手而且想要了解什麼是最好的佈局方法,這篇文章正式你所須要的;固然,若是你是一位比較有經驗的開發者,想要了解一些關於CSS佈局的最新知識,這篇文章也不容錯過。固然,我不會將各種技術的細枝末節都放到這篇文章裏(不然能夠寫一本書了),而是對各種技術作一個基本的概述,同時會給你們提供相關連接來進一步學習。git


1. 正常文檔流(Normal Flow)

若是你打開一個沒有用任何CSS來改變頁面佈局的網頁,那麼網頁元素就會排列在一個正常流(normal flow)之中。在正常流中,元素盒子(boxes)會基於文檔的寫做模式(writing mode)一個接一個地排列。這就意味着,若是你的寫做模式是水平方向的(句子是從左到右或從右到左書寫),正常流會垂直地一個接一個排列頁面的塊級元素。github

固然,若是你是在一個垂直方向的寫做模式下,句子是垂直方向書寫的,因此塊級元素會水平方法排列。web

Block and Inline Directions change with Writing Mode

正常流是一種最基礎的佈局:當你爲文檔應用了CSS、建立了某些CSS佈局,你實際上是讓這些塊作了一個正常文檔流以外的「事」。spring

1.1. 經過頁面結構來發揮正常文檔流的優點

經過確保你書寫的頁面具備良好的頁面結構(well-structured manner),你能夠最大程度利用正常流所帶來的優點。試想一下,若是瀏覽器中沒有正常流,那麼你建立的元素都會堆積在瀏覽器的右上角。這就意味着你必須指定全部的元素的佈局方式。瀏覽器

有了正常流,即便CSS加載失敗了,用戶仍然能閱讀你的頁面內容;同時,一些不使用CSS的工具(例如一些閱讀器)會按照元素在文檔中的位置來讀取頁面內容。從 可用性(accessibility) 角度來看,這無疑是很是有幫助的,同時也讓開發者輕鬆了一些。若是你的內容順序和用戶預期的閱讀順序一致,你就不須要爲了將元素調整到正確的位置而進行大量的佈局調整。當你繼續讀下去會發現,使用新的佈局方式是如何讓頁面佈局事半功倍的。ide

所以,在思考如何佈局以前,你須要認真思考你的文檔結構,以及你但願用戶以何種順序來閱讀文檔中的內容。工具

1.2. 脫離正常文檔流

一旦你有了一個結構良好的頁面,你就須要去決定如何利用它並將它變爲咱們須要的佈局結構。這會涉及到 脫離正常文檔流(moving away from normal flow),即本文後續的部份內容。咱們有許多佈局「利器」可使用,其中第一個就是float,它是一個描述什麼是脫離正常文檔流的很是好的例子。


2. 浮動(Float)

浮動被用來將盒子(box)置於左側或右側,同時讓內容環繞其展現。

要讓一個元素進行浮動,須要爲該元素設置一個值爲leftrightfloat屬性。默認值爲none

.item {
    float: left
}
複製代碼

值得強調的是,當你使某個元素浮動並讓文字環繞它時,內容的line box被截斷了。若是你讓一個元素浮動,同時爲緊跟着的包含文本的元素設置一個背景色,你會發現背景色會出如今浮動元素下方。

The background color on the content runs under the float

若是你想要在浮動元素和環繞的文本之間建立邊距,你須要給浮動元素設置外邊距。在文本元素上設置外邊距只會讓其相對於容器縮進。例如在下面這個例子中,你就須要爲左側浮動的圖片設置右邊距和下邊距。

<div class="container">
  <div class="item"></div>
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
}

.item {
  width: 100px;
  height: 100px;
  float: left;
  margin: 0 20px 20px 0;
  background-color: rgba(111,41,97,.3);
}
複製代碼

2.1. 清除浮動

一旦你對一個元素應用了浮動,全部接下來的元素都會環繞它直到內容處於它下方且開始應用正常文檔流。若是你想要避免這種狀況,能夠手動去清除浮動。

當你不想要某個元素受到其以前的浮動元素影響時,爲其添加clear屬性便可。使用left值能夠清除左浮動效果,right值爲右浮動,both則會清除左右浮動。

.clear {
    clear: both;
}
複製代碼

可是,當你發如今容器內有了一個浮動元素,同時容器文本內容太短時就會出現問題。文本盒子會被繪製在浮動元素下,而後接下來的部分會以正常流繪製在其後。

The box around the text does not clear the float

爲了不這種狀況,咱們須要爲容器中某個元素應用clear屬性。咱們能夠在容器最後添加一個空元素並設置clear屬性。可是在某些狀況下可能沒法使用這種方式(例如一些CMS系統生成的頁面)。所以,最多見的清除浮動的hack方案是:在容器內添加一個CSS僞元素,並將其clear屬性設置爲both。

<div class="container">
  <div class="item"></div>
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra.</p>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
}

.item {
  width: 100px;
  height: 100px;
  float: left;
  margin: 0 20px 20px 0;
  background-color: rgba(111,41,97,.3);
}

.container::after {
  content: "";
  display: table;
  clear: both;
}
複製代碼

example: Smashing Guide to Layout: clearfix on Codepen

2.2. 塊級格式化上下文(Block Formatting Context)

清除浮動的另外一個方法是在容器內建立BFC。一個BFC元素徹底包裹住了它內部的全部元素,包括內部的浮動元素,保證浮動元素不會超出其底部。建立BFC的方式有不少種,其中最經常使用的一種清除浮動的方式是爲元素設置除visible(默認)以外的overflow屬性值。

.container {
    overflow: auto;
}
複製代碼

像上面這樣使用overflow通常狀況下是有效的。然而,在某些狀況下,這可能會帶來一些陰影的截斷或是非預期的滾動條。同時它也使你的CSS變得不那麼直觀:設置overflow是由於你想要展現滾動條仍是僅僅爲了獲取清除浮動的能力呢?

爲了使清除浮動的意圖更加直觀,而且避免BFC的負面影響,你可使用flow-root做爲display屬性的值。display: flow-root作的惟一的一件事就是去建立一個BFC,所以能夠避免其餘建立BFC方法帶來的問題。

.container {
    display: flow-root;
}
複製代碼

2.3. 浮動的一些遺留用法

在新的佈局方式出現之前,float常常會被用來建立多欄佈局。咱們會給一系列元素設置寬度而且將它們一個接一個進行浮動。經過爲浮動元素設置一些精細的百分比大小能夠建立相似網格的效果。

我不建議在當下仍然過分地使用這種方法。可是,在現有的網站中,這種方式仍然會存在許多年。所以,當你碰到一個頁面裏面處處是float的應用,能夠肯定它就是用的這種技術。

2.4. 關於浮動與清除浮動的其餘閱讀資料


3. 定位(Positioning)

想要把一個元素從正常流中移除,或者改變其在正常文檔流中的位置,可使用CSS中的position屬性。當處於正常文檔流時,元素的position屬性爲static。在塊級維度上元素會一個接一個排列下去,當你滾動頁面時元素也會隨着滾動。

當你改變元素的position屬性時,一般狀況下你也會設置一些偏移量來使元素相對於參照點進行必定的移動。不一樣的position值會產生不一樣的參照點。

3.1. 相對定位(relative postioning)

若是一個元素具備屬性position: relative,那麼它偏移的參照位是其原先在正常文檔流中的位置。你可使用top、left、bottom和right屬性來相對其正常流位置進行移動。

.item {
    position: relative;
    bottom: 50px;
}
複製代碼

注意,頁面上的其餘元素並不會因該元素的位置變化而受到影響。該元素在正常流中的位置會被保留,所以你須要本身去處理一些元素內容覆蓋的狀況。

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
}

.item {
  width: 100px;
  height: 100px;
  background-color: rgba(111,41,97,.3);
  position: relative;
  bottom: 50px;
}
複製代碼

example: Smashing Guide to Layout: position: relative on Codepen

3.2. 絕對定位(absolute postioning)

給一個元素設置position: absolute屬性能夠將其徹底從正常流中移除。其本來佔據的空間也會被移除。該元素會定位會相對於視口容器,除非其某個祖先元素也是定位元素(position值不爲static)。

所以,當你爲某個元素設置position: absolute時,首先發生的變化是該元素會定位在視口的左上角。你能夠經過設置topleftbottomright偏移量屬性來將元素移動到你想要的位置。

.item {
    position: absolute;
    top: 20px;
    right: 20px;
}
複製代碼

一般狀況下你並不但願元素相對於視口進行定位,而是相對於容器元素。在這種狀況下,你須要爲容器元素設置一個除了默認static以外的值。

因爲給一個元素設置position: relative並不會將其從正常流中移除,因此一般這是一個不錯的選擇。給你想要相對的容器元素設置position : relative,就可讓絕對定位的元素相對其進行偏移。

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  position: relative;
}

.item {
  width: 100px;
  height: 100px;
  background-color: rgba(111,41,97,.3);
  position: absolute;
  top: 20px;
  left: 20px;
}
複製代碼

example: Smashing Guide to Layout: position: absolute on Codepen

3.3. 固定定位(fixed positioning)

大多數狀況下,position: fixed的元素會相對於視口定位,而且會從正常文檔流中被移除,不會保留它所佔據的空間。當頁面滾動時,固定的元素會留在相對於視口的位置,而其餘正常流中的內容則和一般同樣滾動。

.item {
    position: fixed;
    top: 20px;
    left: 100px;
}
複製代碼

當你想要一個固定導航欄一直停留在屏幕上時這會很是有效。和其餘的position值同樣,這也可能會形成一些元素被遮擋,須要當心保證頁面內容的可讀而不會被固定元素遮擋。

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  position: relative;
}

.item {
  width: 100px;
  height: 100px;
  background-color: rgba(111,41,97,.3);
  position: fixed;
  top: 20px;
  left: 20px;
}
複製代碼

example: Smashing Guide to Layout: position: fixed on Codepen

爲了使一個固定定位的元素不相對於視口進行定位,你須要爲容器元素設置transformperspectivefilter三個屬性之一(不爲默認值none)。這樣固定的元素就會相對於該塊級元素偏移,而非視口。

3.4. STICKY 定位

設置position: sticky會讓元素在頁面滾動時如同在正常流中,但當其滾動到相對於視口的某個特定位置時就會固定在屏幕上,如同fixed通常。這個屬性值是一個較新的CSS屬性,在瀏覽器兼容性上會差一些,但在不兼容的瀏覽器中會被忽略並會退到正常的滾動狀況。

.item {
    position: sticky;
    top: 0;
}
複製代碼

下面的代碼展現瞭如何建立一個很是流行導航欄效果:導航欄會隨着頁面滾動,而當導航欄滾動到頁面頂部時則會固定在頂部位置。

<div class="container">
  
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  
  <div class="item"></div>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
  
   <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  position: relative;
}

.item {
  width: 100px;
  height: 30px;
  background-color: rgba(111,41,97,.3);
  position: sticky;
  top: 0;
  width: 100%;
}
複製代碼

example: Smashing Guide to Layout: position: sticky on Codepen

3.5. 關於定位(positioning)的其餘閱讀資料


4. 彈性佈局(Flex Layout)

彈性盒子(Flexbox)佈局是一種爲一維佈局而設計的佈局方法。一維的意思是你但願內容是按行或者列來佈局。你可使用display: flex來將元素變爲彈性佈局。

.container {
    display: flex;
}
複製代碼

該容器的直接子元素會變爲彈性項(flex item),並按行排列。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
}

.item {
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
複製代碼

example: Smashing Guide to Layout: flex on Codepen

4.1. 彈性盒子的軸(axes)

在上面的例子中,咱們會稱彈性項在行內是從起始位置開始排列,而不是說它們是左對齊。這些元素會按行排列是由於默認的flex-direction值爲rowrow表明了文本的行文方向。因爲咱們工做的環境是英文(中文也是如此),一種自左向右的語言,行的開始位置就是在左邊,所以咱們的彈性項也是從左邊開始的。所以flex-direction的值被定義爲彈性盒子的主軸(main axis)。

交叉軸(cross axis)則是和主軸垂直的一條軸。若是你的flex-directionrow而且彈性項是按照行內方向排列的,那麼交叉軸就是塊級元素的排列方向。若是flex-directioncolumn那麼彈性項就會以塊級元素排列的方向排布,而後交叉軸就會變爲row

若是你習慣於從主軸與交叉軸的角度來使用彈性盒子,那麼一切會變得很是簡單。

4.2. 方向和次序

彈性盒子模型讓咱們能夠經過爲flex-direction屬性設置row-reversecolumn-reverse值來改變主軸上彈性項的方向。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
  flex-direction: row-reverse;
}

.item {
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
複製代碼

example: Smashing Guide to Layout: flex-direction on Codepen

固然,你也能夠經過order屬性來改變某一個彈性項的順序。可是要特別注意,這可能會給那些經過鍵盤(而非鼠標或觸屏)訪問你的網站的用戶帶來一些麻煩,由於tab的順序是頁面內元素在源碼中的順序而非顯示順序。你能夠閱讀以後的「顯示和文檔順序」部分來了解更多相關內容。

4.3. 一些Flex的屬性

這些flex的屬性是用來控制彈性項在主軸上空間大小的。這三個屬性是:

  • flex-grow
  • flex-shrink
  • flex-basis

一般可使用它們的簡寫形式:flex。第一個值表明flex-grow,第二個是flex-shrink,而第三個則是flex-basis

.item {
    flex: 1 1 200px;
}
複製代碼

flex-basis會爲彈性項設置未拉伸和壓縮時的初始大小。在上面的例子中,大小是200px,所以咱們會給每一個項200px的空間大小。可是大多數狀況下容器元素大小不會正好被分爲許多200px大小的項,而是可能有一些不足或剩餘空間。flex-growflow-shrink屬性容許咱們在容器大小不足或有空餘時控制各個彈性項的大小。

若是flex-grow的值是任意的正數,那麼彈性項會被容許拉伸來佔據更多的空間。所以,在上面的例子中,當各項被設爲200px後,全部多餘的空間會被每一個彈性項平分並填滿。

若是flex-shrink的值爲任意的正數,那麼當彈性項被設置了flex-basis後,元素溢出容器時會進行收縮。在上面這個CSS的例子中,若是容器空間不足,每一個彈性項會等比例縮放以適應容器的大小。

flex-growflex-shrink的值能夠是任意的正數。一個具備較大flex-grow值的彈性項會在容器有剩餘空間時拉伸更大的比例;而一個具備更大flex-shrink值的項則會在容器空間不足時被壓縮的更多。

<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
}

.item {
  flex: 1 1 0;
  width: 100px;
  height: 100px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.container :first-child {
  flex: 2 1 0; 
}
複製代碼

example: Smashing Guide to Layout: flex properties on Codepen

理解這些屬性是理解如何使用彈性佈局的關鍵,下面列出的一些資源會幫助咱們進一步學習其中的細節。當你須要在容器的一個維度上拉伸或者壓縮一些元素時,你能夠考慮使用彈性盒子模型。若是你發現你正嘗試在行和列兩個維度上排列你的內容,你須要的是網格模型(grid),這時彈性盒子模型極可能不是最合適的工具了。

4.4. 關於彈性盒子佈局的其餘閱讀資料


5. 網格佈局(grid layout)

CSS網格佈局(grid layout)是一種用來進行二維佈局的技術。二維(two-dimesional)意味着你但願按照行和列來排布你的內容。和彈性盒子相似,網格佈局也須要設置一個display值。你能夠爲容器元素設置display: grid,而且使用grid-template-columnsgrid-template-rows屬性來控制網格中的行與列。

.container {
    display: grid;
    grid-template-columns: 200px 200px 200px;
    grid-template-rows: 200px 200px;
}
複製代碼

上面這段CSS會建立一個行列元素大小固定的網格。不過這也許並非你但願的。默認值爲auto,你能夠認爲這表明了「讓格子儘量的大」。若是你每沒有指定行(row track)的大小,全部添加進來的行內容大小都會被置爲auto。一種經常使用的模式是爲網格制定列寬度,可是容許網格按需添加行。

你可使用任意的長度單位或時百分比來設置行與列,同時你可使用爲網格系統所創造的新的單位——frfr是一種彈性單位,它能夠指定網格容器內的空間被如何劃分。

網格會替你計算與分配空間,你不須要去計算元素的百分比去適應容器大小。在下面這個例子中,咱們使用fr來建立網格的列,這使得網格的列能夠自適應。同時咱們還使用了grid-gap來保證元素間的間距(關於網格內元素與的間距會在「對齊」這一部分詳細介紹)。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5<br>has more content.</div>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
複製代碼

example: Smashing Guide to Layout: a simple grid on Codepen

5.1. 關於網格的一些術語

網格系統老是有兩個軸:inline axis表示頁面中文字的文字排列的方向,block axis表示頁面中塊級元素的排列方向。

一個被設置爲display: grid的元素就是所謂的網格容器。在網格容器中會有網格線(grid line),網格線就是你在指定grid-template-columnsgrid-template-rows時網格中行列所生成的。網格中的最小單位(也就是被四條網格線截取生成的區域)被成爲網格單元格(grid cell),進一步的,由若干個單元格組成的矩形區域被成爲網格區域(grid area)。

Grid Lines run between each track of the grid.

Grid Tracks are between any two lines

Grid cells are the smallest unit on the grid, a Grid Area is one or more cells together making a rectangular area

5.2. 網格的自動排列規則

一旦你建立了網格,那麼網格容器的直接子元素就會開始將它們本身一個一個地放置在網格的單元格中。子元素的放置是依據網格的自動排列規則(auto-placement rule)。這些規則確保了網格內元素是被安排在各個空的單元格中,而不會彼此遮蓋。

網格中任何沒有被進行定位的直接子元素都會根據自動排列規則進行放置。在下面這個列子中,我讓每三個元素中的第一個佔據兩行,但仍然從起始行開始去自動排列。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
  <div>9</div>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.container > div:nth-child(3n+1) {
  grid-row-end: span 2;
  background-color: rgba(193,225,237,.3);
  border: 2px solid rgba(193,225,237,.5);
}
複製代碼

example: Smashing Guide to Layout: auto-placement on Codepen

5.3. 基於行/列的基本定位方法

定位網格元素最簡單的方式是使用基於行/列(line)的定位方法,只需告訴瀏覽器從哪一排到哪一排來進行合併。例如,若是你須要一個2*2的網格區域,你能夠將指定元素從第一行開始到第三行、從第一列開始到第三列,這樣就能夠覆蓋到四個單元格。

.item {
    grid-column-start: 1;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 3;
}
複製代碼

這些屬性能夠用縮寫來表示:grid-columngrid-row,其中起一個值表明起始值,第二個值表明結束值。

.item {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
}
複製代碼

你也可讓網格項(grid item)佔據同一個單元格。支持一些內容間會覆蓋的設計。網格項會像一般網頁中的元素那樣疊起來,在html源碼中下面的網格項會疊在其餘元素上面。你仍然能夠用z-index來控制它的堆疊順序。

<div class="container">
  <div class="one">1</div>
  <div class="two">2</div>
  <div class="three">3</div>
  <div class="four">4</div>
  <div class="five">5</div>

</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 20px;
}

.container > div {
  padding: 10px;
}

.one {
  grid-column: 1 / 4;
  grid-row: 1;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.two {
  grid-column: 1 / 3;
  grid-row: 2;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.three {
  grid-column: 2 / 4;
  grid-row: 2 / 5;
  background-color: rgba(193,225,237,.3);
  border: 2px solid rgba(193,225,237,.5);
}

.four {
  grid-column: 1;
  grid-row: 4 ;
  background-color: rgba(193,225,237,.3);
  border: 2px solid rgba(193,225,237,.5);
}

.five {
  grid-column: 3 ;
  grid-row: 4 / 5;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
複製代碼

example: Smashing Guide to Layout: line-based placement on Codepen

5.4. 經過命名區域來定位元素

你能夠經過命名區域(named areas)來定位網格中的元素。要是用這種方式,你須要給每一個元素一個名字,而後經過grid-template-areas屬性的值來描述佈局方式。

.item1 {
    grid-area: a;
}

.item2 {
    grid-area: b;
}

.item3 {
    grid-area: c;
}

.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-areas: 
     "a a b b"
     "a a c c";
}
複製代碼

使用這種方式有幾個須要注意的點。若是你想要合併一些單元格做爲你的網格項,你須要重複元素的名字。網格區域須要能造成一個完整的矩形 —— 每一個單元格都須要被填入一個值。若是你想要空出某些單元格,那就須要使用.這個值。例如在下面的CSS裏我將最右下角的單元格留空。

.container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-areas: 
     "a a b b"
     "a a c .";
}
複製代碼

你也能夠經過下面這個demo的代碼來看看實際的佈局效果。

<div class="container">
  <div class="one">1</div>
  <div class="two">2</div>
  <div class="three">3</div>
  <div class="four">4</div>
  <div class="five">5</div>

</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-rows: minmax(50px, auto);
  grid-gap: 20px;
  grid-template-areas: 
    "a a a"
    "b c c"
    ". . d"
    "e e d"
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.one {
  grid-area: a;
}

.two {
  grid-area: b;
}

.three {
  grid-area: c;
}

.four {
  grid-area: d;
}

.five {
  grid-area: e;
}

複製代碼

example: Smashing Guide to Layout: grid-template-areas on Codepen

5.5. 關於網格佈局的其餘閱讀資料

這片文章只包括了CSS網格佈局的一些初步內容,其中還有很是多的內容值得學習,下面的一些資料能夠幫助你進一步學習。一些組件或整個頁面的佈局均可以使用網格。若是你須要在兩個維度進行佈局,網格佈局是一個不錯的選擇 —— 不論須要佈局的區域的大小。

我(做者)在Smashing Magazine也寫一些文章來幫助你深刻理解各類網格的概念:


6. 顯示順序和文檔順序(visual and document order)

在文章的最開始,我建議你以從上到下的閱讀順序來組織你的文檔順序,這樣會有助於可讀性和CSS的佈局方式。從咱們關於彈性盒子和CSS網格的簡短介紹來看,你能夠發現用這些佈局方法可能會極大地改變頁面展現的元素在文檔中的順序。這可能會致使一個隱含的問題。

在一些非可視化的應用場景中,瀏覽器會遵循文檔源碼來進行使用。所以,屏幕閱讀器會讀取文檔的順序,此外使用鍵盤tab鍵來瀏覽的用戶訪問文檔的順序是基於源碼的順序,而不是元素展現的順序。許多屏幕閱讀器的用戶並不是徹底失明,他們可能在使用屏幕閱讀器的同時也可以看到這些元素在文檔的哪一個部分。在這些狀況下,當與源碼進行對比時,這種混亂的頁面展示可能會使人充滿迷惑。

當你改變了元素在文檔中原來的順序時,必定確保知道本身在作什麼。若是你發現你本身正在CSS中從新排序你的元素,你應該去回頭看看是否要從新組織你的頁面元素。你能夠經過使用tab訪問來測試一下你的頁面。

6.1. 關於顯示順序和文檔順序的其餘閱讀資料


7. 盒模型的生成(box generation)

你寫在網頁裏的任何東西都會生成一個盒子(box),這篇文章討論的全部東西其實都是如何可以使用CSS來按照你的設計佈局這些盒子。然而,在某些狀況下,你可能根本不想建立一個盒子。有兩個display的屬性值會幫你處理這種狀況。

7.1. 不生成盒子或內容(display: none

若是你但願元素以及它全部的內容(包括全部子元素)都不會生成,你可使用display: none。這樣元素就不會被展現,而且不會保留其本該佔有的空間。

.item {
    display: none;
}
複製代碼

7.2 不生成該元素,可是生成其全部子元素(display: contents

display: contentdisplay的一個新的屬性值。爲一個元素應用display: content屬性會致使其自身的盒子不生成但全部的子元素都會照常生成。這有什麼用呢?試想一下,若是你但願一個彈性佈局或網格佈局中的非直接子元素能應用這些佈局,這就會很是有用。

在下面這個例子裏,第一個彈性項包含了兩個子元素,因爲它被設爲display: contents,它的盒子不會生成而且它的兩個子元素會成爲彈性項,並被看成彈性盒子容器的直接子元素來佈局。

<div class="container">
  <div class="item">
    <div class="subitem">A</div>
    <div class="subitem">B</div>
  </div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
}

.item {
  flex: 1 1 200px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}

.subitem {
  padding: 10px;
  background-color: rgba(193,225,237,.3);
  border: 2px solid rgba(193,225,237,.5);
}

.container .item:first-child {
  display: contents;
}
複製代碼

example: Smashing Guide to Layout: display: contents on Codepen

7.3. 關於box generation的其餘閱讀資料


8. 對齊

在之前,要實現對齊每每會用到一些很"tricky"的方式,而且可以使用的方法也很是有限。隨着CSS盒模型對齊(box alignment module)的出現,這一切都發生了變化。你將會使用它來控制網格容器與彈性盒子容器中的對齊。將來其餘的各類佈局方法都會應用這些對齊屬性。盒模型對齊(box alignment specification)規範中的一系列詳細屬性以下:

  • justify-content
  • align-content
  • place-content
  • justify-items
  • align-items
  • place-items
  • justify-self
  • align-self
  • place-self
  • row-gap
  • column-gap
  • gap

因爲不一樣的佈局模型有不一樣的特性,所以用於不一樣佈局模型的對齊屬性會有一些表現上的差別。讓咱們來看看在一些簡單的網格與彈性佈局中對齊是如何工做的。

align-itemsjustify-items屬性相對是align-selfjustify-self屬性的一種批量形式。這些屬性會控制與元素在其網格區域(grid area)中的對齊狀況。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div class="special">5</div>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-auto-rows: minmax(100px, auto);
  grid-gap: 20px;
  align-items: center;
  justify-items: start;
}

.special {
  grid-column: 2 / 4;
  align-self: end;
  justify-self: end;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
複製代碼

example: Smashing Guide to Layout: Grid align-items, justify-items, align-self, justify-self on Codepen

align-contentjustify-content屬性則會對網格中的行/列(tracks)進行對齊控制(網格容器中須要在排列完行/列元素後有多餘的空間)。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  height: 300px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-auto-rows: minmax(100px, auto);
  grid-gap: 20px;
  align-content: space-between;
  justify-content: end;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
複製代碼

example: Smashing Guide to Layout: Grid align-content, justify-content on Codepen

在彈性盒子中,align-itemsalign-self用來解決交叉軸上的對齊問題,而justify-content則用於解決主軸上空間的分配。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div class="special">3</div>
  <div>4</div>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  height: 300px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
}

.special {
  align-self: stretch;
}

.container > div {
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
複製代碼

example: Smashing Guide to Layout: Flex justify-content, align-items, align-self on Codepen

在交叉軸上,把彈性行(flex line)和額外空間包裹在彈性容器中以後,你就可使用align-content了。

<div class="container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
</div>
複製代碼
p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  height: 300px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  display: flex;
  flex-wrap: wrap;
  align-content: space-between;
}

.container > div {
  flex: 1 1 200px;
  padding: 10px;
  background-color: rgba(111,41,97,.3);
  border: 2px solid rgba(111,41,97,.5);
}
複製代碼

example: Smashing Guide to Layout: Flex align-content on Codepen

下面的一些連接更細節地討論了各種佈局方法中的盒模型對齊。花些時間去理解對齊的工做原理是很是值得的,它對理解彈性盒子、網格佈局以及將來的一些佈局方法都會頗有幫助。

8.1. 行/列的間隔

一個多欄佈局具備column-gap屬性,到目前位置,網格佈局具備grid-column-gaogrid-row-gapgrid-grid。這些如今都被從grid標準中刪除而被添加進盒模型對齊中了。與此同時,grid-的前綴屬性被重命名爲column-gaprow-gapgap。瀏覽器會將帶有前綴的屬性換爲新的重命名屬性,因此若是你在目前的代碼中使用兼容性更好的老名字也不用擔憂。

重命名意味着這些屬性也能被應用於其餘佈局方法,一個明顯的備選就是彈性盒子。雖然目前沒有瀏覽器支持盒子模型中的gap屬性,可是在將來咱們應該可使用column-gaprow-gap來建立彈性項目元素間的間距。

8.2. 關於box generation的其餘閱讀資料


9. 多欄佈局(多列布局)

多欄佈局(multi-column layout)是一種支持建立多欄的佈局類型,如同報紙上那樣。每一塊都被分割成欄(column),你會按照塊方向在欄中往下讀而後會在回到下一欄的頂部。然而用這種方式閱讀在網頁內容中並不老是有效,由於人們並不想去讓滾動條滾動來、滾動去地去閱讀。當須要展現少部份內容、摺疊一組複選框或者其餘一些小的UI組件時會很是有用。

當展現一組高度不一樣的卡片或產品時多欄佈局也很是有用。

9.1. 設置欄的寬度

要設置一個最有的欄寬,並通知瀏覽器依此寬度展現儘量多的欄可使用下面的CSS:

.container {
    column-width: 300px;
}
複製代碼

這會建立儘量多的300px的欄,全部剩下的空間會被全部欄共享。所以,除非空間被劃分爲300px時沒有剩餘,不然你的欄會比300px稍多一些。

9.2. 設置欄的數目

除了設置寬度,你可使用column-count來設置欄的數目。在這種狀況下,瀏覽器會將空間均分給你須要的數目的欄。

.container {
    column-count: 3;
}
複製代碼

若是你同時添加了column-widthcolumn-count,那麼column-count屬性會做爲一個最大值限制。在下面的代碼裏,欄會被添加直到達到三個,此時任何額外的空間都會被分給三欄,即便空間足夠成爲一個額外的新欄。

.container {
    column-width: 300px;
    column-count: 3;
}
複製代碼

9.3. 間距和欄規則

你沒法爲單個欄盒子添加外邊距和內邊距,須要用column-gap屬性來設置間距。若是你不具體指定column-gap的值,它會默認爲1em來防止欄間碰撞。這和其餘佈局方法中column-gap的行爲不同,其餘佈局中默認爲0。你能夠在間距上使用任意的長度單元,包括0(若是你不但願有欄間距)。

column-rule屬性讓你有能力向兩欄間添加規則。它是column-rule-widthcolumn-rule-colorcolumn-rule-style的簡寫形式,可border行爲相似。注意,一個規則自身不會佔用任何空間。它會佔據在間距的頂部,從而增長或減小那些你設置column-gap的規則與內容間的空間。

<div class="container">
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  column-width: 120px;
  column-gap: 20px;
  column-rule: 4px dotted #000;
}
複製代碼

example: Smashing Guide to Layout: multicol on Codepen

9.4. 容許元素橫跨多欄

你可使用column-span屬性讓多欄容器內的元素橫跨多欄,相似通欄。

h3 {
    column-span: all;
}
複製代碼

column-span出現時,多欄容器分欄會在這個元素上放停下,所以,容器裏的內容會在元素上方造成多欄樣式,而後在橫跨元素(spanning element)的下方造成一組新的欄盒子(column box)。

<div class="container">
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <h2>Veggies!</h2>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. </p>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  column-width: 120px;
  column-gap: 20px;
  column-rule: 4px dotted #000;
}

.container h2 {
  column-span: all;
  background-color: rgba(193,225,237,.6);
  border:2px solid rgba(193,225,237,.6);
  margin: 1em 0;
  padding: .5em;
}
複製代碼

example: Smashing Guide to Layout: multicol span on Codepen

你只可使用column-span: allcolumn-span: none,並不能讓元素橫跨某幾個欄(非通欄)。在文章寫做時,Firefox還不支持column-span屬性。

9.5. 關於多欄佈局的其餘閱讀資料


10. 碎片化(Fragmentation)

多欄佈局是碎片化(fragmentation)的一個例子,頁面內容會被拆分紅欄。這和打印時內容被分到不一樣頁很是相似。這個過程是碎片化規範(Fragmentation specification)處理的。這個規範包括了一些幫助控制內容切分的屬性。

例如,若是你有一組置於多欄中的卡片,而且你想確保卡片不會被截爲兩半分到不一樣的欄,你可使用break-inside屬性的avoid值。考慮瀏覽器兼容性的因素,你也可能會想使用遺留的page-break-inside屬性。

.card {
    page-break-inside: avoid;
    break-inside: avoid;
}
複製代碼

若是你想在heading元素後禁止斷行,你可使用break-after屬性。

.container h2 {
    page-break-after: avoid;
    break-after: avoid;
}
複製代碼

這些屬性能夠被用在打印樣式或多欄樣式中。在下面的例子裏,在多欄容器中的三個段落被拆分到了三欄之中。我爲p元素設置了break-inside: avoid,這意味着每一個多欄會在本身的欄中結束(即便這會使各欄長度不一樣)。

<div class="container">
  <p>Pea horseradish azuki bean lettuce avocado asparagus okra. Kohlrabi radish okra azuki bean corn fava bean mustard tigernut jícama green bean celtuce. </p>
  <p>Grape silver beet  collard greens avocado quandong fennel gumbo black-eyed pea watercress potato tigernut corn groundnut. Chickweed okra pea winter purslane coriander yarrow sweet pepper radish garlic brussels sprout</p>
  
  <p>Groundnut summer purslane earthnut pea tomato spring onion azuki bean gourd. Gumbo kakadu plum komatsuna black-eyed pea green bean zucchini gourd winter purslane silver beet rock melon radish asparagus spinach.</p>
</div>
複製代碼
body {
  padding: 20px;
  font: 1em Helvetica Neue, Helvetica, Arial, sans-serif;
}

* {box-sizing: border-box;}

p {
  margin: 0 0 1em 0;
}

.container {
  width: 500px;
  border: 5px solid rgb(111,41,97);
  border-radius: .5em;
  padding: 10px;
  column-width: 120px;
  column-gap: 20px;
  column-rule: 4px dotted #000;
}

.container p {
  page-break-inside: avoid;
  break-inside: avoid;
}
複製代碼

example: Smashing Guide to Layout: multicol fragmentation on Codepen

10.1. 關於碎片化的其餘閱讀資料


11. 如何選擇佈局類型?

大多數的網頁會混合使用多種佈局類型。各佈局規範都準肯定義了它們之間是如何相互做用的。例如,你可能會在網格佈局的網格項中使用彈性佈局。一些彈性容器可能具備定位屬性或浮動。這些規範根據最優的佈局方式已經包含了佈局模型的混合使用。在這篇指南中,我嘗試概述了這種佈局類型的基本使用方式,來幫助你瞭解實現一個效果可能的最好方法。

然而,別懼怕去運用多種方式來實現佈局設計。擔憂你的選擇會不會形成實際問題的狀況比你想象中要少不少。因此請在開始就組織好你的文檔結構,而且注意你文檔內容的可視展現順序。剩下的大部分工做就是在瀏覽器中試試你的佈局方式是否符合預期。


原文:Getting Started With CSS Layout,感謝做者Rachel Andrew。

相關文章
相關標籤/搜索