# 盒子模型
[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-容器中行与列之间的间距