CSS Podcast - 013: Spacing
假設您有三個盒子,每個盒子會疊放在一起,而且想在不同方塊之間留有間隔。你會用幾個 CSS 來達成這個目標?
margin
屬性「或許」能提供您所需的資訊,但也可能會加入不想要的間距。舉例來說,該如何只指定每個元素「之間」的空間?
gap
之類的類似範例可能更適合這種情況。目前有許多方法可在 UI 中調整間距,每個方法都有各自的優勢和注意事項。
HTML 間距
HTML 本身會提供一些間隔元素的方法。<br>
和 <hr>
元素可讓您按照區塊方向放置元素,如果使用拉丁式語言,則會由上到下。
如果您使用 <br>
元素,此元素就會建立換行符號,就如同在文書處理軟體中按下 Enter 鍵一樣。
<hr>
會建立水平線,並在兩側預留空間,稱為 margin
。
除了使用 HTML 元素之外,HTML 實體也可以建立空格。HTML 實體是保留的字元字串,瀏覽器會以字元實體取代。舉例來說,如果您在 HTML 檔案中輸入 ©
,該字元會轉換為 © 字元。
實體會轉換為非中斷空格字元,提供內嵌空間。但請小心,因為這個角色的非破壞性部分會將兩個元素拼接起來,導致奇怪的行為。
利潤
如要在元素外部新增空格,可以使用 margin
屬性。邊界就好比在元素周圍加上坐墊。margin
屬性是 margin-top
、margin-right
、margin-bottom
和 margin-left
的簡寫。
margin
簡寫會以特定順序套用屬性:頂端、右側、底部和左側。還記得以下問題:TRouBLe。
margin
簡寫也可以與 1、2 或 3 個值搭配使用。新增第四個值,即可個別設定每一面。套用方式如下:
- 系統會為所有邊套用一個值。(
margin: 20px
). - 兩個值:第一個值會套用到頂部和底部,第二個值將套用至左側和右側。(
margin: 20px 40px
) - 三個值:第一個值是
top
,第二個值是left
「和」right
,第三個值為bottom
。(margin: 20px 40px 30px
).
邊界可以使用長度、百分比或自動值,例如 1em
或 20%
。如果您使用百分比,系統會根據元素包含的區塊寬度計算這個值。
也就是說,如果元素所含區塊的寬度為 250px
,且元素的 margin
值為 20%
:元素每邊的計算邊界就會是 50px
。
您也可以將利潤的值設為 auto
。如果是設有大小限制的區塊層級元素,auto
邊界會以其套用方向佔用可用空間。就是來自 Flexbox 模組的一個好例子,其中的項目會彼此遠離。
auto
邊界的另一個優點是水平置中的包裝函式,寬度上限。這類包裝函式經常用於在網站上建立一致的中央欄。
.wrapper {
max-width: 400px;
margin: 0 auto;
}
在這裡,邊界會從頂部和底部 (區塊) 移除,auto
則在左側和右側 (內嵌) 之間共用空間。
負利潤
負值也可用於利潤。 這種做法不會在相鄰元素之間加入空間,而是會減少元素之間的空間。如果您宣告的負值超過可用空間,可能會導致元素重疊。
邊界收合
利潤收合是一項棘手概念,但這在建構介面時很常見。假設您有兩個元素,一個標題和一個段落都垂直邊界:
<article>
<h1>My heading with teal margin</h1>
<p>A paragraph of text that has blue margin on it, following the heading with margin.</p>
</article>
h1 {
margin-bottom: 2rem;
}
p {
margin-top: 3rem;
}
一開始,您可能會認為段落在標題中會加上 5em
間距,因為 2rem
和 3rem
會計算為 5rem
。由於垂直邊界會收合,但實際空間實際上是 3rem
。
邊界收合的原理是選取兩個相連元素的最大值,也就是在相鄰邊設定垂直邊界的最大值。h1
的底部與 p
的頂部相符,因此系統會選取 h1
底部邊界的最大值,以及 p
的上邊界。如果 h1
的底部邊界為 3.5rem
,兩者之間的空間會是 3.5rem
,因為大於 3rem
。只有區塊邊界收合,不收合內嵌 (水平) 邊界。
邊界收合也有助於空白元素。如果段落的上邊界為 20px
,則只會建立 20px
的空間,不會建立 40px
。不過,如果在這個元素內部新增任何內容 (包括 padding
),其邊界不會再收合,且會視為包含內容的方塊。
隨堂測驗
測驗您對邊際收合相關知識
如果兩個元素互相堆疊,且上邊界為 20 像素和底部邊界 30 像素,兩者之間應保留多少空間?
避免收合邊界
如果您將元素設為絕對位置,使用 position: absolute
時,邊界不會再收合。使用 float
屬性時,邊界也不會收合。
如果兩個具有區塊邊界的元素之間沒有邊界,邊界也不會收合,因為包含區塊邊界的兩個元素已不再相鄰,這些元素只是同層級。
在版面配置課程中,您已瞭解 Flexbox 和格線容器與區塊容器非常相似,但其子項元素的處理方式完全不同。這時邊界收合也同樣適用。
如果我們以課程中的原始範例為基礎,套用欄方向的 Flexbox,系統會合併邊界,而非收合。透過這種方式,您可以預測版面配置工作,也就是 Flexbox 和格線容器的設計。
邊界和邊界收合可能不太容易,但是瞭解其運作方式的詳盡來說非常實用,因此強烈建議使用這份詳細說明。
邊框間距
padding
屬性和 margin
一樣,不會在方塊外面建立空間,而是在方塊的「內部」建立空間,例如隔離。
視您使用的方塊模型 (我們在方塊模型課程中所述) 而定,padding
也會影響元素的整體尺寸。
padding
屬性是 padding-top
、padding-right
、padding-bottom
和 padding-left
的簡寫。和 margin
一樣,padding
也有邏輯屬性:padding-block-start
、padding-inline-end
、padding-block-end
和 padding-inline-start
。
位置
此外,在版面配置模組中一併介紹了,如果您將 position
的值設為 static
以外的任何內容,可以使用 top
、right
、bottom
和 left
屬性建立元素空間。這些方向值的行為有一些差異:
- 具有
position: relative
的元素即使設定這些值,仍會在文件流程中維持其位置。這些圖片也會與元素的位置相關。 - 具有
position: absolute
的元素會根據相對父項的位置設定方向值。 - 具有
position: fixed
的元素會以可視區域的基礎方向值為基礎。 - 設有
position: sticky
的元素只會在處於固定/停滯狀態時套用方向值。
在邏輯屬性模組中,您可以瞭解 inset-block
和 inset-inline
屬性,以便設定遵循寫入模式的方向值。
這兩個屬性都是合併 start
和 end
值的簡寫,因此可接受一個值要設為 start
和 end
,或有兩個個別值。
格線和 Flexbox
最後,在格線和 Flexbox 中,您可以使用 gap
屬性在子項元素「之間」建立空間。gap
屬性是 row-gap
和 column-gap
的簡寫,可接受一或兩個值,可以是長度或百分比。您也可以使用 unset
、initial
和 inherit
等關鍵字。
如果您只定義一個值,相同的 gap
就會同時套用至列和欄,但如果您同時定義這兩個值,第一個值是 row-gap
,第二個值為 column-gap
。
使用 Flexbox 和格線時,您也可以使用其分佈和對齊功能建立空間,詳情請參閱格線模組和 Flexbox 模組。
維持一致的間距
建議您選擇一個策略並堅持下去,有助於建立一致的使用者介面,讓這個介面的流暢度和節奏保持良好。為達成這個目標,建議你採用一致的測量間隔。
舉例來說,您可以致力使用 20px
做為元素之間所有落差 (稱為溝槽) 的一致測量結果,讓所有版面配置的外觀和風格一致。
您也可以決定使用 1em
做為流程內容之間的垂直間距,這樣就能根據元素的 font-size
達成一致的間距。無論您選擇哪種方式,都應將這些值儲存為變數 (或 CSS 自訂屬性),以便為這些值代碼化,讓一致性變得更簡單。
:root {
--gutter: 20px;
--spacing: 1em;
}
h1 {
margin-left: var(--gutter);
margin-top: var(--spacing);
}
使用這類自訂屬性即可定義一次,然後用於整個 CSS。無論是本機在元素內還是全域更新,這些值都會向下傳遞,並且反映更新的值。
隨堂測驗
測驗間距相關知識
遇到以下情況時,使用 HTML 做為間距是安全的做法...
如要在方塊「內」建立聊天室,請使用...
如要建立方塊「外」的空間,請使用...
如要在方塊「之間」建立空格,請使用...