CSS - 盒模型

盒模型 - Box Model

CSS 在視覺的呈現是創意無限,就我所知,沒有一本書可以涵蓋介紹完他的屬性與效果間的組合,在這些組合技上,CSS 有時是很容易接近的朋友,但有時會鬧鬧脾氣,需要一段時間了解他。而本篇主題盒模型(Box-Model)的是其中一。

在 CSS 的世界裡,是由各式各樣的盒子組成,而這些盒子指的是網頁最基礎的 HTML 元素,也就是說,當我們建立一個 HTML 元素其實等於建立一個 CSS 盒子,一個矩形的盒子,他通常被稱為元素盒(element box)。每個元素盒的中心是內容區域(content area),也就是放文字、圖片的區域,內容區域的周圍還有內距(padding)、邊框(border)、外距(margin),由這些屬性來形成盒模型。

其中,這些屬性值得注意的是,他們都是選擇性的,內距(padding)的背景(顏色、重複圖片)預設是可以顯示在內距之內,他決定內容區域(content area)與邊框(border)之間的留白。外距(margin)他一定是透明,但可以顯示父元素的背景,也就是盒子與盒子之間的距離。內距無法使用負數,外距可以使用複數。邊框沒有指定顏色,會自動渲染內容區的前景色,也就是 color,邊框也是不能有負值。

基礎盒

盒模型可以由兩個基本盒子說起,區塊盒(block-level box)、行內盒(inline box)。這兩個盒子型態是 CSS 世界的大眾居民,大部分元素都是這兩種型態,最經典的範例各自代表為 div、span,當我們建立 div 元素等同建立一個區塊盒,建立 span 則是行內盒,概念如此。

區塊盒 - block box

區塊盒這個居民是 CSS 世界的地主,他們掌控了土地空間的霸權,所以當他們出現,正常流向由左至右的絕對空間(前、後換行),也就是整塊土地都會完全被他們佔有!區塊盒在正常流向裡會垂直堆疊。若有垂直外距有重疊時,則較大的外距會吃掉較小的外距。區塊盒的盒屬性相關設定都可以正常作用。

區塊盒例子:div、h1、p、ul、li、table 等等。

行內盒 - inline box

行內盒是一般居民,他們是被地主奴役的居民,只能擁有一小塊、一小塊的空間(寬、高只能隨著內容改變,也就是無法設定寬、高)。這些行內居民必須一個一個由左至右乖乖排列著,一般情況下,他們是脫離不了地主的控制。除非…他們有勇氣革命,獨立起來定位自己,讓自己進化成區塊級。

行內盒例子:span、a、em 等等。

行內區塊盒 - inline-block box

行內區塊盒(Inline-Block Box),他是介於居民與地主的角色,他的外在行為是行內居民,也就是會像居民乖乖排列,但內在行為卻是區塊地主,區塊盒的盒屬性相關設定因為他的內在行為關係,都可以正常作用。
那麼,最後,誰才是 CSS 世界掌握最多資源的超級大地主?答案呼之欲出。

誰才是超級大地主?

超級大地主指的是初始容器區塊(initial containing block),body 只算是大地主,隱藏版的超級大地主是根元素,也就是 body 的上層 html 元素,html 元素建立的是初始容器區塊,而初始容器區塊是由瀏覽器視埠(viewport)決定本身的尺寸。這也是為甚麼 body 的高度百分比無效化,他被 html 超級大地主控制著。

Margin、Padding、Border

  • 外距、內距若設定百分比(如果有特殊需求),會根據父元素的寬度來計算,即便是上下外距、內距的百分比也是如此,而不是高度喔。
  • 外距可以負數,內距不可以負數。
  • 外距重疊現象指兩區塊外距發生垂直時,大外距會吃掉小外距,而不是兩者相加;左右外距並不會發生重疊。
  • 內距預設會有背景圖渲染。
div {
/* margin 可為負值、padding 沒有 */
/* margin-top、margin-right、margin-bottom、margin-left */
margin-top: 10px;
margin-right: 10px;
margin-bottom: 10px;
margin-left: 10px;
/* top、right、bottom、left*/
margin: 0 0 0 0;
/* 第一個數字為上下外距,第二個數字為左右外距 */
margin: 0 0;
/* 區塊置中,區塊元素一定要設定寬度 */
margin: auto;

/* padding-top、padding-right、padding-bottom、padding-left */
padding-top: 10px;
padding-right: 10px;
padding-bottom: 10px;
padding-left: 10px;
padding: 0 0 0 0;
padding: 0 0;

/* 邊框 */
border-width: 1px;
/*
dotted 一組方格點,會依照邊框 width 的寬度改變方格的大小及間距,如果邊框是 2px,那麼方格是 2px 且每個點之間有 2px 的間距。
dashed 一組短線
double 兩條實線 (border-width 屬性值是兩條線的總和)
groove 看起來像刻入頁面
ridge 看起來像凸出頁面
inset 看起來像嵌入頁面
outset 看起來像浮雕

border-top-style
border-right-style
border-bottom-style
border-left-style
*/
border-style: solid;

/*
border-top-color
border-right-color
border-bottom-color
border-left-color
*/
border-color: #000;
/* 縮寫 */
border: 1px solid #000;
/* 左上、右上、右下、左下 的圓角*/
border-radius: 10px 10px 10px 10px;

/* 盒子陰影 */
/* 水平(+右-左)、垂直(+下-上)、模糊半徑(0 或+不能-)、延展性(+為擴展-為內縮)、顏色、inset(內陰影) */
box-shadow: 0px 0px 3px 3px rgba(0, 0, 0, 0.2);
}

display

display 屬性可以替盒子進行轉型態的設定,

/* inline 轉為 inline-block */
a {
display: inline-block;
}
/* inline 轉為 block */
a {
display: block;
}
/* block 轉為 inline-block */
div {
display: inline-block;
}
  • display:contents

作用在元素上時,display:contents 會將元素從頁面格式化移除,將自身的子元素移到自身所在的層級。
以下例子會將 ul 視覺格式化,就像從來不曾存在過一般,不只邊框消失,ul 周圍的內容的上下外距也一同消失。

<style>
ul {
border: 1px solid red;
display: contents;
}

li {
border: 1px solid gray;
}
</style>
<ul>
<li>link1</li>
<li>link2</li>
<li>link3</li>
</ul>

Box-sizing

可以重新定義 Box 寬度的計算方式。時下流行將此屬性值設定為 border-box,也就是 padding、border 會被計算在 width 裡面,這樣在排版時,只要把焦點放在處理 margin。

Overflow

如果對盒子設定高度 height,內容如果超過高度,則會產生內容溢出,一般頁面元素的高度通常不需要設定,會隨著內容長高。