# 盒子模型
[toc]
## 1. 元素框
無論什么元素, CSS 都會生成一個矩形框來顯示,稱為**元素框**
### 1.1 元素框組合
| 序號 | 名稱 | 描述 |
| ---- | --------------- | ------------------------------ |
| 1 | 內容區(content) | 必須要有,它的四周區域是可選的 |
| 2 | 內邊距`padding` | 內容與邊框之間的填充區域 |
| 3 | 邊框`border` | 邊框可以將內容區與外界進行隔離 |
| 4 | 外邊距 `margin` | 多個盒子之間的間隙 |
- `padding`,`margin`,`border` 的每一條邊都可以單獨設置屬性
- `pading` 和 `margin` 是背景透明的,所以只能設置寬度,不能設置顏色與樣式
### 1.2 內邊距
> 常規屬性
| 序號 | 名稱 | 描述 |
| ---- | ---------------- | -------- |
| 1 | `padding-top` | 上內邊距 |
| 2 | `padding-right` | 右內邊距 |
| 3 | `padding-bottom` | 下內邊距 |
| 4 | `padding-left` | 左內邊距 |
> 屬性簡寫
| 序號 | 值數量 | 舉例 | 描述 |
| ---- | ------ | ----------------------------- | ------------------------ |
| 1 | 四值 | `padding: 5px 10px 15px 20px` | 上 -- 右 -- 下 -- 左 |
| 2 | 三值 | `padding: 5px 10px 5px` | 上 -- (左右相等) -- 下 |
| 3 | 雙值 | `padding: 5px 10px` | (上下相等) -- (左右相等) |
| 4 | 單值 | `padding: 10px` | 上下左右全相等 |
### 1.3 外邊距
> 常規屬性
| 序號 | 名稱 | 描述 |
| ---- | --------------- | -------- |
| 1 | `margin-top` | 上外邊距 |
| 2 | `margin-right` | 右外邊距 |
| 3 | `margin-bottom` | 下外邊距 |
| 4 | `margin-left` | 左外邊距 |
> 屬性簡寫
| 序號 | 值數量 | 舉例 | 描述 |
| ---- | ------ | ---------------------------- | ------------------------ |
| 1 | 四值 | `margin: 5px 10px 15px 20px` | 上 -- 右 -- 下 -- 左 |
| 2 | 三值 | `margin: 5px 10px 5px` | 上 -- (左右相等) -- 下 |
| 3 | 雙值 | `margin: 5px 10px` | (上下相等) -- (左右相等) |
| 4 | 單值 | `margin: 10px` | 上下左右全相等 |
### 1.4 邊框
邊框`border` 比較特殊, 除了可以設置寬度, 還可以設置樣式和顏色,所以有更多的屬性
#### 1.4.1 上邊框
| 序號 | 名稱 | 描述 |
| ---- | ----------------------------- | -------------- |
| 1 | `border-top-width: 1px` | 上邊框寬度 |
| 2 | `border-top-style: solid` | 上邊框樣式 |
| 3 | `border-top-color: black` | 上邊框前景色 |
| 4 | `border-top: 1px solid black` | 上邊框屬性簡寫 |
#### 1.4.2 右邊框
| 序號 | 名稱 | 描述 |
| ---- | ------------------------------- | -------------- |
| 1 | `border-right-width: 1px` | 右邊框寬度 |
| 2 | `border-right-style: solid` | 右邊框樣式 |
| 3 | `border-right-color: green` | 右邊框前景色 |
| 4 | `border-right: 1px solid green` | 右邊框屬性簡寫 |
#### 1.4.3 下邊框
| 序號 | 名稱 | 描述 |
| ---- | ------------------------------- | -------------- |
| 1 | `border-bottom-width: 1px` | 下邊框寬度 |
| 2 | `border-bottom-style: solid` | 下邊框樣式 |
| 3 | `border-bottom-color: grey` | 下邊框前景色 |
| 4 | `border-bottom: 1px solid grey` | 下邊框屬性簡寫 |
#### 1.4.4 左邊框
| 序號 | 名稱 | 描述 |
| ---- | -------------------------------- | -------------- |
| 1 | `border-left-width: 1px` | 左邊框寬度 |
| 2 | `border-left-style: solid` | 左邊框樣式 |
| 3 | `border-left-color: skyblue` | 左邊框前景色 |
| 4 | `border-left: 1px solid skyblue` | 左邊框屬性簡寫 |
#### 1.4.5 所有邊框
| 序號 | 值數量 | 舉例 | 描述 |
| ---- | ------ | ----------------------- | ------------------- |
| 1 | 三值 | `border: 1px solid red` | 寬度--樣式--前景色 |
| 2 | 雙值 | `border: 1px solid` | 寬度--樣式:默認黑色 |
小提示:
- 輪廓`outline`: 位于 `border` 與 `margin` 之間,因為不占空間, 可暫時忽略
- 輪廓沒有針對各條邊的屬性,只能統一設置
- 默認,內容區的背景色會延伸到內邊距范圍內,內邊距是透明的
- 外邊距始終是透明的,可能透過它看到父元素
- 內邊距,邊框不允許是負值, 而外邊距允許
- 內邊距影響到盒子大小, 而外邊距影響到盒子的位置
- 邊框顏色默認與內容區前景色相同,例如文本是黑色, 邊框就是黑色
- 如果邊框是虛線,是可以透過邊框線的間隙看到內容區元素的背景色
---
## 2 重要術語
### 2.1 常規流
- 默認從左到右, 從上到下渲染頁面, 這也符合大多數語言的書寫順序
- 可以通過: `float / position / Flex / Grid` 等布局方式,改變默認行為
### 2.2 非置換元素
- 內容包含在當前文檔中的元素,例如`<p>`,段落文本就在當前的 HTML 文檔中
### 2.3 置換元素
- 充當其它內容占位符的元素. 最常見的就是`<img>`
- `<img>`通過`src`屬性指向一張圖片,渲染時該圖片就會插入到該元素的位置
- 類似的還有`<input>`, 通過`type`屬性指定要插入的表單元素類型
- 例如: `<input type="radio">`
### 2.4 根元素
- 在 html 文檔, 就是指`<html>`元素, xml 文檔中, 可以是任何元素
### 2.5 塊級框
- 元素框在頁面中,只有水平排列與垂直排列二種形式
- 塊級元素生成的框, 總是前后換行, 垂直/縱向/堆疊排列
- 例如:段落`<p>`, 標題`<h3>`, 通用容器`<div>`等
- 任何元素通過`display: block`都可聲明為塊級框
### 2.6 行內框
- 簡單說, 就是前后不換行排列的元素,例如`<span>`,`<strong>`,`<a>`
- 任何元素通過`display: inline`都可聲明為行內框
### 2.7 行內塊級框
- 內部特征像塊級框, 外部特征像行內框,既可設置寬高,又能水平排列
- 行內塊級框也置換元素非常相似: `display: inline-bolck;`
### 2.8 容納塊
- 容納塊是一種特殊的元素框,或者理解為專門充當元素框父級的專用元素框
- 每個**元素框**, 都必須相對于一個容納塊來放置
- 所有, 容納塊, 就是元素框體的**布局上下文**
- 在常規流布局中, 容納塊,是由離元素最近的那個生成列表/塊級框/表格的祖輩元素的邊界構成
```html
<body>
<div>
<p>This is a paragraph.</p>
</div>
</body>
```
- p 元素塊級框的容納塊是 div 元素的塊級框,因為 div 是祖輩中離 p 最近的,并且 div 生成的是塊級框
- 以此類推, div 元素的容納塊是 body 元素生成的塊級框
- 所以, p 元素的布局依賴于 div, 而 div 又依賴于 body 元素的布局, body 又依賴 html 元素的布局
- 而 html 又依賴于誰的布局呢? 對應的是**初始容納塊**(initial containing block)
- 這個初始容納塊大小, 由可視 afadd 小決定,而不是根元素內容大小
- 初始容納塊與其它容納塊差異極小, 我們只需要知道有這么一個大 boss 就可以
---
## 3. 調整元素的顯示方式
- display: 屬性, 默認值`inline`,適用所有元素, 不能繼承
- display 改變的是顯示方式, 并不能改變元素的本質
- 例如,塊級元素不允許做為行內元素后代, 并不會因為它顯示為行內塊而改變
### 3.2 塊級框
- **塊級框寬度**,其實就是內容區寬度,由左內邊界到右內邊界的距離, 高度也一樣
- 元素內容寬度可以用`box-sizing`進行調整,默認為內容寬度(content-box)
#### `box-sizing`
- `box-sizing`: 指示瀏覽器如何計算一個元素的總寬度和總高度
- 盒模型中,元素的`width/height`默認只會應用到"內容區"
- 當盒子中存在`padding/border`時,計算盒子總大小非常麻煩
| 序號 | 屬性值 | 描述 |
| ---- | ------------- | -------------------------------------- |
| 1 | `content-box` | 默認值,`width/height`只應用到內容區 |
| 1 | `border-box` | `width/height`還包括`padding`,`border` |
- 即 `width` 總寬度是不變的, 寬度計算邊界在邊框上,所以 `width=broder+padding+content`
- `box-sizing`: 適用于所有能設置 `width` 和 `height` 的所有元素
- `box-sizing`: 通常只適用于塊級, 也適合置換元素和行內塊元素(因為都可以設置寬高)
### 3.3 橫向格式化
> 涉及七個屬性
| 序號 | 屬性 | 默認值 | 描述 |
| ---- | --------------- | ------ | ---------- |
| 1 | `margin-left` | auto | 左外邊距 |
| 2 | `border-left` | 0 | 左邊框 |
| 3 | `padding-left` | 0 | 左內邊距 |
| 4 | `width` | auto | 內容區寬度 |
| 5 | `padding-right` | 0 | 右內邊距 |
| 6 | `border-right` | 0 | 右邊框 |
| 7 | `margin-right` | auto | 右外邊距 |
- 這七個屬性影響著塊級框的橫向布局
- 本個屬性相加應該等于父元素容納塊的寬度,而這個寬度就是父元素的 width 值
- 七個屬性中,只有內容區和左右外邊距,允許設置`auto`,其它屬性要么 0,要么具體值
- `width`僅允許`auto`, 非負值
- `margin`允許`auto`, 正值, 負值都可以
---
## 4. 細說`auto`值
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>細說auto</title>
<style type="text/css">
* :not(body) {
outline: 1px dashed;
}
div {
width: 600px;
}
/* 只有margin 與 width/height可設置自動 */
p {
/*
最終左外邊距auto, 被200px代替,這個值是如何計算出來的呢?
父元素width:600 - width:200 - margin-right:100 = margin_left:300px
*/
margin-left: auto;
margin-right: 100px;
width: 200px;
}
/*如果右外邊距設置為auto,則與計算左外邊距auto值的方式是一樣的*/
p {
margin-left: 100px;
/*父元素中的剩余空間:300px全部自動分配給右外邊距*/
margin-right: auto;
width: 200px;
}
/*同樣, 如果內容區auto,由會將父元素中剩余空間分配給它*/
p {
margin-left: 100px;
margin-right: 100px;
/*父元素中的剩余空間:400px全部自動分配給內容區*/
width: auto;
}
/*這三個屬性中, 應該總有一個值設置為auto, 以確保總寬義總是等于父元素的寬度*/
/*如果這三個屬性全部被設置為具體的數值(約束過度), 瀏覽器應該如何渲染和計算呢?*/
p {
margin-left: 100px;
/*
此時, 右外邊距的用戶自定義值100px無效
margin-right會被強制設置為auto,以確保總寬度仍等于父元素的寬度
最終,margin-right:auto; 即300px
*/
margin-right: 100px;
width: 200px;
}
/*如果三個屬性中, 右邊外邊距都是auto呢? 會導致內容區居中,這非常有用*/
p {
/*(600-200)/2=200px,左右外邊距都是200px*/
margin-left: auto;
margin-right: auto;
width: 200px;
}
/*如果左外邊距有具體值, 內容區自動,首先計算有具體數值,auto視為0,會導致右外邊距auto為0*/
p {
margin-left: 100px;
margin-right: auto;
width: auto;
}
p {
/*計算原理與上面一樣,先計算有具體數值的,auto視為0, 內容區占據父元素剩余空間*/
margin-left: auto;
margin-right: 100px;
width: auto;
}
/*全部auto, 左右外邊距全部清零, 內容區占據全部父元素空間*/
p {
margin-left: auto;
margin-right: auto;
width: auto;
}
</style>
</head>
<body>
<div>
<p>php中文網</p>
</div>
</body>
</html>
```
- 教學大綱
- HTML5基礎
- 1-html基礎知識
- 2-語義化結構元素
- 3-語義化文本元素
- 4-鏈接/列表/圖像元素
- 5-表格元素
- 6-表單與控件元素[重點]
- CSS3基礎
- 1-css與html文檔
- 2-css選擇器
- 3-細說盒模型
- Flex布局[精簡版]
- 1-Flex概論
- 2-Flex布局是什么
- 3-Flex基本概念
- 4-Flex容器屬性
- 5-Flex項目屬性
- Flex布局[細說版]
- 1-flex 布局概述
- 2-flex 容器與項目
- 3-flex 容器主軸方向
- 4-flex 容器主軸項目換行
- 5-flex 容器主軸與項目換行簡寫
- 6-flex 容器主軸項目對齊
- 7-flex 容器交叉軸項目對齊
- 8-flex 多行容器交叉軸項目對齊
- 9-flex 項目主軸排列順序
- 10-flex 項目交叉軸單獨對齊
- 11-flex 項目放大因子
- 12-flex 項目收縮因子
- 13-flex 項目計算尺寸
- 14-flex 項目縮放的簡寫
- Flex布局[案例版]
- 1-調整項目順序
- Grid布局[精簡版]
- 1. 常用術語
- 2. 容器屬性
- 3. 項目屬性
- 4. 布局實例
- 1. 經典三列布局
- 2. 媒體查詢
- Grid布局[細說版]
- 1-必知術語
- 2-容器創建與行列劃分
- 3-單元格常用單位
- 4-項目填充到單元格
- 5-項目填充到網格區域
- 6-對齊容器中的所有項目
- 7-對齊單元格中所有項目
- 8-對齊單元格中某個項目
- 9-容器中行與列之間的間距