CSS基础学习——理解盒子模型
初了解
-
CSS盒子模型,一个神秘的方形组织。
-
MDN中的定义:W3C盒模型是 CSS 规范的一个模块,它定义了一个长方形的盒子,每个盒子拥有各自的内边距和外边距,并根据视觉格式化模型来对元素进行布局。
-
自己的话来解释一番:盒子模型是相对于块状元素和行内可替换元素而言的,当我们编辑好html与css,命令浏览器开始渲染时,浏览器的渲染引擎会根据盒子模型而将所有符合要求的元素表示为一个矩形的盒子,而我们编写好的CSS样式,便决定着这个盒子的各组成元素的大小、盒子的位置、颜色、背景、边框等等属性。
两种模型
- 标准盒模型
- 图示:
-
- 以及相关的CSS属性:
高度/宽度 | 外边距 | 最大最小高宽度 | 溢出 | 内边距 | 其他 |
height | margin | max-height | overflow | padding | visibility |
width | margin-left | max-width | overflow-x | padding-left | box-shadow |
margin-right | min-height | overflow-y | padding-right | box-decoration-break | |
margin-bottom | min-width | padding-bottom | box-sizing | ||
margin-top | padding-top |
-
- 其中最主要的五个属性:
width:内容区(content)的宽度,注意不是整个盒子的宽度。
height:内容区(content)的高度,也不是整个盒子的高度。
padding:内边距。
border:边框。
margin:外边距。
- IE盒模型:但是,还有另一种盒模型,那就是IE盒模型,IE5.5及更早的版本使用的是IE盒模型,而IE6之后,也遵从了标准盒模型。它的计算方法与标准盒模型不同,接下来会阐述不同在哪。
盒子的大小
设置内容大小
在标准盒模型中,整个div可以看做一个盒子,而此时整个盒子的宽度并不等于width,而是width+2*border+2*padding,最中间的content宽度等于width为100px;
此时设置的宽度只能应用到内容区。
值得一提的是,虽然margin也属于存在于盒子模型中,但并不参与盒子模型的宽度和高度计算,可以看做是用于控制与其他元素之间的距离关系。
<div class="box">这是一个小盒子</div>
.box { width: 100px; height: 100px; border: 5px solid #000; padding: 10px; margin: 20px; box-sizing: border-box; }
盒子模型展示
盒子的真实宽度(margin没有计算在内)
设置高度后,效果和宽度一样:
<div class="box">这是一个小盒子</div>
.box { width: 100px; height: 100px; border: 5px solid #000; padding: 10px; margin: 20px; }
盒子模型展示
盒子的真实宽度(margin没有计算在内)
因此若改动任意一个width、padding或border都会导致盒子的大小发生改变,这对布局来说十分不友好。
设置盒子大小
如何设置盒子的大小,使得改动padding和border时,不会改动整个盒子的大小,而是“内部解决”。
使用box-sizing属性改变盒子模型的计算方式。
MDN中写道:如果box-sizing为默认值content-box,width、min-width、max-width、height、min-height 与 max-height 控制内容大小。
可见box-sizing属性值与盒子模型的大小计算密切相关。
box-sizing
- 语法:content-box | border-box | inherit
- IE盒模型的不同之处就在此。
content-box | 默认值,标准盒模型。如果你设置一个元素的宽为100px,那么这个元素的内容区会有100px宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素(盒子)宽度中。 |
border-box | IE盒模型。告诉浏览器你设置的边框和内边距的值是包含在width内的。也就是说,如果你将一个元素的width设为100px,那么这100px会包含其它的border和padding,内容区的实际宽度会是width减去border + padding的计算值。大多数情况下这使得我们更容易的去设定一个元素(盒子)的宽高。 |
设置box-sizing为border-box
实践一下吧
<div class="box">这是一个小盒子</div>
.box { width: 100px; height: 100px; border: 5px solid #000; padding: 10px; margin: 20px; box-sizing: border-box; }
盒子模型展示(盒子宽度=content+2*padding+2*border=70+2*10+2*5=width=100px;)
盒子的真实宽度(margin没有计算在内)
可以清楚地看见:盒子宽度=content+2*padding+2*border=70+2*10+2*5=width=100px;
改变padding大小
<div class="box">这是一个小盒子</div>
.box { width: 100px; height: 100px; border: 5px solid #000; padding: 20px; /*调整padding*/ margin: 20px; box-sizing: border-box; }
并且将padding增大到20px时,盒子总宽度还是不变,只是调整了内容区的宽度为paddingteng腾出10px的位置。
盒子模型展示(盒子宽度=content+2*padding+2*border=50+2*20+2*5=width=100px;)
盒子的真实宽度(margin没有计算在内)
浏览器兼容
/* * 支持 Firefox, Chrome, Safari, Opera, IE8+ 和老的Android浏览器 * 对于box-sizing属性,浏览器厂商已移除 -webkit 前缀 */ .example { -moz-box-sizing: border-box; box-sizing: border-box; }
垂直外边距的合并
既然说到盒子模型了,就再记录一下外边距margin!
margin呢,不参与盒子模型的宽高度计算,用来调整与其他元素之间的位子等关系,但是有一点需要注意的是,垂直方向上的外边距有“合并”的效果。
即:垂直方向相邻的两个元素如果都有设置外边距,浏览器渲染时只保留较大的外边距。
这只是一个定义,那么具体什么条件下会发生这个事件呢~(来自MDN)
-
直接相邻的两个元素
-
毗邻的两个元素之间的外边距会折叠(除非是两个浮动元素)
-
-
父元素与其第一个或最后一个子元素之间
-
如果在父元素与其第一个子元素之间不存在边框、内边距、行内内容,也没有创建块格式化上下文、或者清除浮动将两者的
margin-top
分开;或者在父元素与其最后一个子元素之间不存在边框、内边距、行内内容、height
、min-height
、max-height
将两者的margin-bottom
分开,那么这两对外边距之间会产生折叠。此时子元素的外边距会“溢出”到父元素的外面。
-
-
空的块级元素
-
如果一个块级元素中不包含任何内容,并且在其
margin-top
与margin-bottom
之间没有边框、内边距、行内内容、height
、min-height
将两者分开,则该元素的上下外边距会折叠。
-
一些需要注意的地方:
-
上述情况的组合会产生更复杂的外边距折叠。
-
即使某一外边距为0,这些规则仍然适用。因此就算父元素的外边距是0,第一个或最后一个子元素的外边距仍然会“溢出”到父元素的外面。
-
如果参与折叠的外边距中包含负值,折叠后的外边距的值为最大的正边距与最小的负边距(即绝对值最大的负边距)的和。
-
如果所有参与折叠的外边距都为负,折叠后的外边距的值为最小的负边距的值。这一规则适用于相邻元素和嵌套元素。
实践
简单相邻元素
<ul style="margin: 10px;"> <li>路飞</li> <li>索隆</li> <li>娜美</li> </ul>
“小盒子”设置了margin:20px;(下同)
可见列表的上外边距被“小盒子”吞啦
父子元素
<ul style="margin: 10px;"> <li>路飞</li> <li>索隆</li> <li style="margin-bottom: 30px;;">娜美</li> </ul>
li元素设置了下外边距30px,li元素的外边距“溢出到”父元素外面,并且与下一个相邻元素“小盒子”产生外边距合并,得到的视觉效果便是两者列表与“小盒子”之间的间距为30px,而不是30+20=50px;
父子元素外边距合并
若父元素设置了边框
<ul style="margin: 10px; border: solid;"> <li>路飞</li> <li>索隆</li> <li style="margin-bottom: 30px;;">娜美</li> </ul>
li元素的外边距就无法“溢出”了
设置边框后便无法合并父子元素外边距
空元素
<div class="box">这是一个小盒子</div> <div style="margin: 50px;"></div>
上下外边距合并,并和上方相邻的“小盒子”的下边距合并
总结
1、CSS盒子模型规定了一个块状元素或行内可替换元素的展示方式,从而使浏览器根据这个规定和样式表,渲染元素。
2、标准盒模型与IE盒模型,在计算元素宽高度时的不同,可以用box-sizing来转换。
3、相邻元素的垂直外边距会合并。