A23. 盒模型
3.1. 🌟 盒模型的基本原理
人们对“留白”的审美总是有一定要求的。正常情况下,字不能贴着边框写,不同的文本间应留有间距,这是设计的基本原则。
CSS 通过建立巧妙的模型——“盒模型”来解决这个问题。它就像快递盒一般,可以一层套一层,每个盒子有宽度和高度,盒子之间也有空隙。
<div style="width: 200px; padding: 20px; border: 5px solid black; margin: 30px">
我是内容区
</div>
<div style="width: 200px; padding: 20px; border: 5px solid black; margin: 30px">
我是内容区
</div>
建议使用开发者工具查看盒模型:
- 路径:元素(Elements)→ Computed(已计算)
- 里面所有的数字都表示像素
px
。-
表示为0
,未设置。 - 最内层(一般用蓝色表示)为内容区。所有的文本、图片都在这个区内展示。控制合适的内容区宽高有利于文本正常显示。
- 次内层(一般用绿色表示)为内边距。内边距是指内容和边框之间的距离。
- 次外层(一般用黄色表示)为边框。上面的长度表示边框的宽度。
- 最外层(一般用橙色表示)为外边距。外边距是指边框向外延伸的无内容区的距离。
TIP
width
默认指的是内容区的宽度,所以实际占用的宽度可能比指定的 width
的属性更大,这也就是为什么两个 width: 50%
的盒子会超出边界。详见 3.4。
3.2. 🌟 内外边距 可变语法
想让导航栏按钮间距上下10px,左右20px怎么办?像数学中的合并同类项,CSS也有简写妙招!
3.2.1. 🌟 可变语法
内边距的属性名为 padding
;外边距的属性名为 margin
。它们的所有语法形式上都一致。
所有的长度属性值之间都用空格分隔。
<div style="width: 200px; border: 5px double black">
<div style="">在此添加样式</div>
</div>
要查看效果,将下列代码中某一行复制到上面 HTML 的 style=""
的引号中。
/* 四个值(四值语法):上 右 下 左(顺时针) */
margin: 10px 20px 30px 40px;
/* 两个值(双值语法):上下 / 左右 */
padding: 20px 40px;
/* 一个值(单值语法):四个方向相同 */
margin: 15px;
例:设置内边距,上下 8px
,左右 16px
。
解:两种方法,可以四值全部写出来,也可以双值简写。
padding: 8px 16px;
padding: 8px 16px 8px 16px;
WARNING
双值语法先上下后左右!四值语法是上→右→下→左(顺时针)!
3.2.2. 特殊技巧
水平居中经典写法:margin: 0 auto;
<div style="width: 200px; margin: 0 auto; background-color: yellow">
水平居中经典写法
</div>
WARNING
水平居中时,需要保证该元素是块级元素。
3.2.3. 缩写本质
本质上,CSS 会将我们设置的 margin
和 padding
属性各自拆分成四个属性:
margin-top
、margin-right
、margin-bottom
、margin-left
padding-top
、padding-right
、padding-bottom
、padding-left
所以代码 margin: 10px 20px;
等价于:
margin-top: 10px;
margin-bottom: 10px;
margin-left: 20px;
margin-right: 20px;
3.3. 🌟 border 属性 多值语法
如何同时控制边框粗细、样式和颜色?怎么让某一边与众不同?
3.3.1. 基础语法
边框属性有三个必要子属性:
border-width
:边框的粗细,需要至少一个<length>
作为值传入(但是极少用到四边不一样的边框,所以一般只写单值)。border-style
:边框的样式,常见的有:none
:无边框;solid
:实线;dashed
:虚线;dotted
:点状线;double
:双实线。
border-color
:边框的颜色,需要至少一个<color>
作为值传入,同样一般只写单值。所有颜色的表示法均可用。
但是我们一般更常用“三合一”的语法,记住顺序:
border: <border-width> <border-style> <border-color>;
/* 简写 */
border: 2px solid red;
/* 拆分写法 */
border-width: 2px;
border-style: dashed;
border-color: blue;
例:设置边框为 1px 点线 紫色。
一般只用这种写法:
border: 1px dotted purple;
WARNING
忘记写border-style时边框不会显示!比如只写border: 2px red
无效。
3.3.2 单边边框技巧
若想让四边的宽度不同,则可以使用 border-left
等细分属性。
/* 单边设置 */
border-left: 3px solid black;
常用于底线边框:
<h1 style="border-bottom: 3px dotted green; width: 8rem;">Hello</h1>
3.4. ⭐ box-sizing 属性 渲染计算方式
为什么设置了
width: 100%;
的元素加上padding
后会撑破容器?盒子的"数学公式"可以重写!
对比:
<div style="width: 100%; padding: 1rem; border: 2px solid black; background-color: green;">
<strong>默认</strong> box-sizing: content-box
</div>
<div style="width: 100%; padding: 1rem; border: 2px solid black; background-color: green; box-sizing: border-box;">
设置 box-sizing: border-box
</div>
box-sizing
可以设置为 content-box
或 border-box
。
根本上来说,box-sizing
决定了 width
和 height
究竟是针对谁制定的:
box-sizing: content-box;
从内容角度出发,使得内容区有指定的宽高,所以元素的宽高还要加上内边距和边框。box-sizing: border-box;
从布局角度出发,使得元素包含边框后有指定的宽高,此时内容区的宽高要减去内边距和边框。
INFO
- 在不设置
width
的情况下,块级元素宽度默认撑满父元素,行级元素以“恰好容纳内容”为原则,即从内容区开始由内向外“撑”; - 在不设置
height
的情况下,元素均以“恰好容纳内容”为原则。
例:计算 <div style="width: 40px; height: 60px; padding: 10px; box-sizing: border-box;"></div>
留给内容区的空间。
解:因设置 box-sizing: border-box;
,故设置的宽高以边框为基准。内边距四边各 10px
,故内容区宽高各向内收缩 10px * 2
。故答案为:20x40
(单位:px
)。
知识回顾
- 盒模型四层结构:内容区 → 内边距(
padding
) → 边框(border
) → 外边距(margin
) margin
/padding
简写规则:单值全相同,双值上下/左右,四值顺时针上右下左border
必须按顺序<width>
/<style>
/<color>
box-sizing
控制宽度计算方式,分为content-box
和border-box
。
课后练习
(单选)
margin: 10px 20px;
表示:- A. 外边距 上下
10px
左右20px
- B. 外边距 左右
10px
上下20px
- C. 外边距 上
10px
右20px
- D. 内边距 左右
10px
上下20px
- E. 内边距 上下
10px
左右20px
- F. 内边距 上
10px
右20px
- A. 外边距 上下
(填空)实现边框实现宽
1px
,颜色为蓝色。代码实现为border: ___ ___ ___;
。(计算)请分别计算下面三个元素 内容区 的宽度。
html<div style="width: 100px; padding: 10px; border: 2px solid black;">A</div> <div style="width: 100px; padding: 10px; border: 2px solid black; box-sizing: border-box;">B</div> <div style="width: 100px; margin: 10px; border: 2px solid black; box-sizing: border-box;">C</div>
参考答案
A
1px solid blue
A = 100px
,B = 100px - 2px * 2 - 10px * 2 = 76px
,C = 100px - 2px * 2 = 96px