外邊界 margin
在網頁元素容器主體的外面,還有一層使用 margin 控制樣式的「外邊界」,這篇教學會介紹網頁元素的 margin,除了基本的單數值設定、多數值設定和長度單位,還會介紹 margin 重疊現象、可置換元素和不可置換元素使用 margin 時的細節差異。
請先閱讀:容器盒子模型 ( box Model )
快速導覽:
margin 撰寫語法
margin
是元素容器盒子模型裡的「外邊界」,也就是在網頁元素容器主體外面延伸出去的空間,W3C 為了避免網頁元素出現時太過緊密,許多元素都有外邊界 margin
預設值,因此就算不做任何設定,元素之間也會按照預設值互相撐開。
由於各個元素預設值都太相同,詳細參考「HTML 教學」,從左側選單選擇元素查看預設值。
如果要調整外邊界,需要使用下列幾種撰寫語法修改數值,數值的位置對應不同方向的外邊界 ( margin 沒有繼承特性 ):
語法 | 說明 |
---|---|
margin: 上 右 下 左; |
空白分隔「四個」數值,分別設定四個方向的外邊界。 |
margin: 上 (左右) 下; |
空白分隔「三個」數值,分別設定上、下和左右外邊界,左右的數值相同。 |
margin: (上下) (左右); |
空白分隔「二個」數值,分別設定上下和左右外邊界,上下的數值相同,左右的數值相同。 |
margin: (上下左右); |
一個數值,上下左右外邊界數值相同。 |
下方的範例使用五個 div 呈現不同的 margin
的寫法,div 裡會放入另一個 em,並設定該 div 的外邊界。
<!-- HTML 程式碼 -->
<div><div>預設值</div></div>
<div><div class="a">margin: 20px 15px 10px 5px;</div></div>
<div><div class="b">margin: 20px 10px 5px;</div></div>
<div><div class="c">margin: 20px 5px;</div></div>
<div><div class="d">margin: 20px;</div></div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
background: orange;
width: max-content; /* 讓內容撐開 */
margin: 10px;
}
div div {
display: block;
width: 240px;
height: 30px;
border: none;
background: yellow;
}
.a {margin: 20px 15px 10px 5px;}
.b {margin: 20px 10px 5px;}
.c {margin: 20px 5px;}
.d {margin: 20px;}
</style>
margin-* 單一外邊界
除了一次設定四個方向的 margin
數值,也可以透過單一外邊界的樣式屬性,單獨設定上下左右數值。
單一外邊界樣式 | 說明 |
---|---|
margin-top |
上方外邊界 |
margin-right |
右側外邊界 |
margin-bottom |
下方外邊界 |
margin-left |
左側外邊界 |
單一外邊界的權重與 margin
相同,有時會運用「撰寫順序」來覆寫特定方向的外邊界,下方的範例先將 div 的 margin
統一設定為 10px,再運用單一外邊界調整特定方向的寬度。
<!-- HTML 程式碼 -->
<div><div class="a">margin-top: 30px;</div></div>
<div><div class="b">margin-right: 30px;</div></div>
<div><div class="c">margin-bottom: 30px;</div></div>
<div><div class="d">margin-left: 30px;</div></div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
background: orange;
width: max-content;
margin: 10px;
}
div div {
display: block;
width: 240px;
height: 30px;
border: none;
background: yellow;
margin: 10px; /* 四個方向的外邊界都是 10px */
}
.a {margin-top: 30px;}
.b {margin-right: 30px;}
.c {margin-bottom: 30px;}
.d {margin-left: 30px;}
</style>
margin 使用的長度單位
margin
使用的數值需要具有「長度單位」,支援相對長度和絕對長度,數值「可以負值」,長度單位如下表所示:
延伸閱讀:長度與角度單位
長度單位 | 性質 | 說明 |
---|---|---|
auto 或不設定 | - | 採用元素預設外邊界值。 |
px | 絕對長度 | 像素。 |
% | 相對長度 | 父元素內容寬度的百分比。 |
em | 相對長度 | 元素本身字體大小的幾倍。 |
rem | 相對長度 | 根元素字體大小的幾倍。 |
pt、cm、mm、in | 絕對長度 | 印刷單位。 |
下方的範例使用不同長度單位設定元素的外邊界值,注意 margin
就算是設定上下的數值,使用百分比為單位時,仍然是採用「父元素內容寬度」進行計算。
<!-- HTML 程式碼 -->
<div><div class="a">margin: 10px;</div></div>
<div><div class="b">margin: 0.5em;</div></div>
<div><div class="c">margin: 3rem;</div></div>
<div><div class="d">margin: 10%;</div></div>
<!-- CSS 程式碼 -->
<style>
:root {font-size: 10px;} /* 根元素字型大小 10px */
div {
border: 1px solid #000;
background: orange;
width: 300px; /* 父元素寬度 300px */
margin: 10px;
}
div div {
font-size: 20px; /* 元素本身字型大小 20px */
display: block;
width: 240px;
height: 30px;
border: none;
background: yellow;
}
.a {margin: 10px;} /* 絕對長度 10px */
.b {margin: 0.5em;} /* 20px x 0.5 = 10px */
.c {margin: 3rem;} /* 10px x 3 = 30px */
.d {margin: 10%;} /* 300px x 10% = 30px */
</style>
除了使用單一種長度單位,margin
也支援多種長度單位混合使用,或使用 calc() 等 CSS 函式去計算長度,下方範例同時使用了四種不同長度單位呈現方式。
<!-- HTML 程式碼 -->
<div><div>margin: 10px 1em 1rem calc(10px * 5);</div></div>
<!-- CSS 程式碼 -->
<style>
:root {font-size: 50px;}
div {
border: 1px solid #000;
background: orange;
width: max-content;
margin: 10px;
}
div div {
font-size: 14px;
display: block;
width: 260px;
height: 30px;
border: none;
background: yellow;
margin: 5px 1em 1rem calc(10px * 5);
}
</style>
margin 設定負值
margin
可以設定「負值」,當數值為負值時,就會產生「內縮到元素裡」的負向外邊界,有時會透過負向外邊界讓元素內縮或與其他元素重疊在一起,實現網頁排版的特殊效果,下方的範例會透過負值的 margin
,將 div 重疊在一起 ( 每個 div 都把 margin-bottom
設為 0,避免向下邊界的推開下方元素 )。
<!-- HTML 程式碼 -->
<div></div>
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
width: 100px;
height: 100px;
background: orange;
}
.a {
margin: -60px 30px 0;
background: #f003;
}
.b {
margin: -60px 60px 0;
background: #0f05;
}
.c {
margin: -60px 10px 0;
background: #00f5;
}
</style>
margin 邊界重疊特性
margin
有一個很重要的特性,叫做「邊距重疊 Collapsing margins」,意思是如果有兩個或多個元素 垂直擺放,就會發生「多個外邊界自動組合成單一個邊界」的行為,這種方式組生成的外邊界稱為重疊邊界,重疊邊界會採用「最大的 margin
值」。
下方範例的畫面中有三個 div 元素,雖然設定了 margin: 10px;
,但可以看出因爲重疊邊界的緣故,兩個 div 之間的間距還是保持 30px,而不是兩兩相加的 60px。
<!-- HTML 程式碼 -->
<div></div>
<div></div>
<div></div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 30px;
margin: 30px;
background: #f005;
}
</style>
此外,如果元素本身高度為 0 或 auto ( 包含邊框與 padding
),則會發生「margin
無效」的狀況,從下方的例子可以看出來,因為第二個 div p 爲高度是 0,所以 margin
上下重疊後又與前後元素重疊,最後變成只有 30px 間距的狀況,而其他高度為 0 的 div 因為有設定邊框或 padding
,就不會發生 margin
無效的狀況。
<!-- HTML 程式碼 -->
<div></div>
<div class="a"></div>
<div></div>
<div class="b"></div>
<div></div>
<div class="c"></div>
<div></div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 30px;
margin: 30px;
background: #f005;
}
.a {
height: 0;
}
.b {
padding:1px;
height: 0;
}
.c {
border: 1px solid #000;
height: 0;
}
</style>
這種邊界重疊現象不只發生在「兄弟元素」,在「父子元素」的結構更為明顯,下方的範例位於子元素的 div 不僅沒有保持和父元素的外邊界,甚至因為發生了外邊界重疊,造成父元素與其他元素的邊界值變成了子元素的 50px ( 因為子元素的 margin
值較大 )
<!-- HTML 程式碼 -->
<div>
<div></div>
</div>
<div>
<div></div>
</div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 50px;
margin: 10px;
background: #f005;
}
div div {
margin: 50px;
background: #00f5;
}
</style>
不會發生邊界重疊的狀況
雖然元素會發生 margin
外邊界重疊,但下列幾種情況「不會發生外邊界重疊」:
- 水平的外邊界不會重疊。
- 父元素
- 父元素有設定
padding
或border
,「父子元素」不會重疊。- 父元素的
display
屬性是inline-*
、flex
、grid
、table
、table-*
、flow-root
。- 元素本身
- 元素的
display
屬性是inline-block
、table-caption
。- 元素的
position
樣式使用absolute
或fixed
。- 元素之間穿插了非區塊容器元素,例如
inline
、table
...等。
下方範例展示父元素設定了 padding
和 border
後,margin
不會重疊的狀況,從中也可以發現,垂直的外邊界會重疊,但水平的外邊界不會重疊。
<!-- HTML 程式碼 -->
<div>
<div>預設</div>
</div>
<div class="a">
<div>父元素有 border</div>
</div>
<div class="b">
<div>父元素有 padding</div>
</div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 50px;
margin: 30px;
background: #f005;
}
div div {
margin: 20px;
background: #05f5;
border: none;
}
.a {border: 1px solid #000;}
.b {padding: 1px;}
</style>
下方範例更改父元素的 display
,可以發現沒有產生外邊界重疊現象。
<!-- HTML 程式碼 -->
<div class="a">
<div>父元素 display: inline-block;</div>
</div>
<div class="b">
<div>父元素 display: table;</div>
</div>
<div class="c">
<div>父元素 display: grid;</div>
</div>
<div class="d">
<div>父元素 display: flex;</div>
</div>
<!-- CSS 程式碼 -->
<style>
div {
width: 240px;
height: 50px;
margin: 30px;
background: #f005;
}
div div {
margin: 20px;
background: #05f5;
}
.a {display: inline-block;}
.b {display: table;}
.c {display: grid;}
.d {display: flex;}
</style>
下方範例會在元素之間穿插 inline
、table
顯示類型元素,這也會讓外邊界不重疊,此外如果加入的是 block
區塊容器元素,就會發生外邊界重疊現象。
<!-- HTML 程式碼 -->
<div>
<span>我是行內容器 inline</span>
<div></div>
</div>
<table>
<tr>
<td>我是表格</td>
<td>我是oxxo</td>
</tr>
</table>
<div class="b">
<div>我是區塊容器 block</div>
<div></div>
</div>
<!-- CSS 程式碼 -->
<style>
div {
width: 240px;
height: 50px;
margin: 30px;
background: #f005;
}
div div {
margin: 20px;
background: #05f5;
}
td {
border: 1px solid #000;
}
</style>
不可置換行內容器的 margin
雖然不可置換行內容器無法調整寬高 ( 文字樣式的顯示類型大多都是 inline
),但卻可以透過 margin
改變外邊界,進而改變寬度,不過由於行內容器的高度由字型大小和行高所管控,就算設定了 margin
數值也不會影響整體高度。
不可置換行內容器表示不會透過 src 等屬性改變元素內容。
下方的範例設定了 strong 和 em 這兩個行內容器元素的 margin
數值,因為外邊界的改變而把左右兩側的內容推開,上下的 margin 則沒有作用,不影響容器的行高表現,也不會影響整體的高度與外部的元素,如果設定為「負值」,重疊的方式和元素流向相同,都是「右邊在上層,左邊在下層」。
<!-- HTML 程式碼 -->
<span>hello oxxo</span>
<div>
<span><strong>STEAM 教育學習網</strong>透過免費且高品質的<em>教學與範例</em>讓所有人都能輕鬆跨入 STEAM 的學習領域。</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
line-height: 30px;
}
strong {
margin: 80px;
background: orange;
}
em {
margin: -25px;
background: cyan;
}
</style>
如果 margin
為負值,會造成「第一行超出範圍」的表現行為,但卻不會影響其他行。
<!-- HTML 程式碼 -->
<div>
<span>STEAM 教育學習網透過免費且高品質的教學與範例讓所有人都能輕鬆跨入 STEAM 的學習領域。</span>
</div>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
line-height: 30px;
width: 200px;
margin: 100px;
}
span {margin: -80px;}
</style>
可置換行內容器的 margin
網頁中的圖片元素 img 或 svg 都屬於「可置換」行內容器 ( 顯示類型大多都是 inline-block
),這些元素原本就能設定寬高,而不是根據字型或行高決定容器大小,因此如果設定了 margin
數值,外邊界就會發生作用,將旁邊的元素推開*。
下方的範例在文字中插入兩張圖片,當設定了圖片的 margin
數值,如果是正值就會將周圍元素推開,如果是負值就會讓周圍元素內縮到元素裡,或發生元素跑到邊界外的狀況。
<!-- HTML 程式碼 -->
<div>
<span>STEAM 教育學習網透過免費且高品質的教學與範例
<img src="https://steam.oxxostudio.tw/download/css/function-filter-demo.jpg">讓所有人都能輕鬆跨入 STEAM 的<img class="a" src="https://steam.oxxostudio.tw/download/css/function-filter-demo.jpg">學習領域。</span>
</div>
<span>hello oxxo!!!</span>
<!-- CSS 程式碼 -->
<style>
div {
border: 1px solid #000;
line-height: 30px;
}
span {background: yellow;}
img {
width: 100px;
margin: 50px;
}
img.a {margin: -50px;}
</style>
小結
元素的外邊界 margin
雖然在使用上跟 padding
大同小異,但對於其他元素或邊界重疊的現象卻大相徑庭,不過只要透過這篇教學,就能熟悉相關做法,也能輕鬆應用在網頁設計或網頁排版囉!
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~