盒模型是CSS布局的基础,因为所有的HTML元素都能看做是一个一个的盒子。
CSS盒模型
CSS盒模型包含四个部分:
- Content:盒内容,文本和图片显示在这里
- Padding:内容周围的空白部分,padding是透明的
- Border:边框,边框围绕padding和内容
- Margin:边框外的空白部分,margin是透明的
相关属性
padding
padding
是透明的,我们可以分别设置padding
的宽度:padding-top
,padding-left
,padding-bottom
,padding-right
margin
margin
也是透明的,我们也可以分别设置margin
的宽度:margin-top
,margin-left
,margin-bottom
,margin-right
**需要注意的是,当两个盒子相邻时,它们之间的距离是两个盒子中较大的margin
,而不是两个margin
之和。这个现象叫margin-collapse
**。
border
border
可以分别设置宽度:border-top
,border-left
,border-bottom
,border-right
- 设置边框的样式
border-width
设置边框的宽度(可以设置数值,也可以设置thick
,medium
,thin
)border-style
设置边框样式,如(dotted
点状,solid
实线,inset
嵌入)border-color
设置边框颜色- 以上三个属性可以通过
border
简写直接设置border: 1px solid black
- 混合设置,如
border-top-width
,border-right-color
元素宽高
width
和height
属性
元素的宽高通过width
和height
属性来设置。但是width
和height
属性设置的是内容即content area
的宽高,元素的实际宽高需要将padding
,border
,margin
计算进去。
IE盒子模型和W3C盒子模型
如上所述,W3C标准的盒模型在计算宽高时,是计算的内容部分的宽高。
但IE盒模型包含padding
和border
,所以在计算width
和height
时,会得到不一样的值。
指定盒模型
box-sizing
属性可以指定使用元素的哪个宽高作为元素的整体宽高。
box-sizing: content-box
:以内容为宽高
box-sizing: border-box
:以content
+border
+padding
为宽高
还可以将设定放在CSS reset部分:
1 | * { |
设定盒子的最大/最小宽高
min-width
,max-width
,min-height
,max-height
属性可以设定元素的最大/最小宽高。
设置元素的宽高可以使用数值,也可以设置百分比,百分比会按照元素父元素的宽高来计算元素的对应宽高。
内容溢出
当盒子内放置的内容超出盒子大小时,就会溢出。我们使用overflow
来控制这种情况:
overflow: auto
当内容过多时,溢出内容被隐藏,使用滚动条来滚动查看所有内容overflow: hidden
溢出内容被隐藏overflow: visible
溢出内容显示在盒子外面(默认行为)
CSS盒子类型
块级盒子(Block box)
可以堆放在其他盒子上的盒子(内容会单独占一行),可以设置宽高
行内盒子(inline box)
- 多个行内元素在一排时,会出现在一行
- 对行内盒子设置宽高无效
padding
,margin
横向有效,垂直方向无效- 行内盒子的高度可以通过
line-height
来设置
行内块级盒子(inline-block box)
- 会像行内盒子一样,和其他行内盒子出现在一行
- 但是不会像行内盒子那样出现断行,也就是说,如果一行剩下的空间不够行内块级盒子放下全部内容,那么它会在新的一行开始内容
- 可以像块级盒子一样设置宽高
BFC
BFC(Block Formatting Context),即“块级格式化上下文”。它是页面中CSS渲染的一部分,在布局过程中生成块级盒子的区域。它像一个隔离的独立容器,容器里面的子元素不会影响到外面元素。容器内的长度大于容器长度时,会出现内部滚动,但是滚动不会影响父容器之外的布局。
触发条件
根元素本身就是BFC
float
值不为none
overflow
值不为visible
display
值为inline-block
,table-cell
,table-caption
position
值为absolute
或fixed
应用场景
自适应两栏布局
通常文本会围绕浮动元素,但有些时候,我们并不希望发生这样的情况:
我们想要Figure2的样式,
我们将元素内容列出来:
1 | <div class="container"> |
1 | .container { |
但我们注意看W3C给BFC的规范:
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
在BFC中,每一个盒子的左边外部边缘会挨着父容器的左边缘(如果是从右向左排版,则盒子右边缘挨着父容器的右边缘)。即使是浮动布局的情况下,这一点也不会改变(尽管父容器的子元素可能会因为浮动而尺寸缩小)。除非子元素创建一个新的BFC,这样它也会因为浮动布局而变窄。
也就是说,如果我们希望p元素不要围绕图片,那么可以通过给p建立一个BFC来实现。
1 | p { |
清除内部浮动
我们经常会遇到容器里面是浮动元素,于是容器的高度就塌陷到0的情况。
1 | <div class="container"> |
1 | .container { |
页面中只有两个孤独的div漂浮。.container
因为没有高度,并不会显示出来。通常我们会设置一个空的伪元素去把容器敞开,但利用BFC,我们能更容易地处理这个情况。
1 | .container { |
防止垂直的margin
重叠
1 | <div class="container"> |
我们创建一个div
,中间包含3个p
元素,此时如果给p
元素设定margin
值,上下相邻的两个margin
是会塌陷的。
1 | .container { |
此时p元素之间的margin值是10px
,而并不是20px
。
如果我们还记得根元素整体也是一个BFC,那么我们就能理解,同一个BFC中是会发生margin collapse的,要想解决它,需要让元素属于不同的BFC。所以我们要建立一个新的BFC。
1 | <div class="container"> |
给新的BFC也设置overflow
1 | .container { |
通过设置元素在不同的BFC中避免了垂直方向的margin collapse。