第4章 盒尺寸四大家族
盒尺寸中的4个盒子content box、padding box、border box和margin box分别对应CSS世界中的content、padding、border和margin属性。
4.1 深入理解content
4.1.1 content与替换元素
1、什么是替换元素
根据“外在盒子”是内联还是块级我们可以把元素分为内联元素和块级元素,而根据是否具有可替换内容,我们也可以把元素分为替换元素和非替换元素。
替换元素,顾名思义,内容可以被替换。
<img src="1.jpg">
把上面的1.jpg换成2.jpg,图片就会被替换。这种通过 修改某个属性值呈现的内容就可以被替换的元素就称为“替换元素”。因此,<img>、<object>、<video>、<iframe>或者表单元素<textarea>和<input>都是典型的替换元素。
替换元素除了内容可以替换这一特性以外,还有以下一些特性。
1)内容的外观不受页面上的CSS的影响。用专业的话讲就是样式表现在CSS作用域之外。(????)
2)有自己的尺寸。
3)在很多CSS属性上有自己的一套规则。比较具有代表性的就是vertical-align属性,对于替换元素和非替换元素,vertical-align属性值的解释是不一样的。比方说,vertical-align的默认值baseline,基线,被定义为字符x的下边缘,但是到了替换元素那里就不适用了。因为替换元素的内容往往不可能含有字符x,于是替换元素的基线被硬生生定义成了元素的下边缘。
2、替换元素的默认display值
所有的替换元素都是内联水平元素,也就是替换元素和替换元素、替换元素和文字都是可以在一行显示的。但是,替换元素默认的display值却是不一样的。
3、替换元素的尺寸计算规则
1)固有尺寸指的是替换内容原本的尺寸。例如,图片、视频作为一个独立文件存在的时候,都是有着自己的宽度和高度。这个宽度和高度的大小就是这里的“固有尺寸”。
2)HTML尺寸这个概念略微抽象,我们不妨将其想象成水煮蛋里面的那一层白色的膜,里面是“固有尺寸”这个蛋黄蛋白,外面是“CSS尺寸”这个蛋壳。“HTML尺寸”只能通过HTMl原生属性改变,这些HTML原生属性包括<img>的width和height属性、<input>的size属性、<textarea>的cols和rows属性等。
<img width="300" height="100">
<input type="file" size="30">
<textarea cols="20" rows="5"></textarea>
3)CSS尺寸特指可以通过CSS的width和height或者max-width/min-width和max-height/min-height设置的尺寸,对应盒尺寸中的content box。
3层结构的计算规则如下:
- 如果没有CSS尺寸和HTML尺寸,则使用固有尺寸作为最终的宽高。
- 如果没有CSS尺寸,则使用HTML尺寸作为最终的宽高。
- 如果有CSS尺寸,则最终尺寸由CSS属性决定
- 如果“固有尺寸”含有固有的宽高比例,同时仅设置了宽度或仅设置了高度,则元素依照固有的宽高比例显示。
- 如果上面的条件都不符合(如空内容的情况下,video、canvas、iframe这些元素),则最终宽度的表现为300像素,高度为150像素。
- 内联替换元素和块级替换元素使用上面同一套尺寸计算规则。
5、content与替换元素关系剖析
在CSS世界中,把content属性生成的对象称为“匿名替换元素”。
content属性生成的内容都是替换元素。
4.2 温和的padding属性
4.2.1 padding与元素的尺寸
CSS中默认的box-sizing是content-box,所以使用padding会增加元素的此村。
对于非替换元素的内联元素,不仅padding不会加入行盒高度的计算,margin和border也都是如此,都是不计算高度,但实际上在内联盒周围发生了渲染。
4.2.2 padding的百分比值
其一,和margin属性不同,padding属性是不支持负值的;其二,padding支持百分比值,但是,和height等属性的百分比计算规则有些差异,差异在于:padding百分比值无论是水平方向还是垂直方向均是相对于宽度计算的!
4.2.3 标签元素内置的padding
padding属性和background-clip属性配合,可以在有限的标签下实现一些CSS图形绘制效果。
backgrounf-clip设置元素的背景(背景图片或颜色)是否延伸到边框、内边距盒子、内容盒子下面。
4.3 激进的margin属性
padding性格温和,负责内间距;而margin则比较激进,负责外间距。
4.3.1 margin与元素尺寸以及相关布局
1、元素尺寸的相关概念
- 元素尺寸:在原生的DOM API中写作offsetWidth和offsetHeight,包括padding和border,也就是元素的border box尺寸,所以,有时候也称为“元素偏移尺寸”。
- 元素内部尺寸:元素的内部区域尺寸,包括padding但不包括border,也就是元素的padding box的尺寸。在原生的DOM API中写作clientWidth和clientHeight,所以,有时候也称为“元素可视尺寸”。
- 元素外部尺寸:表示元素的外部尺寸,不仅包括padding和border,还包括margin,也就是元素的margin box的尺寸。没有相对应的原生的DOM API。
2、margin与元素的内部尺寸
margin同样可以改变元素的可视尺寸,但是和padding几乎是互补态势。
什么意思呢?
对于padding,元素设定了width或保持“包裹性”的时候,会改变元素可视尺寸;但是对于margin则相反,元素设定了width值或保持“包裹性”的时候,margin对尺寸没有影响,只有元素是“充分利用可用空间”状态的时候,margin才可以改变元素的可视尺寸。
4.3.2 margin的百分比值
和padding属性一样,margin的百分比值无论是水平方向还是垂直方向都是相对于宽度计算的,不过相对于padding,margin的百分比值的应用价值就低了一截,根本原因在于和padding不同,元素设置margin在垂直方向上无法改变元素自身的内部尺寸,往往需要副元素作为载体,此外,由于margin合并的存在,在垂直方向往往需要双倍尺寸才能和padding表现一致。
4.3.3 正确看待CSS世界里的margin合并
1、什么是margin合并
块级元素的上外边距和下外边距有时会合并为单个外边距,这样的现象称为“margin合并”。
重要信息:
1)块级元素,但不包括浮动和绝对定位元素,尽管浮动和绝对定位可以让元素块化。
2)只发生在垂直方向,需要注意的是,这种说法在不考虑writing-mode的情况下才是正确的,严格来讲,应该是只发生在和当前文档流方向的相垂直的方向上。由于默认文档流是水平流,因此发生margin合并的就是垂直方向。
2、margin合并的3种场景
margin合并有以下3种场景。
1)相邻兄弟元素margin合并。
2)父级和第一个/最后一个子元素。
对于margin-top合并,可以进行如下操作(满足一个条件即可):
- 父元素设置为块状格式化上下文元素(https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context)
- 父元素设置border-top值;
- 父元素设置padding-top值;
- 父元素和第一个子元素之间添加内联元素进行分隔。
对于margin-bottom合并,可以进行如下操作(满足一个条件即可):
- 父元素设置为块状格式化上下文元素;
- 父元素设置border-bottom值;
- 父元素设置padding-bottom值;
- 父元素和最后一个子元素之间添加内联元素进行分隔;
- 父元素设置height、min-height或max-height。
3)空块级元素的margin合并。(空块级元素的上下边距合并。)
对于空块级元素的margin合并,可以进行如下操作(满足一个条件即可):
- 设置垂直方向的border;
- 设置垂直方向的padding;
- 里面添加内联元素(直接Space键空格是没用的);
- 设置height或者min-height。
3、margin合并的计算规则
margin合并的计算规则总结为“正正取大值”“正负值相加”“负负最负值”3句话。
4.3.4 深入理解CSS中的margin:auto
margin:auto的填充规则如下:
1)如果一侧定值,一侧auto,则auto为剩余空间大小。
2)如果两侧均是auto,则平分剩余空间。
4.3.5 margin无效情形解析
margin无效的情形:
1)display计算值inline的非替换元素的垂直margin是无效的,虽然规范提到有渲染,但浏览器表现却未寻得一点踪迹,这和padding是有明显区别的。对于内联替换元素,垂直margin有效,并且没有margin合并的问题,所以图片永远不会发生margin合并。
2)表格中的<tr>和<td>元素或这是display计算值是table-cell或table-row的元素的margin都是无效的。但是,如果计算值是table-caption、table或inline-table则没有此问题,可以通过margin控制外间距。
3)margin合并的时候,更改margin值可能是没有效果的。
4)绝对定位元素非定位方位的margin值“无效”。(看着“无效”)
5)定高容器的子元素的margin-bottom或者宽度定死的子元素的margin-right的定位“失效”。
6)鞭长莫及导致的margin无效。(看第六章内容)
7)内联特性导致的margin无效。(看第五章内容)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。