# 简述 CSS 盒模型
# 一、块级盒子(Block box) 和 内联盒子(Inline box)
在 CSS 中我们广泛地使用两种“盒子” —— 块级盒子 (block box) 和 内联盒子 (inline box)。这两种盒子会在页面流(page flow)和元素之间的关系方面表现出不同的行为,我们这里不细分析如果转换他们的行为,仅做了解。
# 1.1 块级(block)盒子会表现出以下行为:
- 盒子会在内联的方向上扩展并占据父容器在该方向上的所有可用空间,在绝大数情况下意味着盒子会和父容器一样宽
- 每个盒子都会换行
- width 和 height 属性可以发挥作用
- 内边距(padding), 外边距(margin) 和 边框(border) 会将其他元素从当前盒子周围“推开”
常见的块级元素:
div, h1~h6, p, form, ul, li, ol, dl, address, hr, menu, table, fieldset
# 1.2 行级(inline)盒子会表现出以下行为:
- 盒子不会产生换行。
- width 和 height 属性将不起作用。
- 垂直方向的内边距、外边距以及边框会被应用但是不会把其他处于 inline 状态的盒子推开。
- 水平方向的内边距、外边距以及边框会被应用且会把其他处于 inline 状态的盒子推开。
常见的行内元素有:
a, span, label, strong, em, br, img, input, select, textarea, cite,
一个简单的示例了解以下:
# 二、盒模型的组成
完整的 CSS 盒模型应用于块级盒子,内联盒子只使用盒模型中定义的部分内容。模型定义了盒的每个部分:
- content:内容
- padding:包围在内容区域外部的空白区域——内边距
- border:边框盒包裹内容和内边距——边框
- margin:这是最外面的区域,是盒子和其他元素之间的空白区域——外边距
合在一起就可以创建我们在页面上看到的内容。为了增加一些额外的复杂性,有一个标准的和替代(IE)的盒模型。
在chrome浏览器下可查看元素盒模型,如下图:
# 2.1 内边距(padding)
我们把月饼和月饼盒的距离称为盒子模型的 内边距
内边距位于边框和内容区域之间。与外边距不同,您不能有负数量的内边距,所以值必须是0或正的值。
我们可以使用padding简写属性控制元素所有边,或者每边单独使用等价的普通属性:
padding-top
padding-right
padding-bottom
padding-left
您还可以更改类.container的内边距,这将在容器和方框之间留出空间。任何元素上的内边距都可以更改,并在其边界和元素内部的任何内容之间留出空间。
# 2.2 外边距(margin)
月饼盒与另一个月饼盒之间的距离,我们管他叫外边距
外边距是盒子周围一圈看不到的空间。它会把其他元素从盒子旁边推开。 外边距属性值可以为正也可以为负。设置负值会导致和其他内容重叠。无论使用标准模型还是替代模型,外边距总是在计算可见部分后额外添加。
我们可以使用margin属性一次控制一个元素的所有边距,或者每边单独使用等价的普通属性控制:
margin: 10px
// 等于
margin-top: 10px
margin-right: 10px
margin-bottom: 10px
margin-left: 10px
在下面的示例中,可以看一下测试元素在外边距设置为正时是如何推开周边元素,以及设置为负时,是如何收缩空间的。
# 外边距折叠(margin塌陷)
理解外边距的一个关键是外边距折叠的概念。如果你有两个外边距相接的元素,这些外边距将合并为一个外边距,即最大的单个外边距的大小。
在下面的例子中,我们有两个段落。顶部段落的页 margin-bottom为50px。第二段的margin-top 为30px。因为外边距折叠的概念,所以框之间的实际外边距是50px,而不是两个外边距的总和。
.one {
margin-bottom: 50px;
}
.two {
margin-top: 30px;
}
<div class="container">
<p class="one">I am paragraph one.</p>
<p class="two">I am paragraph two.</p>
</div>
如果你减少 .two 内的margin-top,实际上没有变化的。至于为什么以及如何解决它,我们在这不做讨论。
# 2.3 边框(border)
月饼盒的边,在样式表里被称为边框
它是在边距和填充框之间绘制的。
- 如果您正在使用标准的盒模型,边框的大小将添加到框的宽度和高度。
- 如果您使用的是替代盒模型,那么边框的大小会使内容框更小,因为它会占用一些可用的宽度和高度。
为边框设置样式时,有大量的属性可以使用——有四个边框,每个边框都有样式、宽度和颜色,我们可能需要对它们进行操作。
可以使用border属性一次设置所有四个边框的宽度、颜色和样式。
分别设置每边的宽度、颜色和样式,可以使用:
border-top
border-right
border-bottom
border-left
设置所有边的颜色、样式或宽度,请使用以下属性:
border-width
border-style
border-color
设置单边的颜色、样式或宽度,可以使用最细粒度的普通属性之一:
border-top-width
border-top-style
border-top-color
border-right-width
border-right-style
border-right-color
border-bottom-width
border-bottom-style
border-bottom-color
border-left-width
border-left-style
border-left-color
# 三、标准盒模型
在标准模型中,如果你给盒设置 width
和 height
,实际设置的是 content box
。 padding 和 border 再加上设置的宽高一起决定整个盒子的大小。 见下图:
如果使用标准模型,则宽度 = 410px (300 + 50 + 50 + 5 + 5),由margin之外的其他属性组成。
注: margin 不计入实际大小 —— 当然,它会影响盒子在页面所占空间,但是影响的是盒子外部空间。
盒子的范围到边框为止 —— 不会延伸到margin。
# 四、替代模型(IE)
你可能会认为盒子的大小还要加上边框和内边距,这样很麻烦,就比如在我们前端在开发页面时,经常只知道盒子的宽高,总不能我们还要备一个计算器,计算内外边距吧?
因为这个原因,css还有一个替代盒模型。使用这个模型,所有宽度都是可见宽度,所以:
内容宽度 = 该宽度 - border - padding。
大家可以看到child
的宽度就为300 - 50 - 50 - 5 - 5 = 190px。
默认浏览器会使用标准模型。如果需要使用替代模型,可以通过为其设置 box-sizing: border-box 来实现。
.box {
box-sizing: border-box;
}
如果你希望所有元素都使用替代模式,而且确实很常用,设置 box-sizing 在 html 元素上,然后设置所有元素继承该属性,正如下面的例子。如果想要深入理解,请看 the CSS Tricks article on box-sizing。
html {
box-sizing: border-box;
}
*, *::before, *::after {
box-sizing: inherit;
}
最后你应该一眼就能看出来两个盒子之前的区别了吧?
# 写在最后
本文是《CSS基础系列》第二篇文章
如果对你有所帮助不妨给本项目的github 点个 star (opens new window),这是对我最大的鼓励!
关于我
- 花名:余光
- WX:j565017805
- 沉迷 JS,水平有限,虚心学习中
其他沉淀