原文: When And How To Use CSS Multi-Column Layout
做者:Rachel Andrew
譯者:博軒
當咱們把注意力都放在 CSS Grid
佈局和 CSS Flexbox
佈局的時候,常常忽略了另外一種佈局方法。在本文中,我將介紹多列布局 - 一般稱爲 multicol
或者 「CSS Columns」 。經過這篇文章,你瞭解到使用 columns
的最佳實踐,以及一些使用 columns
的注意事項。css
multicol
的基本思想是,你能夠把一大塊內容帶到多個列中,就像報紙同樣。您可使用兩個屬性中的其中一個來完成此操做。您可使用 cloumn-count
屬性來指定內容的列數。還可使用 column-width
屬性來指定理想的列寬,讓瀏覽器來決定合適的列數。git
不論你的內容包含什麼樣的元素,當你將它轉換爲多列布局時,一切都將保持正常的內容流,可是將以列的形式展示。這使得 multicol
佈局與現在在瀏覽器中常見的其餘佈局會有所不一樣。例如 Flexbox
和 Grid
,獲取容器元素中子元素,讓這些子元素參與到 flex
和 grid
的佈局中來。使用 multicol
,在每一列的內部,您還能夠得到正常的內容流。github
在下面的例子中,咱們正在使用 column-width
,最小列寬爲 14em
。Multicol
會盡量多的分配寬度爲 14em
的列,而後,讓每一列分享剩餘的空間。每一列的寬度至少 14em
,除非,容器的寬度小於 14em
,那麼將只展現一列。multicol
也是 CSS
中首次出現的一種行爲,能夠建立出列,同時也默認符合響應式的規則。您沒必要增長 CSS 查詢條件 (Media Queries
) ,修改每個斷點的列數,而是制定一個最佳的寬度,讓瀏覽器自身來進行處理。web
示例連接設計模式
// 核心代碼摘錄 .container { max-width: 800px; margin: 0 auto; column-width: 14em; }
當你使用列屬性(columns
)來建立佈局的時候,cloumns box
中的內容將沒法定位。您沒法使用 JavaScript
來進行定位,您也沒法爲單個列來指定惟一的樣式,好比背景顏色,外邊距,內邊距等等。全部 column boxes
將保持相同的大小。你惟一能夠作的事情,就是使用 column-rule
屬性來添加列之間的規則,該屬性的做用相似於 border
。您還可使用 column-gap
屬性控制列之間的間隙,該屬性的默認值爲 1em
,可是您還能夠將其改成任何有效的長度單位。瀏覽器
示例連接安全
// 核心代碼 .container { max-width: 800px; margin: 0 auto; column-width: 14em; column-gap: 2em; column-rule: 1px solid #ccc; }
這是 multicol
的基本功能。您能夠將一大塊內容拆分爲列。內容將依次填充到每一列,並在內聯的方向建立這些列。您能夠控制列之間的間隙以及規則,使用與 border
相同的取值便可。到目前爲止,上述全部內容在瀏覽器中獲得了很好的支持,而且已經存在了很長時間,使得這個規範在向後兼容性方面很是安全。ide
您可能須要考慮使用列的其餘一些事項,以及在Web上使用列時須要注意的一些潛在問題。佈局
有時候,您可能但願將某些內容分解爲列的同時,使用一個元素跨越這些列。將 columns-span
屬性用於 multicol
能夠實現這一點。flex
下面的示例中,我使用一個 <blockquote>
元素來跨越列。請注意,在執行此操做時,內容會被分爲兩個區域,分別位於設置了 column-span
元素的上下兩個部分。內容不會跳過設置了 column-span
的元素。
column-span
屬性目前已在 Firefox 中實現,而且向後兼容。
// 核心代碼 blockquote { font: 2em 'Berkshire Swash', cursive; margin: 0; column-span: all; text-align: center; } .container { max-width: 800px; margin: 0 auto; column-width: 14em; column-gap: 2em; column-rule: 1px solid #ccc; }
要知道,目前的規範,column-span
的取值只有 all
或者 none
。若是你想實現報紙中的樣式,可使用多列布局結合其餘佈局來實現。在下面的示例中,咱們實現了一個帶有兩個列軌道的網格容器(Grid)。左邊軌道的寬度是 2fr
,右邊軌道的寬度是 1fr
。咱們將左邊的軌道變成了一個具備兩欄的 multicol
容器。它一樣包含了一個跨欄元素。
在右邊,咱們將內容放入第二個 Grid
列軌道中。經過嘗試各類佈局方法,咱們能夠確切地找出適合手頭工做的佈局方法 - 不要懼怕混合搭配!
// 核心代碼 .container { max-width: 800px; margin: 0 auto; display: grid; grid-gap: 1em; grid-template-columns: 2fr 1fr; align-items: start; } .container article { column-count: 2; column-gap: 2em; column-rule: 1px solid #ccc; } .container aside { border-left: 1px solid #ccc; padding: 0 1em; }
若是您的內容中包含標題,您可能但願避免標題出如今列的末端,而內容卻出如今了下一列中。再好比,您的內容中有一些帶有文字說明的圖片,那麼理想的狀況下,圖片和他的文字說明,將保持一個總體展現,而不會被跨列分割。
當您將內容拆分爲列時,這種行爲被稱爲CSS片斷模塊(Fragmentation) 。將內容分割成兩頁進行展現,就好像打印機選擇兩欄的打印模式同樣。所以,相比較Web上的其餘佈局方法,multicol
是最接近Paged Media
的佈局方法。所以,咱們可使用屬於CSS2.1 的屬性 page-break
來實現這一點。
page-break-before
page-break-after
page-break-inside
最近,CSS片斷模塊規範定義瞭如何爲各類片斷模塊上下文設計的碎片化的屬性,規範包括 Paged Media
,multicol
和處於停滯狀態的區域樣式(Region Styling); 區域也會支持展現被分解(碎片化)連續的內容。經過使用這些通用屬性,它們能夠應用於任何將來的CSS片斷模塊上下文,就像 Flexbox
的對齊屬性被移動到 Box Alignment
規範中同樣,以便它們能夠在 Grid
和 Block
佈局中使用。
break-before
break-after
break-inside
下面的示例中,我在 <figure>
元素中使用 break-inside avoid
屬性,防止圖像的標題和圖像分離。支持該屬性的瀏覽器中,咱們應該能夠看到聯合在一塊兒的效果,即便這會致使列中的內容看起來不平衡。
// 核心代碼 figure { margin: 0; break-inside: avoid; } .container { max-width: 800px; margin: 0 auto; column-width: 14em; }
不幸的是,在 multicol
中對這些屬性的支持很是不完整。即便在支持的狀況下,它們也應該被視爲一個建議,由於在實際使用的時候,會提出不少要求來控制內容是否應該被分離,可是實際上瀏覽器並不會真正讓這些內容分離。在上面的示例中,咱們定義了展現的優先級,可是當您在使用的時候仍是要謹慎一些,僅在最須要的地方使用。
咱們在瀏覽網頁時,並無看到 multicol
被普遍的使用,其緣由是讀者的閱讀習慣,一般是自頂向下滾動閱讀的。對於使用英語,或其餘垂直寫做的人來講,橫向的佈局並非很好的閱讀體驗。
若是你固定容器的高度,例如使用 viewport
單位 vh
,當內容過多時,它會在內聯方向溢出,同時,你會獲得一個橫向的滾動條。
這些狀況都不是很理想。因此,在使用多列布局的時候,咱們須要仔細的考慮每一欄的內容量。
在 Level 2
的規範當中,咱們考慮如何使用一種方法,列的內容不會溢出,生成橫向的滾動條,而是在塊的方向上面生成新的列。這意味着您能夠擁有一個具備高度的 multicol
容器,而且一旦內容超出了該容器的寬度,就會在下面建立一組新的列。這看起來有點像咱們上面的跨越示例,可是,不是讓設置了column-span
的元素致使新的列框開始,而是由塊大小限制的容器寬度,從而解決溢出的問題。
此功能將使 multicol
對Web更有用。雖然咱們如今還有一段距離,但您能夠關注CSS工做組回購中的問題。若是您有此功能的其餘用例,請發佈它們,它在設計新功能時很是有用。
Multicol
?使用當前規範,不建議將全部內容拆分爲列而不考慮滾動問題。可是,在某些狀況下,multicol
對於 web
是理想的。在查看設計模式時,有足夠的示例k可供你參考。
multicol
能夠在任何須要佔用較少空間的項目列表的地方使用。例如,複選框的簡單列表或名稱列表。一般在這些狀況下,訪問者不會讀取一列而後返回到下一列的頂部,而是掃描內容以選中要單擊的複選框或要選擇的項目。即便您確實建立了滾動體驗,這個問題也依然存在。
您能夠在 DonarMuseum網站 上看到 Sander de Jong以這種方式使用的 multicol
示例。
有時,咱們設計一個網站,咱們知道某些內容區域相對較小,而且適合大多數屏幕展現,且不須要滾動。我在 Notist演示頁面 使用了 multicol
,用於介紹演講。
Andy Clarke爲 Equfund網站設計了一個可愛的例子。
爲了不很是小的屏幕致使頁面出現滾動,就像寬度同樣,您可使用媒體查詢來檢查高度。對於超出最小高度的內容,您能夠在斷點處設置 min-height
,來避免用戶使用較小設備時所帶來的較差體驗。
多列布局工做得很漂亮的另外一個地方是,若是要建立瀑布流的內容顯示。Multicol
是目前惟一一種,能夠建立不定高度的佈局方法。Grid
佈局要麼會留下間隙,要麼拉伸項目以造成嚴格的二維網格。
Veerle Pieters 有一個很好的例子,就是在她的靈感頁面上以這種方式使用multicol
。
這些 column-
屬性還能夠用做 Grid
和 Flex
佈局的備選方案。若是在容器上指定其中一個屬性,則使用 display: flex
或 display: grid
將刪除任何列行爲,將該容器轉換爲 Flex
或 Grid
佈局。例如,若是你有一個使用 Grid
佈局的卡片佈局,若是它在列中而不是在頁面上運行,那麼佈局就是可讀的,你可使用 multicol
做爲簡單的後備。不支持 Grid
的瀏覽器將得到 multicol
顯示,支持 Grid
的瀏覽器將得到 Grid Layout
。
我常常回答 Grid
和 Flexbox
的問題,答案是不使用 Grid
或 Flexbox
,而是試試 Multicol
。您可能不會在每一個站點上使用它,可是當您遇到本文中提到的場景時,它可能很是有用。在MDN上有關於 multicol和CSS片斷模塊的有用資源。
若是您在項目中有 multicol
的其餘使用場景,也歡迎留言分享!
本文已經聯繫原文做者,並受權翻譯,轉載請保留原文連接