9.7 行盒的高度计算
行盒line box的高度计算包含:IFC内各元素的高度与垂直位置,line box的高度计算。
9.7.1 两级IFC属性设置
本节内容特别重要,为全面说明其本质,可能会使用不规范的开发习惯。
IFC四属性包括两级设置:
(1)父div设置。div设置vertical-align无效,所以实际可以设置字体三属性。本质是设置strut bounds的字体三属性,同时其它inline元素也继承这些属性。这是标准做法,养成在块容器设置字体三属性的习惯。
(2)内部inline元素设置。内部inline元素可以设置IFC四属性。通常情况下,不要使用这级设置,可能出现inline元素的bounds与strut bounds的高度与基线不一致,可能撑高line box,可能引起各种混乱。只在极少数情况使用。
9.7.2 line box高度计算方法
示意代码。div、span设置不同line-height,img设置不同高度。
<div>
<span>span1</span>
<span>span2</span>
<img src="xiaobuteach.png">
</div>
line box高度计算包括4步。
(1)计算strut的bounds。根据父div设置的字体三属性计算。
(2)计算各inline-level元素的bounds或盒子。根据继承自父div或自身设置的字体三属性计算;原子行内级别元素以盒子模型进行计算,详情见“9.9 原子行内级盒子”。
前两步示意图如下。
(3)垂直对齐。inline-level元素根据vertical-align属性与strut(或line box)进行垂直对齐。假设上述示意图三个元素均基线对齐,对齐后示意图如下。
(4)找最上方bounds(包含strut与box)的顶线、找最下方bounds(包含strut与box)的底线,两线之间的距离即line box高度。
理解行盒的高度计算过程,就能理解为什么避免在Inline元素设置字体三属性,它们与strut bounds不一致容易导致混乱。
9.7.3 设置span的字体属性撑高行盒
初始代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小步教程</title>
<style>
body{
font-family: Arial;
font-size: 40px;
line-height: 50px;
}
</style>
</head>
<body>
<div class="div1">
<span class="span1">x</span>
<span class="span2">xiaobuteach.com</span>
</div>
</body>
</body>
</html>
查看当前div高度即行盒line box高度50px。
span设置line-height值60px。
<span class="span2" style="line-height: 60px;">xiaobuteach.com</span>
查看当前div高度即line box高度60px。
结合“IFC模型完整示意图”比较容易理解个别bounds高度撑高行盒。
9.7.4 更小字体因对齐而撑高line box
span元素设置更小字体,可能因后续对齐过程使line box撑高。不是所有更小字体都使line box撑高。
初始代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小步教程</title>
<style>
body{
font-family: Arial;
font-size: 40px;
line-height: 50px;
}
.div1{
border-top: 1px solid #4aa6fc;
border-bottom: 1px solid #4aa6fc;
position: relative;
}
.span1{
border-top: 3px solid #ed7d31;
border-bottom: 3px solid #ed7d31;
}
</style>
</head>
<body>
<div class="div1">
<span class="span1">x</span>
<span class="span2">xiaobuteach.com</span>
<div style="top: 39px;position: absolute;width: 100%; border-top: 1px solid #0aaa76;"></div>
</div>
</body>
</body>
</html>
运行结果
其中蓝线与桔块亲密接触,说明第1个x即span1元素的bounds高度等于行高。
注:本例画各条线是为直观显示行高变化与对齐变化。同学们可以不加各border,直接查看div的高度即行高(因为当前只有一行)。
调小字体。span2原先继承的字体大小是40px,现设置span2的字体大小为30px。
<span class="span2" style="font-size: 30px;">xiaobuteach.com</span>
运行效果
上图中绿色线依然在x的底部,说明基线位置不变;但span1的下方桔色border与div1的底部蓝色border没有亲密接触,说明行高发生变化:被撑高。
对齐前示意图
strut、span1与span2继承div1的line-height,所以它们的bounds高度相同;
因为font-size不同、导致内容高度不同、Leading不同、综合作用基线绝对位置不同, font-size更小的inline元素可能基线更靠上。
对齐过程示意图
首先span2下移,然后line box底线也相应下移,导致行盒高度变大。所以,父div的line-height与span的line-height都只是行盒的最小高度。实际项目,外部元素根据需要可能会设置height属性,避免类似调整引起父div高度变化。
试一试。去掉span1元素,测试修改span2字体前后行高的变化。
试一试。编码尝试各种场景验证line box高度计算方法。