CSS 佈局入門

已發表: 2022-03-10
快速總結 ↬無論您是 CSS 新手,還是堆棧中其他地方的經驗豐富的開發人員,想要確保您今天對佈局的理解是最新的,本指南涵蓋了您今天需要了解的有關 CSS 佈局的所有信息。

在過去的幾年中,CSS 佈局以及我們開發網站前端的方式發生了巨大變化。 對於我們在 CSS 中使用的佈局方法來開發我們的網站,我們現在有了一個真正的選擇,這意味著我們經常需要選擇採用哪種方法。 在本文中,我將通過解釋它們的使用方式和用途的基礎知識來介紹您可以使用的各種佈局方法。

如果您是 CSS 新手並且想知道處理佈局的最佳方法是什麼,並且如果您是堆棧中其他地方的經驗豐富的開發人員,並且希望確保您今天對佈局的理解是最新的,那麼本指南適合您. 我沒有嘗試在這裡完整記錄每種佈局方法,因為那樣會創建一本書而不是一篇文章。 相反,我將概述您可以使用的內容,並提供大量鏈接以了解更多信息。

正常流量

如果您使用沒有應用 CSS 的 HTML 網頁來更改佈局,則元素將以正常流顯示。 在正常流程中,根據文檔的編寫模式,一個個顯示框。 這意味著,如果您有橫向書寫模式,其中句子從左到右或從右到左運行,正常流程將在頁面垂直向下一個接一個地顯示塊級元素的框。

跳躍後更多! 繼續往下看↓

如果您處於垂直寫作模式,那麼句子會垂直運行,因此正常流程會將塊水平放置。

顯示 Block Axis 在垂直書寫模式下是水平的,在水平書寫模式下是垂直的
塊和內聯方向隨書寫模式而變化

正常流程是您從任何佈局開始的地方:當您創建 CSS 佈局時,您正在獲取塊並導致它們執行與正常流程不同的操作。

構建文檔以利用正常流程

您可以通過確保文檔以結構良好的方式開始來利用正常流程。 想像一下,如果——而不是這種正常流程的概念——瀏覽器將你所有的盒子堆疊在一個角落裡,直到你創建了一個佈局。 這意味著您必須將每一件事都放在頁面上。 相反,瀏覽器以一種立即可讀的方式顯示我們的內容。

如果您的 CSS 無法加載,用戶仍然可以閱讀內容,而根本沒有獲得 CSS 的用戶(例如使用屏幕閱讀器的用戶)將按照文檔中的順序將內容交付給他們。 從可訪問性的角度來看,這使得您的 HTML 文檔以良好的順序開始生活很重要。 但是,它也將使您作為 Web 開發人員的生活更輕鬆。 如果您的內容按照用戶期望的順序閱讀,則無需對佈局進行大量更改即可將其放置在正確的位置。 使用更新的佈局方法,您可能會驚訝於您需要做的事情是如此之少。

因此,在考慮佈局之前,請考慮文檔結構以及您希望從文檔頂部到底部讀取內容的順序。

遠離正常流量

一旦我們有了一個結構良好的文檔,我們就需要決定如何把它變成我們想要的佈局。 對於我們文檔的部分內容,這將涉及遠離正常流程。 我們有一整套佈局方法可供使用。 我們要看的第一個方法是float ,因為 float 很好地展示瞭如何將元素從正常流中取出。

花車

浮動用於將框向左或向右移動,允許內容圍繞它顯示。

為了使項目浮動,請使用 CSS 屬性float和 left 或 right 值。 浮動的默認值為無。

 .item { float: left; }

值得注意的是,當您浮動一個項目並且文本環繞它時,會發生該內容的行框被縮短。 如果您浮動一個項目並且包含您的文本的以下框應用了背景顏色,您可以看到該背景顏色將在浮動項目下方運行。

一個向左浮動的塊,其右側文本的背景色在該塊下方運行
內容上的背景顏色在浮動下運行

當您縮短行框以便在浮動和換行文本之間留出空間時,您必須在浮動項目上設置邊距。 文本上的邊距只會將文本從容器邊緣移入。 對於向左浮動的圖像,您將在右側和底部添加邊距,假設您希望圖像與容器的頂部和左側齊平。

請參閱 CodePen 上的 Rachel Andrew (@rachelandrew) 的 Pen Smashing Guide to Layout:float。

請參閱 CodePen 上的 Rachel Andrew (@rachelandrew) 的 Pen Smashing Guide to Layout:float。

清除浮動

浮動元素後,以下所有元素將環繞該浮動元素,直到它們環繞在下方並繼續正常流動。 如果你想防止這種情況,你需要清除浮動。

在要在浮動後開始顯示的元素上,添加值為 left 的屬性clear以指示清除向左浮動的項目,使用 right 以清除向右浮動的項目,或同時清除任何浮動項目。

 .clear { clear: both; }

如果您希望元素在浮動之後開始,則上述方法有效。 如果您發現自己處於一個盒子裡有一個浮動項目並且旁邊有一些文本的情況,這將無濟於事。 如果文本比浮動項短,則框將繪製在內容下方並忽略浮動。 正如我們已經了解到的,浮動縮短了行框,佈局的其餘部分繼續正常流動。

浮動框從容器底部伸出
文本周圍的框不清除浮動

為了防止這種情況,我們需要清除盒子裡的東西。 我們可以添加一個空元素並將其設置為全部清除。 這涉及將空 div 粘貼到我們的文檔中,這並不理想,如果您的頁面是由 CMS 生成的,則可能無法實現。 因此,典型的清除浮動方法是所謂的清除修復黑客。 此方法通過添加 CSS 生成的內容並將其設置為清除兩者來工作。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: clearfix。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: clearfix。

塊格式化上下文

清除框內浮動的另一種方法是調用容器上的塊格式化上下文 (BFC)。 塊格式化上下文包含其中的所有內容,其中包括無法再從盒子底部伸出的浮動項目。 有幾種方法可以強制執行 BFC,最常見的清除浮點數的方法是將溢出屬性設置為具有默認可見以外的值。

 .container { overflow: auto; }

以這種方式使用溢出通常會起作用,但是,在某些情況下,您最終可能會在項目上出現剪切陰影或不需要的滾動條。 它在你的樣式表中也可能看起來有點混亂:你設置溢出是因為你想要滾動條還是只是為了獲得這種清除能力?

為了使意圖更清晰並防止創建 BFC 導致不必要的副作用,您可以使用flow-root作為display屬性的值。 display: flow-root唯一要做的就是創建一個 BFC,從而清除您的浮點數而不會引起其他問題。

 .container { display: flow-root; }

浮點數的傳統用法

在新的佈局方法出現之前,浮動被用來創建列佈局,這種技術通過給一組項目一個寬度並將它們設置為彼此相鄰浮動來工作。 仔細管理這些浮動框的百分比大小可能會產生網格效果。

我不建議現在開始新設計並使用這種方法。 但是,它將在未來許多年內保留在現有站點中。 因此,如果您遇到幾乎所有東西似乎都是浮動的設計,這就是正在使用的技術。

關於浮動和清除浮動的資源和進一步閱讀

  • “Clearfix:強制元素自行清除其子級,” Chris Coyier,CSS-Tricks
  • float ”,CSS:層疊樣式表,MDN 網絡文檔
  • clear ”,CSS:層疊樣式表,MDN 網絡文檔
  • “理解 CSS 佈局和塊格式化上下文”,Smashing Magazine 的 Rachel Andrew

定位

要從正常流程中移除元素或將其從正常流程中的位置移動,您可以使用 CSS 中的position屬性。 在正常流程中,元素的positionstatic 。 這些項目在塊維度中一個接一個地顯示,如果您滾動頁面,它們會隨之滾動。

在更改位置值時,您通常還會使用偏移值從特定參考點移動框。 使用的參考點取決於您使用的位置值。

相對定位

如果一個項目有position: relative那麼參考點是它通常在正常流程中的位置。 然後,您可以使用屬性topleftbottomright的偏移值來將框從通常顯示的位置移動。

 .item { position: relative; bottom: 50px; }

請注意,頁面上的其他項目不會響應您元素的新位置。 它在正常流程中的位置是保留的,因此您需要自己管理任何重疊。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:相對定位。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:相對定位。

絕對定位

在項目上設置position: absolute ,它將完全從正常流程中刪除。 留給它的空間將被刪除。 然後該項目將相對於它的包含塊定位,除非它嵌套在另一個定位元素中,否則它將是視口。

因此,如果您在一個項目上設置position: absolute ,首先會發生的事情是它通常最終會卡在視口的頂部和左側。 然後,您可以使用屬性topleftbottomright的偏移值將框從該位置移動到您想要的位置。

 .item { position: absolute; top: 20px; right: 20px; }

通常你不希望盒子根據視口定位,但參考包含元素,它在裡面。 在這種情況下,您需要給該包含元素一個位置值,而不是默認的靜態值。

設置position: relative不會從正常流程中刪除項目,這是通常的選擇。 給父元素您希望從position: relative ,然後從該元素的邊界偏移絕對定位的塊。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:絕對定位。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:絕對定位。

固定定位

在大多數情況下,帶有position: fixed的東西會相對於視口定位,並從文檔流中移除,這樣就不會為其保留空間。 當頁面滾動時,固定元素保持相對於視口的位置,因為正常流程中的其餘內容照常滾動。

 .item { position: fixed; top: 20px; left: 100px; }

這有助於啟用固定在屏幕上的導航面板,例如在內容滾動時。 與其他定位值一樣,在執行此操作時可能會導致重疊,因此您應注意所有內容都可以讀取,並且不會出現在固定項目後面。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:Fixed position。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:Fixed position。

要定位固定項目而不是相對於視口,您需要有一個包含元素,其transformperspectivefilter屬性之一設置為默認值none以外的值。 在這種情況下,該元素將成為包含塊,並且您的偏移量與該塊相關,而不是視口。

粘性定位

設置position: sticky元素會導致元素像在正常流程中一樣隨著文檔滾動,但是,一旦它到達相對於視口的某個點(使用通常的偏移量),它就會“粘住”並開始表現得像position: fixed 。 這是一個較新的值,並且在瀏覽器中的支持不如其他方法,但是,它回退到僅使用頁面滾動 os 是一個很好地用作增強功能的值,如果不支持它不會導致問題。

 .item { position: sticky; top: 0; }

這是如何創建導航欄隨內容滾動然後在視口頂部停止以在滾動內容時停留在屏幕上的流行效果的方法。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:粘性定位。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:粘性定位。

關於定位的資源和進一步閱讀

  • “定位”,MDN 學習區,MDN 網絡文檔,Mozilla
  • position: sticky; ,” Chris Coyier,CSS 技巧
  • “CSS position:sticky”,瀏覽器對粘性定位的支持信息,caniuse

彈性佈局

彈性盒佈局(Flexbox)是一種專為一維佈局而設計的佈局方式。 一維意味著您希望將內容佈置成一行或一列。 要將元素轉換為 flex 佈局,請使用值為flexdisplay屬性。

 .container { display: flex; }

該元素的直接子元素成為彈性項目,它們將排列成一行,與內聯方向的起始邊緣對齊。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex。

Flexbox 的軸心

在上面的示例中,我將項目描述為在行內方向上與行的起始邊緣對齊,而不是將它們描述為與左側對齊。 我們的項目排成一行,因為flex-direction屬性的默認值為row ,這會在行內方向創建一行,即句子運行的方向。 由於我們使用的是英語,一種從左到右的語言,一行的開始在左邊,所以我們的項目從那裡開始。 因此flex-direction的值定義了 Flexbox 的主軸

因此,交叉軸以直角穿過主軸。 如果您的 flex-direction 是row並且您的項目以 inline 方向顯示,則您的交叉軸在 Block 方向上運行。 如果您的flex-directioncolumn ,因此項目在 Block 方向上運行,那麼您的橫軸沿行。

如果您在使用 Flexbox 時習慣於考慮主軸和交叉軸,它會讓很多事情變得更容易。

方向與秩序

Flexbox 使您能夠通過使用flex-directionrow-reversecolumn-reverse來更改主軸上項目的方向。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex-direction。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex-direction。

您還可以使用order屬性更改單個彈性項目的順序。 但是,這樣做時您應該非常小心,因為這可能會給使用鍵盤而不是鼠標或觸摸屏導航的任何用戶帶來問題,因為文檔的 Tab 鍵順序將遵循源中內容的順序。 有關更多詳細信息,請參閱下面的視覺和文檔順序部分。

彈性屬性

flex 屬性是如何控制 flex 項目沿主軸的比率。 這三個屬性是:

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

這些通常以flex屬性的簡寫形式使用,第一個值是flex-grow ,第二個是flex-shrink ,第三個是flex-basis

 .item { flex: 1 1 200px; }

flex-basis的值給出了項目在任何增長或收縮發生之前將具有的大小。 在上面的例子中,這個大小是 200 像素,所以我們會給每個項目 200 像素的空間。 我們的容器不太可能整齊地除以 200 像素,因此如果每個項目都有 200 像素,那麼所有項目都會有剩餘空間或沒有足夠的空間。 flex-growflex-shrink屬性允許我們控制項目在空間過多或不足時會發生什麼。

如果flex-grow設置為任何正值,則允許項目增長以佔用空間。 因此,在我們上面的示例中,在給每個項目 200 像素之後,任何額外的空間都將在項目之間共享。

如果flex-shrink設置為正值,那麼如果所有項目都被賦予了flex-basis ,則項目可以在發生溢出的情況下收縮。 如果在我們的示例中容器中沒有足夠的空間,則每個項目將縮小等量以減少,直到所有項目都可以放入容器中。

flex-growflex-shrink值可以是任何正值。 具有較大flex-grow值的項目將在增長時按比例分配更多可用空間,而具有較大flex-shrink值的項目將在收縮時移除更多空間。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex properties。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex properties。

了解這些 flex 屬性的工作方式確實是了解 Flexbox 的關鍵,下面列出的資源將為您提供所有詳細信息。 但是,當您有一堆東西要在一個維度中拉伸和擠壓到容器中時,請考慮使用 Flexbox。 如果您發現自己試圖按行和列排列,那麼您需要一個 Grid,在這種情況下 Flexbox 可能不是這項工作的工具。

Flex 佈局的資源和進一步閱讀

  • “CSS 靈活框佈局”,規範的完整指南,MDN 網絡文檔,Mozilla
  • “Flexbox 完整指南”,Chris Coyier,CSS-Tricks
  • 《Flexbox Froggy》,一款學習 Flexbox 的遊戲
  • “Flexbugs”,一個社區策劃的與 Flexbox 相關的瀏覽器錯誤列表

網格佈局

CSS Grid Layout 被設計為一種二維佈局方法。 二維意味著您希望將內容佈置在行和列中。 與 Flexbox 一樣,網格佈局是display的值,因此要開始使用 Grid,您應該從容器上的display: grid開始,然後使用grid-template-columnsgrid-template-rows設置一些列和/或行grid-template-rows屬性。

 .container { display: grid; grid-template-columns: 200px 200px 200px; grid-template-rows: 200px 200px; }

上面的 CSS 將創建一個固定大小的網格,具有完全固定的列和行軌道。 這可能不是您在網絡上想要的,而 Grid 為您提供了很好的解決方案。 任何軌道的默認值都是auto ,通常可以認為是“足夠大的內容”。 如果我們沒有創建任何行軌道,那麼將為我們創建行以獲取添加的任何內容,並且這些行將auto調整大小。 一種常見的模式是指定列軌道,但允許 Grid 根據需要創建行。

雖然您可以使用任何長度單位或百分比設置列和行軌道,但您也可以使用新的fr單位,這是為網格佈局創建的單位。 fr單元是一個彈性單元,表示網格容器中可用空間的份額。

網格可以為你分配空間; 您無需計算百分比即可確保物品適合容器。 在下面的示例中,我們使用fr單位創建列並允許自動創建軌道。 我們還使用grid-gap來分隔我們的軌道(有關間隙和網格佈局的更多詳細信息,請參見 Box Alignment 部分)。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:一個簡單的網格。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:一個簡單的網格。

與 Flexbox 和flex-growflex-shrink一樣, fr單元處理共享可用空間。 一個軌道的較高fr值意味著它按比例獲得更多可用空間。 您還可以混合fr單位和絕對長度。 在計算fr單位之前,將從可用空間中減去長度所需的空間。

請參閱 CodePen 上的 rachelandrew (@rachelandrew) 的 Pen Smashing Guide to Layout:fr 單位和絕對長度。

請參閱 CodePen 上的 rachelandrew (@rachelandrew) 的 Pen Smashing Guide to Layout:fr 單位和絕對長度。

網格術語

Grid 始終有兩個軸:Inline Axis 沿文字在頁面上的佈局方向運行,而 Block Axis 沿塊的佈局方向運行。

Grid Container 是您設置display: grid on 的元素。 然後,您就有了網格線,由您在使用grid-template-columnsgrid-template-rows時指定的列和行軌道創建。 網格上的最小單位(在四條相交的線之間)稱為網格單元,而構成完整矩形的網格單元的集合稱為網格區域。

圖像顯示了突出顯示列和行線的網格
網格線在網格的每個軌道之間運行。
圖像顯示了在網格上突出顯示的列軌道
網格軌道位於任意兩條線之間
圖像顯示了一個網格,其中包含多個單格區域和一個跨兩行兩列的區域。
網格單元是網格上的最小單位,一個網格區域是一個或多個單元共同構成一個矩形區域

網格自動放置

一旦你創建了一個網格,你的網格容器的直接子元素就開始佈置自己,在網格的每個單元格中都有一個。 他們根據網格自動放置規則執行此操作。 這些規則確保每個項目都放置在一個空單元格中,避免項目重疊。

根據自動放置規則放置網格容器的任何您未指定位置的直接子項。 在下面的示例中,我已使每第三個項目跨越兩行軌道,同時仍根據起始線自動放置。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: auto-placement。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: auto-placement。

基本的基於行的定位

在網格上定位項目的最簡單方法是使用基於行的定位,給項目規則以告訴它從網格的一條線跨越到另一條線。 例如,如果我有一個包含三個列軌道和兩行軌道的網格,我可以將一個項目從第 1 列到第 3 列,從第 1 行到第 3 行。然後它將總共覆蓋四個網格單元,跨越兩個列軌道和兩個列行。

 .item { grid-column-start: 1; grid-column-end: 3; grid-row-start: 1; grid-row-end: 3; }

這些屬性可以表示為速記、 grid-columngrid-row ,第一個值是start ,第二個是end

 .item { grid-column: 1 / 3; grid-row: 1 / 3; }

網格項目可以佔據相同的單元格,從而可以創建具有重疊內容的設計。 項目以內容在網絡上堆疊的通常方式堆疊,降低源的項目出現在其他項目的頂部。 不過,您可以使用z-index來控制它。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:基於行的放置。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:基於行的放置。

使用命名區域定位

您還可以使用命名區域在網格上定位項目。 要使用此方法,您需要為每個項目命名,然後將佈局描述為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: "aabb" "aacc"; }

使用此方法時需要記住一些規則。 如果您希望一個項目跨越多個單元格,那麼您應該重複該名稱。 區域需要形成一個完整的矩形,不允許 L 形或俄羅斯方塊! 網格必須是完整的——必須填充每個單元格。 如果您想留下空白,請用 . 填充該單元格. . 例如,在下面的 CSS 中,我將右下角留空。

 .container { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-areas: "aabb" "aac ."; }

這是一種很好的工作方式,因為任何查看 CSS 的人都可以準確地看到佈局將如何工作。

請參閱 CodePen 上 rachelandrew (@rachelandrew) 的 Pen Smashing Guide to Layout: grid-template-areas。

請參閱 CodePen 上 rachelandrew (@rachelandrew) 的 Pen Smashing Guide to Layout: grid-template-areas。

網格佈局的資源和進一步閱讀

CSS 網格佈局比這個快速概述分享的要多得多,下面的資源將幫助您學習規範。 組件和您的整個頁面佈局都可以是網格,如果您要創建二維佈局,請選擇網格佈局 - 無論大小。

  • “CSS 網格佈局”,面向開發人員的 Web 技術,MDN 網絡文檔,Mozilla
  • “示例網格”,學習 CSS 網格佈局所需的一切,Rachel Andrew
  • “Grid Garden”,一款有趣的互動遊戲,用於測試和提高您的 CSS 技能
  • “佈局土地”,YouTube 的 Jen Simmons

我還在 Smashing Magazine 上寫了許多文章,可以幫助您深入了解各種網格概念:

  • “CSS 網格佈局的最佳實踐”
  • “使用生成的內容和 CSS 網格佈局為空單元格設置樣式”
  • “使用 CSS 網格:支持沒有網格的瀏覽器”
  • “CSS 網格陷阱和絆腳石”
  • “在 CSS 網格佈局中命名事物”

視覺和文件順序

在本文的開頭,我建議您以從上到下的順序閱讀文檔,因為這對可訪問性和 CSS 佈局的工作方式都有幫助。 從我們對 Flexbox 和 CSS Grid 的簡短介紹中,您可以看到可以將事物從該順序中大大改變。 這有可能導致問題。

瀏覽器將遵循文檔源以對文檔進行任何非可視化使用。 因此,屏幕閱讀器將讀出文檔順序,任何使用鍵盤導航的人都將按照文檔在源中的順序而不是顯示順序來瀏覽文檔。 許多屏幕閱讀器用戶並非完全失明,因此可能在使用屏幕閱讀器的同時能夠看到他們在文檔中的位置。 對於這兩種情況,與源相比混亂的顯示確實會導致非常混亂的情況。

當您從源中的順序移動元素時要非常注意。 如果你發現自己在 CSS 中重新排列項目的順序,你真的應該回去重新組織你的文檔嗎? 測試您是否仍然可以在文檔周圍使用標籤,並且視覺順序是否有意義。

視覺和文檔順序的資源和進一步閱讀

  • “CSS 網格佈局和可訪問性”,面向開發人員的 Web 技術,MDN 網絡文檔,Mozilla
  • “HTML 源順序與 CSS 顯示順序”,Adrian Roselli
  • “Flexbox 和鍵盤導航斷開連接”,Code Things,Tink
  • “鍵盤焦點的響應順序衝突,”阿拉斯泰爾坎貝爾

盒子生成

您在網頁上放置的所有內容都會創建一個盒子,本文中的所有內容都描述瞭如何在設計中使用 CSS 來佈局這些盒子,但是,在某些情況下,您可能根本不想創建一個盒子。 display屬性有兩個值用於處理不需要框的情況。

不生成框或內容( display: none

如果您希望不生成該元素和該元素的所有內容,包括任何子項,您可以使用display: none 。 該元素現在將不會顯示,並且不會為它本來的位置保留空間。

 .item { display: none; }

不生成此元素,但生成任何子元素( display: contents

display 的更新值是display display: contents 。 將display: contents應用於元素,不會生成該元素的框,但將正常生成任何子元素。 如果您希望間接子元素成為彈性或網格佈局的一部分,這會很有幫助。

在下面的示例中,第一個 flex 項包含兩個嵌套的子項,但它設置為display: contents ,它的盒子沒有被租用,子項顯示為好像它們是直接子項並成為 flex 項。 從該元素中刪除display: contents以查看佈局如何更改。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: display: contents。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: display: contents。

盒子生成的資源和進一步閱讀

  • “帶display: contents ”,雷切爾·安德魯
  • 如何display: contents; 作品,”Ire Aderinokun,
  • CSS display: contents ,”瀏覽器支持信息, caniuse

結盟

直到最近,對齊一直是網絡上的一個棘手主題,正確對齊框內項目的方法非常有限。 盒子對齊模塊正在改變這一點,目前您將在控制 Grid 和 Flex 容器中的對齊時使用該模塊。 未來,其他佈局方法也將實現這些對齊屬性。 Box Alignment 規範中詳述的對齊屬性列表如下:

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

由於佈局模型具有不同的功能,對齊的工作方式會根據使用的佈局模型略有不同。 讓我們看看對齊如何與一些簡單的 Grid 和 Flex 佈局一起工作。

align-itemsjustify-items屬性將align-selfjustify-self屬性設置為一個組。 這些屬性在它們的網格區域內對齊項目。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:align-items、justify-items、align-self、justify-self。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:align-items、justify-items、align-self、justify-self。

align-contentjustify-content屬性對齊網格軌道,其中網格容器中的空間比顯示軌道所需的空間多。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:align-content, justify-content。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout:align-content, justify-content。

在 Flexbox 中, align-itemsalign-self處理 Cross Axis 上的對齊,而justify-content處理主軸上的空間分佈。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: Flex justify-content, align-items, align-self。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: Flex justify-content, align-items, align-self。

在橫軸上,您可以使用align-content來包裹 flex 線和 flex 容器中的額外空間。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex align-content。

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: flex align-content。

See the resources for some links that discuss Box Alignment in detail across layout methods. It really is worth spending some time understanding how alignment works, as it will make working with Flexbox, Grid and future layout methods far easier.

Row And Column Gaps

A multiple-column layout has the column-gap property, and the Grid Layout spec had — until recently — the properties grid-column-gap , grid-row-gap , and grid-gap . These have now been removed from the Grid specification and added to Box Alignment. At the same time, the grid- prefixed properties were renamed to column-gap , row-gap , and gap . Browsers will alias the prefixed properties to the new renamed ones so you do not need to worry if you are using the better supported old names in your code right now.

The renaming means that these properties can be also applied to other layout methods, the obvious candidate being Flexbox. While no browser supports gaps in Flexbox at the moment, in future we should be able to use column-gap and row-gap to create space between flex items.

Resources And Further Reading For Alignment

  • “CSS Box Alignment,” CSS: Cascading Style Sheets, MDN web docs, Mozilla
  • “Box Alignment in Flexbox,” CSS Flexible Box Layout, MDN web docs, Mozilla
  • “Box Alignment in CSS Grid Layout,” CSS Grid Layout, MDN web docs, Mozilla
  • “The New Layout Standard For The Web: CSS Grid, Flexbox And Box Alignment,” Rachel Andrew, Smashing Magazine
  • “Box Alignment Cheatsheet,” Rachel Andrew

Multi-Column Layout

A multiple-column layout is a layout type that enables the creation of columns, such as you might find in a newspaper. A block is split into columns, and you read down a column in the block direction then return to the top of the next column. While reading content in this way is not always useful in a web context as people don't want to have to scroll up and down to read, it can be a helpful way to display small amounts of content or to collapse down sets of checkboxes or other small UI elements.

A multiple-column layout can also be used to display sets of cards or products which have differing heights.

Setting A Column Width

To set an optimal column width, and instruct the browser to display as many columns as possible at that width use the following CSS:

 .container { column-width: 300px; }

This will create as many as 300 pixel columns as possible, any leftover space is shared between the columns. Therefore, unless your space divides into 300 pixels with no remainder, it is likely that your columns will be slightly wider than 300 pixels.

Setting A Number Of Columns

Instead of setting the width, you could set a number of columns using column-count . In this case, the browser will share the space between the number of columns you have asked for.

 .container { column-count: 3; }

If you add both column-width and column-count , then the column-count property acts as a maximum. In the below code, columns will be added until there are three columns, at which point any extra space will be shared between those three columns even if there was enough space for an additional column.

 .container { column-width: 300px; column-count: 3; }

Gaps And Column Rules

You cannot add margins or padding to individual column boxes, to space out columns use the column-gap property. If you do not specify a column-gap , it will default to 1em to prevent columns bumping up against each other. This is a different behavior to the way column-gap is specified for other layout methods, where it defaults to 0. You can use any length unit for your gap, including 0 if you want no gap at all.

The column-rule property gives you the ability to add a rule between two columns. It is a shorthand for column-rule-width , column-rule-color , and column-rule-style , and acts in the same way as border . Note that a rule does not take up any space of its own. It lays on top of the gap so to increase or decrease space between the rule and the content you need to increase or decrease the column-gap .

See the Pen Smashing Guide to Layout: multicol by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Smashing Guide to Layout: multicol by Rachel Andrew (@rachelandrew) on CodePen.

Allowing Elements To Span Columns

You can span an element inside the multicol container across all of the columns using the column-span property on that element.

 h3 { column-span: all; }

When a column-span happens, the multicol container essentially stops above the spanning element, therefore, the content forms into columns above the element and then remaining content forms a new set of column boxes below the spanning element.

See the Pen Smashing Guide to Layout: multicol span by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Smashing Guide to Layout: multicol span by Rachel Andrew (@rachelandrew) on CodePen.

You can only use column-span: all or column-span: none ; it isn't possible to span some of the columns. At the time of writing, Firefox does not support the column-span property.

Resources And Further Reading For Multiple-Column Layout

  • “Using Multi-Column Layouts,” CSS Multi-column Layout, MDN web docs, Mozilla

碎片化

Multiple-Column Layout is an example of fragmentation . In this case, the content is broken into columns. It is, however, very similar to the way that content is broken into pages when printing. This process is dealt with by the Fragmentation specification, and this specification contains properties to help control the breaking of content.

For example, if you have laid out a set of cards using multicol and you want to make sure that a card never breaks in half, becoming split between two columns you can use the property break-inside with a value of avoid . Due to browser compatibility reasons, you will also want to use the legacy page-break-inside property as well.

 .card { page-break-inside: avoid; break-inside: avoid; }

If you want to avoid a break directly after a heading, you can use the break-after property.

 .container h2 { page-break-after: avoid; break-after: avoid; }

These properties can be used when preparing a print stylesheet and also in multicol. In the example below, I have three paragraphs in a multicol container that fragments into three columns. I have given break-inside: avoid to the p element meaning that the paragraphs end up one in each column (even if this makes the columns uneven).

See the Pen Smashing Guide to Layout: multicol fragmentation by Rachel Andrew (@rachelandrew) on CodePen.

請參閱 Rachel Andrew (@rachelandrew) 在 CodePen 上的 Pen Smashing Guide to Layout: multicol fragmentation。

碎片化的資源和進一步閱讀

  • “2018 年打印樣式表狀態指南”,Smashing Magazine 的 Rachel Andrew
  • “分欄”,QuirksMode.org

選擇佈局類型:如何選擇?

大多數網頁將混合使用這些佈局類型,並且每個規範都準確定義了它們之間的交互方式。 例如,您可能有一個網格佈局,其中一些網格項目也是 Flex 容器。 其中一些彈性容器可能是定位項目的包含塊或內部浮動圖像。 編寫規範時期望我們將根據最適合我們佈局的內容混合佈局模型。 在本指南中,我試圖概述每種佈局類型的基本行為方式,以幫助您了解實現特定效果的最佳方式。

但是,不要害怕嘗試不同的方式來創建您想要的設計。 您應該擔心您的選擇會導致任何實際問題的地方比您想像的要少。 從良好的文檔結構開始,並註意不要將視覺顯示與該訂單斷開連接。 其餘大部分只是測試在目標瀏覽器中是否按預期工作的情況。