寫給自己看的CSS columns分欄佈局教程
byzhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8436
本文可全文轉載,個人網站無需授權,只要保留原作者、出處以及文中連結即可,任何網站均可摘要聚合,商用請聯絡授權。

一、前言&索引
Multiple-column佈局,也稱多列布局、多欄佈局,我自己喜歡叫做分欄佈局,這種佈局可以講內容佈局到一組列框,類似於報紙上的排版。
分欄佈局非常特殊,有別於傳統佈局方法,它將包括包括所有子元素在內的所有內容拆分為列,這與我們列印網頁時候時頁面內容分割成不同的頁面的方式類似。
分欄佈局IE10+都可以使用,API穩定,移動端相容性比flex佈局要好,雖然設計初衷不一樣,但很多佈局都可以實現。甚至某些場景下,只能使用分欄佈局才能實現。很有學習的必要。
與分欄佈局相關的CSS屬性包括:
直接相關屬性 | 間接相關屬性 |
---|
二、直接相關CSS屬性
1. column-width
column-width
表示每一欄/列的最佳寬度。
如果我們只設定 column-width
,瀏覽器會自動根據現有容器寬度劃分欄目的個數。
語法如下:
column-width: <length> | auto;
其中:
- <length>
- 表示設定的最佳列寬值。實際呈現的每一欄的寬度可能與指定值不同,具體內容參見下面的細節描述。
- auto
-
預設值。表示每一欄的寬度由其它CSS屬性決定,例如
column-count
。
一些細節:
-
column-width
有時候會無效。例如容器寬度400畫素,設定的每一欄寬度是300畫素,不足以分欄,此時內容填充填充表現為充分利用可用空間,最終呈現的列寬比設定的更寬。又例如容器寬度400畫素,column-width
設定為500畫素,則最終分欄寬度不會超過容器寬度,比設定的500畫素要小。 -
column-width
不支援負值,也不支援百分比值。
實地演示:
點選下面的選項卡,感受下不同 column-width
屬性值下的佈局表現:
CSS column-width
屬性指定多列布局中的理想列寬。容器將具有儘可能多的列,其中任何一列的寬度都不小於列寬值。如果容器的寬度小於指定值,則單列的寬度將小於宣告的列寬。
此屬性可以幫助您建立適合不同螢幕大小的響應式設計。尤其是在 column-count
屬性(具有優先權)存在的情況下,必須指定所有相關的長度值以獲得精確的列寬度。在水平文字中,這些長度值包括 width
、 column-width
、 column-gap
,以及 column-rule-width
。
2. column-count
column-count
表示理想的分欄數目。
語法如下:
column-count: <integer> | auto;
其中:
- <integer>
- 表示分欄數目,整數值。
- auto
-
預設值。表示分欄數目由其它CSS屬性決定,例如
column-width
。
一些細節:
-
column-count
與column-width
都有可能有更高的優先順序,要看具體場景。優先順序計算訣竅就是統一轉換column-count
值,哪個小就使用哪一個。 -
column-count
不支援負值,也不支援0
。
實地演示:
點選下面的選項卡,感受下不同 column-count
屬性值下的佈局表現:
column-count:2;
column-width:200px
column-count:4;
column-width:200px
這個選項卡測試切換效果建議在PC端瀏覽器上體驗,在移動端,由於寬度限制感受不到後兩個選項的差異。
在PC桌面端,容器寬度大約700畫素出頭一點,此時 column-width:200px
換算成 column-count
大約3.6的樣子。於是,選項卡3分成了2欄,因為 column-count:2
值更小;而選項卡4由於 column-width
換算值更小,因此 column-width
優先順序更高,最終分成了3欄顯示。
其中,我們重點關注選項卡3和選項卡4。在PC算,由於容器寬度大約700畫素出頭一點,因此 column-width:200px
可以近似看成 column-count
為3.6的樣子。還記不記得上面提到的優先順序計算訣竅:哪個值小哪個優先順序高。於是,選項卡3分成了2欄,因為 column-count:2
值更小;而選項卡4由於 column-width
換算值更小,因此 column-width
優先順序更高,最終分成了3欄顯示。
另外,從兩欄效果可以看出,columns每一個欄目的高度並不總是相等的,內容的分割也不總是均勻的,瀏覽器有一套自己的演算法。
3. columns
columns
是 column-width
和 column-count
屬性的縮寫。舉幾個使用的例子:
/* 欄目寬度 */ columns: 18em; /* 欄目數目 */ columns: auto; columns: 2; /* 同時定義寬度和數目 */ columns: 2 auto; columns: auto 12em; columns: auto auto;
不展開。
4. column-rule-color
column-rule-color
表示每個欄目中間分隔線的顏色。
語法如下:
column-rule-color: <color>
支援的屬性值和 border-color
是一模一樣的,例如:
column-rule-color: red; column-rule-color: rgb(255, 0, 0); column-rule-color: transparent; column-rule-color: hsla(0, 100%, 50%, 0.5);
預設值是當前 color
屬性的計算值。
例項如下:
column-rule-style: dotted; column-rule-color: red;
實時效果如下:
由於 column-rule
預設的分隔線的型別是 none
,因此,我們必須要指定 column-rule-style
,否則會看不到分隔線。 column-rule-*
相關屬性值和 border-*
是一樣的。
5. column-rule-style
column-rule-style
表示每個欄目中間分隔線的型別。支援的屬性值和 border-style
是一模一樣的,例如:
column-rule-style: none; column-rule-style: hidden; column-rule-style: dotted; column-rule-style: dashed; column-rule-style: solid; column-rule-style: double; column-rule-style: groove; column-rule-style: ridge; column-rule-style: inset; column-rule-style: outset;
每個屬性值具體效果可以點選下面選項卡進行體驗:
其中 dotted
表示虛點, dashed
表示虛線, solid
表示實線。這三個比較常用,就不多展開。然後著重提下後面幾個,首先是 double
, double
表示
雙線邊框,顧名思意,兩根線,且為實線。雖然平常我們使用少,但是相容性非常好。視覺表現為線框-透明-線框。其它 column-rule-style
型別,如 inset
(內凹), outset
(外凸), groove
(溝槽), ridge
(山脊),風格老土過時,且相容性慘不忍睹,因此,沒有任何實用價值,大家無需關心。
科學研究表明,對於大多數人而言,無論在這裡寫的是什麼文字,都不會被讀者注意到。
5. column-rule-width
column-rule-width
表示每個欄目中間分隔線的寬度大小。支援的屬性值和 border-width
是一模一樣的,例如:
/* 關鍵字值 */ column-rule-width: thin; column-rule-width: medium;/* 預設值 */ column-rule-width: thick; /* 具體長度值 */ column-rule-width: 1px; column-rule-width: 2.5em;
我們平常使用 column-rule-width
幾乎全是固定的數值,比方說 column-rule-width:1px
之類,於是對關鍵字屬性值不太瞭解,這裡介紹下。 column-rule-width
支援三個關鍵字屬性值,分別是 thin
, medium
(預設值)和 thick
,對應的具體尺寸大小如下:
-
thin
:薄薄的,等同於1px
; -
medium
(預設值):薄厚均勻,等同於3px
; -
thick
:厚厚的,等同於4px
;
不知大家有沒有想過這麼一個問題:為什麼預設寬度大小是 medium
,也就是3px,明明thin(1px)寬度更常用吧?這是因為…… column-rule-style:double
至少3px才有效果!
6. column-rule
column-rule
是 column-rule-width
, column-rule-style
和 column-rule-color
這3個CSS屬性的縮寫。正如 border
是 border-style
, border-width
和 border-color
的縮寫一樣。
其他沒什麼好說的,幾個屬性值順序不講究,隨便。除了 column-rule-style
之外那其它兩個屬性可以預設。
7. column-span
column-span
有點類似於表格佈局中的 colspan
這個HTML屬性,表示某一個內容是否跨多欄顯示。
語法
column-span: none; column-span: all;
其中:
- none
- 表示不橫跨多欄,預設值。
- all
- 表示橫跨所有垂直列。
我們一起來看一個例子,就知道這個屬性是幹嘛用的了:
在HTML中,類似單元格 <td>
元素可以設定 colspan
屬性,表示合併單元格,例如 colspan="3"
表示3個普通單元格合併成1個大的單元格。
column-span
這個CSS屬性作用與之類似,只是不能指定具體的數目。要麼不跨列,要跨就跨全部條列。
在我們想要在垂直分欄顯示的文章中插一個橫貫整個頁面的廣告的時候,就可以使用這個屬性。或者單純只是希望上下再垂直分欄顯示,也可以使用該屬性。
實際開發的時候,非指定某個元素 column-span:all
,沒有文字內容,就一個高度,或者加個水平邊框,就可以將文章內容進一步上下分欄。於是,一篇文章的內容,就如報紙排版一樣,想要在哪裡分欄就隨心所欲了。
當然,插入通欄廣告也可以使用該屬性。
8. column-fill
column-fill
作用是當內容分欄的時候,如何平衡每一欄填充的內容。
語法
column-fill: auto; column-fill: balance; column-fill: balance-all;
其中:
- auto
- 按順序填充每一列。內容只佔用它需要的空間。
- balance
-
預設值。儘可能在列之間平衡內容。在分隔斷開的上下文中,只有最後一個片段是平衡的。舉例來說就是有多個
<p>
元素,正好最後一個<p>
換行了,那這個<p>
元素的內容前後等分,保持平衡。這就會造成最後一欄內容較少的情況。 - balance-all (可忽略)
- 儘可能在列之間平衡內容。在分隔斷開的上下文中,所有片段都是平衡的。
我們一起來看一個與 column-fill
屬性相關的demo(目前僅Firefox瀏覽器有正確表現):
這是一堆分成多個的文字列。CSS`column-fill`屬性是用於將內容均勻地分佈在一起所有列。
column-fill
這個屬性的準確渲染需要在Firefox瀏覽器下才可以看到。當我們點選 auto
的時候,所有的文字內容應該擠在最左邊一欄中才是正確的。但是Chrome和IE下卻和 balance
屬性值表現一樣。
上面demo當我們點選 'auto'
這個選項卡的時候,正確的表現應該如下圖所示:
還有,根據我在IE,Chrome和Firefox瀏覽器下測試,這幾個瀏覽器點選 balance-all
都沒能識別。我檢視官方草案文件,也沒有 balance-all
的示意,該屬性值大家可以忽略。
9. column-gap
column-gap
表示每一欄之間的那個空白間隙大小。
語法
column-gap: normal | <length-percentage>;
具體
/* 關鍵字值 */ column-gap: normal; /* 長度值 */ column-gap: 3px; column-gap: 3em; /* 百分比值 */ column-gap: 3%;
其中:
- normal
-
預設值。在多欄佈局中為
1em
,在其它型別的佈局中為0
。 - <length>
- 具體的長度值。不支援負數。
- <percentage>
-
百分比值。和
column-width
不同,column-gap
支援百分比值。同樣,不能是負數。
實地demo演示
雖然 column-gap
屬性的預設值 normal
最終的表現就是 1em
,但並不表示可以和數值屬性值產生 transition
過渡效果。因此,當我們點選到第一個選項卡的時候,寬度變化是突然的,而不是連續的。
column-gap
和 columns
屬性發生衝突的時候,例如, column-gap
太大,導致空間不足,此時, column-gap
是會被捨棄的。
三、間接相關CSS屬性
每個可能的斷點(換句話說,每個元素邊界)受三個屬性的影響:前一個元素的 break-after
值,下一個元素的 break-before
值,以及包含元素的 break-inside
值。
下面要介紹的3個屬性,可以控制分欄佈局中當前元素前後是否允許分欄。
1. break-after
break-after
這個CSS屬性定義頁面,列或區域中斷在生成的框之後應該如何表現。如果沒有生成框,則忽略該屬性。
break-after
支援屬性很多,但大多瀏覽器不支援,我們目前只要關注下面兩個屬性值就好了:
break-after: auto; break-after: avoid;
其中:
- auto
- 允許但不強制在主框之後插入任何中斷(page,column或region佈局下)。
- avoid
- 避免在主體框後插入任何分隔符(page,column或region佈局下)。
2. break-before
break-before
這個CSS屬性定義頁面,列或區域中斷在生成的框之前應該如何表現。如果沒有生成框,則忽略該屬性。
break-before
支援屬性很多,但大多瀏覽器不支援,我們目前只要關注下面兩個屬性值就好了:
break-before: auto; break-before: avoid;
其中:
- auto
- 允許但不強制在主框之前插入任何中斷(page,column或region佈局下)。
- avoid
- 避免在主體框前插入任何分隔符(page,column或region佈局下)。
3. break-inside
break-inside
這個CSS屬性定義頁面、列或區域發生中斷時候的元素該如何表現。如果沒有中斷,則忽略該屬性。
break-inside
支援屬性相對少一些,同樣的,我們目前只要關注下面兩個屬性值就好了:
break-inside: auto; break-inside: avoid;
其中:
- auto
- 元素可以中斷。
- avoid
- 元素不能中斷。
demo例項頁面
拿column分欄佈局舉例,分欄佈局在流動和平衡內容方面做得很好。不幸的是,並非所有元素都能優雅地流動。有時元素會斷開分佈在兩個列中。如下圖所示:
有時候,我們希望我們的條目一個元素一個元素都是獨立的,前後都不斷開,此時,就可以使用 break-inside:avoid
實現:
.list { -webkit-column-break-inside: avoid; /* Chrome, Safari, Opera */ page-break-inside: avoid; /* Firefox */ break-inside: avoid; /* IE 10+, Chrome, Safari, Opera */ }
此時效果如下截圖:
您可以狠狠地點選這裡: CSS break-inside與分欄不斷開demo
其他
應該是上個月,還介紹了一個名為 box-decoration-break
的CSS屬性,也與columns佈局是相關的,其作用更多的是元素斷開後的裝飾表現。有興趣可以參見這篇文章:“ CSS/CSS3 box-decoration-break屬性簡介 ”。
四、一些特殊佈局應用舉例
CSS3 columns多欄佈局可以實現水平翻書閱讀效果。
具體見這篇文章:“ 基於CSS3 column多欄佈局實現水平翻頁互動 ”。
CSS3 columns多欄佈局還可以用來實現等分導航效果,支援單行和多行,類似flex佈局那種效果,但相容性比flex要好。本文篇幅已經很長了,相關內容我回頭專門寫一篇文章介紹。
其他類似主題文章
能夠閱讀到這裡的都是真愛,感謝,比心!
本文為原創文章,會經常更新知識點以及修正一些錯誤,因此轉載請保留原出處,方便溯源,避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。
本文地址: https://www.zhangxinxu.com/wordpress/?p=8436
(本篇完)