版面配置

CSS Podcast - 009:版面配置

假設您是開發人員和設計師的同事 負責設計全新的網站此設計包含各種有趣的版面配置和組合:分別考量可視區域寬度和高度的雙維版面配置,以及需要順暢又彈性的版面配置。又是如何決定運用 CSS 設定樣式的最佳方式?

CSS 供應商提供多種解決版面配置問題的方法,例如水平軸、垂直軸,甚至兩者並用。為情境選擇合適的版面配置方法可能並不容易,而您通常需要多種版面配置方法才能解決問題。為協助您做到這一點,在下列模組中,您將瞭解每個 CSS 版面配置機制的獨特功能,並據此做出相關決策。

版面配置:簡短記錄

在網路早期,<table> 元素的設計比簡單的文件更複雜。2090 年代末期,瀏覽器開始廣泛採用 CSS 技術,因此區分 HTML 和視覺樣式變得更簡單。CSS 為開發人員開啟了大門,讓他們不必觸控 HTML 就能完全變更網站的外觀與風格。 這項新功能的設計靈感是 CSS Zen Garden,它旨在展現 CSS 的強大功能,鼓勵更多開發人員學習。

CSS 隨著我們對網頁設計和瀏覽器技術的需求不斷演進。 您可以參閱 Rachel Andrew 的文章,瞭解 CSS 版面配置和版面配置做法如何隨時間演變。

時間軸顯示 CSS 自 1996 年至 2021 年以來的演變情形

版面配置:現在和未來

現代 CSS 的版面配置工具功能更加強大。我們有專屬的版面配置系統,並且會先概略瞭解我們處理的內容,再在接下來的模組深入探討 Flexbox 和 Grid。

瞭解 display 屬性

display 屬性會執行兩項工作。首先,系統會判斷方塊套用的是內嵌或模塊。

.my-element {
  display: inline;
}

內嵌元素的運作方式與句子中的字詞相似。彼此位於內嵌方向中。根據預設,<span><strong> 等元素通常會為包含元素 (如 <p> (段落)) 內的文字片段設定樣式。同時也保留周圍的空白字元。

圖表顯示盒內各種不同大小的方塊,以及每個大小區段的開始與結束時間

您無法對內嵌元素設定明確的寬度和高度。周圍元素會忽略任何區塊層級邊界和邊框間距。

.my-element {
    display: block;
}

區塊元素不會彼此對齊。他們創造出新的線條。除非透過其他 CSS 程式碼變更,否則區塊元素會展開為內嵌尺寸的大小,因此在水平書寫模式中會橫跨整個寬度。系統會遵循區塊元素所有邊的邊界。

.my-element {
    display: flex;
}

display 屬性也會決定元素的子項的行為方式。舉例來說,將 display 屬性設為 display: flex,方塊就會成為區塊層級的方塊,也會將其子項轉換為彈性項目。如此一來,彈性屬性就能控制對齊、排序和流程。

Flexbox 和格線

主要的版面配置機制有兩種,分別為 flexboxgrid 建立版面配置規則。 兩者相似,但主要用於解決不同的版面配置問題。

Flexbox

.my-element {
    display: flex;
}

Flexbox 是一維版面配置的版面配置機制。在單一軸上 (水平或垂直) 版面配置。根據預設,Flexbox 會在內嵌方向中,將元素的子項彼此對齊,並往區塊方向延伸,因此兩者的高度相同。

項目不會沿著同一軸線顯示,空間不足時也不會換行。而會試著將兩者沿著同一行交叉。您可以使用 align-itemsjustify-contentflex-wrap 屬性變更這個行為。

Flexbox 也會將子項元素轉換為彈性項目,也就是說,您可以撰寫規則,規範其在 Flex 容器中的行為。您可以變更個別項目的對齊方式、順序和原因。 您也可以使用 flex 屬性來變更其縮小或擴充的方式。

.my-element div {
    flex: 1 0 auto;
}

flex 屬性是 flex-growflex-shrinkflex-basis 的簡寫。您可以展開上述範例,如下所示:

.my-element div {
 flex-grow: 1;
 flex-shrink: 0;
 flex-basis: auto;
}

開發人員提供這些低階規則,指示瀏覽器在受到內容和可視區域尺寸限制時應如何行為。因此,這對於回應式網頁設計而言是非常實用的機制。

格線

.my-element {
    display: grid;
}

格線在 Flexbox 的許多方面相似,但其旨在控制多軸的版面配置,而非單軸的版面配置 (垂直或水平空間)。

格線可讓您在含有 display: grid 的元素上編寫版面配置規則,並導入一些版面配置樣式的新基元,例如 repeat()minmax() 函式。fr 單位是實用的格線單位,這是剩餘空間的比例,您可以建構傳統的 12 欄格線,每個項目之間有 3 個 CSS 屬性:

.my-element {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1rem;
}

上例是單一軸版面配置。如果 Flexbox 主要將項目視為群組,網格則能讓您在兩個維度中精確控制項目的刊登位置。我們可以定義此格線中的第一個項目會佔用 2 列和 3 欄:

.my-element :first-child {
  grid-row: 1/3;
  grid-column: 1/4;
}

grid-rowgrid-column 屬性會指示格線中的第一個元素從第一個資料欄跨越至第四欄的開頭,接著從第一欄跨越至第三列。

流程版面配置

如果不是使用格線或 Flexbox,元素會以正常流程顯示。在正常流程中,您可以使用多種版面配置方法來調整項目的行為和位置。

內嵌區塊

還記得周圍元素如何不會遵循內嵌元素上的區塊邊界和邊框間距?使用 inline-block 時,您「可以」發生這種情況。

p span {
    display: inline-block;
}

使用 inline-block 可為您提供一個方塊,其中含有區塊層級元素的部分特性,但仍會內嵌於文字中。

p span {
    margin-top: 0.5rem;
}

浮動

如果您的圖片位於文字段落中,是否不適合將這類文字包裝在報紙圖片上?您可以用浮點值執行此操作。

img {
    float: left;
    margin-right: 1em;
}

float 屬性會指示元素根據指定方向「float」。本例中的圖片會指示向左浮動,以便同層元素「環繞」。您可以指示元素讓元素浮動 leftrightinherit

多欄版面配置

如果您的元素清單很長 (例如列出全球所有國家/地區的清單),可能會導致使用者「大量」捲動和浪費時間。或是在頁面上產生多餘的空白字元。 使用 CSS 多欄時,您可以將該欄位分割為多欄,以協助解決這兩個問題。

<h1>All countries</h1>
<ul class="countries">
  <li>Argentina</li>
  <li>Aland Islands</li>
  <li>Albania</li>
  <li>Algeria</li>
  <li>American Samoa</li>
  <li>Andorra</li>
  …
</ul>
.countries {
    column-count: 2;
    column-gap: 1em;
}

如此會自動將完整的清單分成兩欄,並在兩個資料欄之間加入間隔。

.countries {
    width: 100%;
    column-width: 260px;
    column-gap: 1em;
}

您也可以使用 column-width 定義所需的最小寬度,而不是設定內容分割的欄數。隨著可視區域中的可用空間增加,系統會自動建立更多欄。當空間減少時,資料欄也會縮減。這對回應式網頁設計來說非常實用。

位置

最後是版面配置機制總覽說明。position 屬性會變更元素在文件正常流程中的行為,以及元素與其他元素之間的關係。可用的選項包括 relativeabsolutefixedsticky,預設值為 static

.my-element {
  position: relative;
  top: 10px;
}

這個元素會根據元素在文件中的目前位置,向下移動 10 個像素。在元素中新增 position: relative,也會讓該元素成為任何具有 position: absolute 的子項元素區塊。這表示如果其子項已套用絕對位置,此特定元素現在會重新定位至該特定元素,而非最上層的父項。

.my-element {
  position: relative;
  width: 100px;
  height: 100px;
}

.another-element {
    position: absolute;
    bottom: 0;
    right: 0;
    width: 50px;
    height: 50px;
}

position 設為 absolute 時,元素會從目前的文件流程中分離出來。這意味著以下兩點:

  1. 您可以使用 toprightbottomleft (放在最接近的相對父項) 放置這個元素。
  2. 任何與絕對元素周圍的內容都會自動重排,以填滿該元素剩餘的剩餘空間。

position 值為 fixed 的元素運作方式與 absolute 類似,而父項是根層級的 <html> 元素。固定位置元素會根據您設定的 toprightbottomleft 值,從左上角固定。

您可以使用 sticky 實現 fixed 的固定式固定部分,以及 relative 的可預測文件流動性部分。只要使用這個值,當可視區域捲動經過元素時,該值就會固定在您設定的 toprightbottomleft 值上。

總結

CSS 版面配置有許多選擇和彈性。如要深入瞭解 CSS FlexboxGrid 的強大功能,請繼續收看接下來幾個單元。

隨堂測驗

測驗版面配置相關知識

display 屬性有什麼功用?

決定 inlineblocknone
版面配置引擎必須知道這個方塊是否為全寬度,且需要換行。
決定格線版面配置頁框。
顯示屬性可以設為格狀顯示,但與版面配置頁框無關。
決定子項的行為。
Flexbox 和 Flexbox 為孩子帶來評論和新功能。
決定方塊是否應捲動。
overflow 屬性。

如要將多個段落排入資料欄,最適合這項工作的 CSS 屬性為何?

display: grid
雖然格線可以把多個段落放入欄中,但這些欄應該是各自獨立的欄,不會依序排進下欄。
column-count
段落會從一欄的結尾不斷流動至下一欄的開頭,就和雜誌或報紙一樣。
display: flex
雖然 Flex 可以將多個段落放入欄中,但這些欄會是各自的欄,不需要像接下來的一樣流通。
float
請再試一次!

如果區塊超出流量,代表什麼意思?

它卡在河邊。
情境是 CSS,不是地理位置。
已經指定 topleft 排名值。
光是這些屬性並不會使流程跳出。
已經不再根據同層級位置放置。
舉例來說,含有 position: absolute 的方塊現在會根據內含的區塊以 x 和 y 座標定位,而不是以其他同層級元素的順序來定位。

Flexbox 和 Grid 預設會包裝子項?

必須選擇啟用 flex-wrap: wraprepeat(auto-fit, 30ch)
false
Flexbox 和 Grid 包含特殊包裝功能,需要採用其他樣式才能套用。