了解有关内嵌式包装盒高度的CSS2.1规范

时间:2018-09-11 18:46:04

标签: html css

CSS2.1 Section 10.6.1指定:

  

内容区域的高度应基于字体,但是此规范未指定操作方式。 UA可以例如使用em-box或字体的最大升序和降序。

     

内联的非替换框的垂直填充,边框和边距始于内容区域的顶部和底部,并且'line-height' 无关。 / p>

然后,在10.8 Line height calculations中出现似乎矛盾的语句:

  

行框的高度确定如下:

     
      
  1. 计算行框中每个 inline-level框的高度。 对于嵌入式盒,这是他们的'line-height' ....
  2.   

并且:

  

用户代理必须通过其相关基准使未替换的嵌入式框中的字形彼此对齐。...

     

内联框的高度将所有字形及其两边的前导符包围起来,因此恰好是'line-height'

有些地方我没有完全理解。

内联级别框的高度是否等于其上设置的line-height属性(最小值是在父块容器上设置的line-height),还是由字体高度(和UA实现)决定?


编辑

只是为了避免造成混淆(因为有很多与此相关的帖子):

  • 我知道inline-level element的内容高度等于它包含的字体(和UA实现)
  • 我意识到规范确实在10.6.1中声明了这一点,但是在10.8.1中声明了inline-level box的高度等于其line-height
  • 这似乎与我矛盾
  • 我在这篇文章中的目的是讨论规范中的措辞,以便充分理解其含义以及与现实的联系

编辑:

为了避免以“基于观点”为基础进行投票,我更改了标题。我认为规范不是矛盾的,我也不是在征求其他人对它是否矛盾的看法。

我意识到这实际上不是矛盾的,我只是想理解为什么不这样做,因为它的措辞。

2 个答案:

答案 0 :(得分:4)

  

内联级别框的高度是否等于其上设置的line-height属性(最小值是在父块容器元素上设置的line-height),

是的。

  

是由字体高度(和UA实现)决定的吗?

不,不是

CSS实际上是关于盒子的,而不是元素的,并且您应该尽量不要混淆两者。

因此,一个内联元素与之关联了许多框。内容框,填充框,边框和边距框。它具有零个(如果display:none),一个或多个内联框。内容框,内边距,边框和边距可以在内联框之间划分,以便内联内容可以分布在多行上。

内嵌的高度是由leading调整的内容高度。领导在这里发挥了魔力。前导定义为元素的行高减去该内联框的内容高度。

简单地重新排列该方程式就可以告诉我们,内联框的高度仅取决于行高,而不取决于内容框(或填充,边框,边距框)。

请注意,以上内容都没有讨论行框,这又是另一回事,而不是内联元素或其框的直接属性。通过将出现在同一行上的内联框排列成它们的垂直对齐方式来构造该行框,以使其垂直对齐适合为元素计算的规则,包括由撑杆形成的零宽度内联框。

每个行框都由该行框所包含的最上面的内嵌框的顶部和最下面的内嵌框的底部界定。


题外话:关于为什么线框的高度会令人惊讶。

假设我们有一个包含块的简单情况,它只包含一个短的内联元素(即足够短,以至于它适合单个行框)。还假设一切都在基线上对齐。假设在包含框上将line-height设置为20px,并且inline元素继承了该高度。还假设包含块的字体大小(em-square)为16px,这意味着字体度量标准计算得出的上升(基线以上)为14px,下降为4px(基线以下)。

因此,支撑的内容区域高(14px + 4px =)18px。行高为20像素,因此领先2像素,在上升上方1像素,在下降下方1像素。因此,撑杆的线高由基线上方的15px和基线下方的5px组成。

现在,假设将内联元素的字体大小设置为0.5em(即包含块的一半)。内联元素的内容区域将是7px的上升和2px的下降。行高仍为20px,因此行距为20px-(7px + 2px)= 11px,这意味着5.5px在上升上方,而5.5px在下降下方。这导致inline元素的行高由基线上方12.5px和基线下方7.5px组成。

由于strut和inline元素垂直于其基线对齐,因此,最上面的inline框(strut)的顶部比基线高15px,最下面的inline框(inline元素)的底部比基准线低7.5像素,则线框的实际高度不是20像素,而是(15像素+ 7.5像素=)22.5像素。

答案 1 :(得分:1)

正如我在上一个问题(Why is there space between line boxes, not due to half leading?中所解释的那样),我们有内容区域行框

内容区域是由字体属性和UA定义的(如第一个引号中所述),而行框是由行高定义的(如第二个引号中所述)。下面是一些示例,这些示例根据不同的字体显示不同的内容区域高度,并说明与行框的区别:

span {
  border-left: 1em solid red;
  background: rgba(255, 0, 0, 0.2);
}

.container>div {
  margin-bottom: 5px;
  border: 1px solid;
  line-height: 30px;
}

.container>div:nth-of-type(1) span{
  font-family: arial;
  font-size: 25px;
}

.container>div:nth-of-type(2) span{
  font-family: "open sans";
  font-size: 20px;
}

.container>div:nth-of-type(3) span{
  font-family: monospace;
  font-size: 30px;
}

.container>div:nth-of-type(4) span{
  font-family: cursive;
  font-size: 22px;
}
<div class="container">
  <div>
    <span>Hello World</span>
  </div>
  <div>
    <span>Hello World</span>
  </div>
  <div>
    <span>Hello World</span>
  </div>
  <div>
    <span>Hello World</span>
  </div>
</div>

如您所见,背景和边框适用于font-familyfont-size定义的内容区域。对于所有情况,我将line-height设置为等于30px,因此所有行框都相等。

我们还可以注意到border-left的行为有所不同,这表明内容区域的高度确实取决于字体和UA。


下面是同一示例,其中带有一些垂直填充/边距/边框,以说明它们如何影响内容区域,并且与line-height无关:

span {
  border-left: 1em solid red;
  background: rgba(255, 0, 0, 0.2);
  font-family: arial;
  font-size: 25px;
}

.container>div {
  margin-bottom: 5px;
  border: 1px solid;
  line-height: 40px;
}

.container>div:nth-of-type(1) span {
  padding: 10px;
}

.container>div:nth-of-type(2) span {
  border-bottom: 5px solid red;
}

.container>div:nth-of-type(3) span {
  padding: 10px;
  background-clip: content-box;/*I limit the background to content-box only*/
}

.container>div:nth-of-type(4) span {
  margin: 20px;
}
<div class="container">
  <div>
    <span>Hello World</span>
  </div>
  <div>
    <span>Hello World</span>
  </div>
  <div>
    <span>Hello World</span>
  </div>
  <div>
    <span>Hello World</span>
  </div>
</div>