ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 盒子模型 [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> ```