为什么带有`overflow:hidden`的`inline-block`元素的基线设置为其下边距?

Tim*_*nov 16 html css w3c overflow

读取两个伟大的答案解释的行为后inline-block元素(这是为什么inline-block的元素被推向下?为什么跨度的行高也没用)我仍然有两个原因不明的问题.

1.inline-block元素基线从其线框基线改为底边缘的原因是什么?

http://www.w3.org/TR/CSS2/visudet.html#leading

"内联块"的基线是正常流程中其最后一个线框的基线,除非它没有流入线框或者其"溢出"属性具有"可见"以外的计算值,在哪种情况下,基线是底部边缘边缘.

2.如何计算这种转变?

在此输入图像描述

重要提示:我不要试图找到一个解决方案如何解决它.我试着理解inline-block在应用元素时改变元素定位行为的原因是什么overflow: hidden.所以,请不要发布傻瓜的答案.

UPDATE

不幸的是,虽然我接受了答案,但我没有得到我想要的东西.我认为问题本身存在问题.关于第一个问题:我想了解为什么inline-block不能保留其线框的基线,即使它有overflow:hidden(当然,尽管有W3C规范).我想听听设计决定 - 不仅仅是必须设置一些东西,因为它要求W3C.第二个:我想得到一个公式,我们可以粘贴font-sizeline-height元素,并得到正确的结果.

无论如何感谢任何人:)

更新2

幸运的是,主观上找到了答案!看到第一个重新接受的答案.谢谢@pallxk!)

pal*_*lxk 11

1.将内联块元素的基线从其线框基线更改为下边距边缘的原因是什么?

当其overflow属性设置为hidden(此处为完全规范)时,"内联块"的基线将更改为其下边距边缘.

至于这个决定的原因,我认为由于溢出的部分是隐藏的,用户代理(浏览器)可能会选择渲染溢出的部分而不显示它,或者选择不渲染它.并且当未呈现溢出部分时,用户代理无法告知其最后一个行框的基线,因为它没有呈现,它的去向不明.

如果"inline-block的"谁的基线overflow设置为hidden仍然保持作为其最后行框的基线,用户代理被迫渲染什么是隐藏的用户,这可能会影响性能,或者至少把更多的限制上用户代理.更重要的是,在这种情况下,同一行框中的其他内联文本与这样的基线对齐,其中隐藏了溢出隐藏的内联框周围的文本,这是一种诡计而不直观.

我做了一个简单的演示,模拟隐藏溢出的内联块仍然将其基线设置为其最后一个线框的基线.

emultaing_imaginary_baseline_of_overflow_hidden_​​inline_block

var isOverflowHidden = false;
document.querySelector('button').onclick = function() {
  document.getElementById('inline-box').style.overflow = isOverflowHidden ? '' : 'hidden';
  isOverflowHidden = !isOverflowHidden;
}
Run Code Online (Sandbox Code Playgroud)
html { background: white; }
#inline-box { display: inline-block; height: 18px; }
.overflown { color: white; }
Run Code Online (Sandbox Code Playgroud)
<p><button id="toggle">Toggle 'overflow: hidden;' on 'inline-block'</button></p>

<span>
  texts sit
  <span id="inline-box">
    texts in inline-block <br>
    <span class="overflown">
      line 2 <br>
      line 3
    </span>
  </span>
  on baseline
</span>
Run Code Online (Sandbox Code Playgroud)

此外,您还可以将此行为与此进行比较display: none.当这样设置,clientWidthclientHeight都等于0.

2.如何计算这种转变?

这部分要容易得多,因为它在您在问题中给出的链接中有记录.

我将从'line-height'的定义开始.

内联框的高度将所有字形包围在每一侧的半个前导,因此恰好是"行高".

也就是说,线高由顶部到底部,上半部分+高度(上升)+深度(下降)+下半部分引导组成.

可以针对给定大小的给定字体计算每个组件的高度.

基本上,每种字体都有字体度量,指定高于基线的特征高度和低于它的深度.

以宋体'为例,使用FontForge,我们看到它有Em Size2048,HHead Ascent如1825年,并HHead Descent为-443.也就是说,1825 / 2048 = 89.1%font-size有助于上升,并443 / 2048 = 21.6%有助于下降.

FontForge

还有以"Typo"开头的指标,如果选中"真正使用错字指标",则会使用该类别,并且规范建议:

注意.建议使用OpenType或TrueType字体的实现使用字体的OS/2表中的指标"sTypoAscender"和"sTypoDescender"进行A和D(在缩放到当前元素的字体大小之后).如果没有这些指标,则应使用HHEA表中的"Ascent"和"Descent"指标.

线高减去上升和下降是所谓的领先.

领先的一半加在A(上升)之上,另一半加在D之下(下降).

假设一个font-family: Times New Roman; font-size: 100px; line-height: 200px;,我们得到

ascent = 100px * (1825 / 2048) = 89px
descent = 100px * (443 / 2048) = 22px
top half-leading = bottom half-leading = (200px - 89px - 22px) / 2 = 44.5px
Run Code Online (Sandbox Code Playgroud)

所以我们看到这可以计算出来.这也可以在页面上测量.

这是另一个让你摆弄的演示.

如果你要求下半场前移,它会在代码片段中显示为绿线和蓝线之间的空格.如果您要求下降和下半场前移,它会在代码片段中显示为红线和蓝线之间的空格.

var $ = document.querySelector.bind(document);

var fontFamily = window.getComputedStyle($('#examinee'))['font-family']
  , fontSize = +window.getComputedStyle($('#examinee'))['font-size'].replace('px', '')
  , containerLineHeight = +window.getComputedStyle($('#examinee'))['line-height'].replace('px', '')
  , textLineHeight = $('.target').offsetHeight
  , ascent = $('#examinee .baseline').offsetTop + $('#examinee .baseline').offsetHeight - $('#examinee .text-top').offsetTop
  , descent = $('#examinee .text-bottom').offsetTop - $('#examinee .baseline').offsetTop
  , topHalfLeading = $('#examinee .text-top').offsetTop
  , bottomHalfLeading = $('#examinee').offsetHeight - 2/* borders of the container */ - $('#examinee .text-bottom').offsetTop - $('#examinee .text-bottom').offsetHeight;

$('#font-family').innerText = fontFamily;
$('#font-size').innerText = fontSize + 'px';
$('#container-line-height').innerText = containerLineHeight + 'px';
$('#text-line-height').innerText = textLineHeight + 'px';
$('#ascent').innerText = ascent + 'px';
$('#descent').innerText = descent + 'px';
$('#top-half-leading').innerText = topHalfLeading + 'px';
$('#bottom-half-leading').innerText = bottomHalfLeading + 'px';
Run Code Online (Sandbox Code Playgroud)
div {
  font-size: 20px;
  line-height: 2;
  width: 650px;
  
  border: 1px dashed gray;
  border-top: 1px solid blue;
  border-bottom: 1px solid blue;
  margin: 1rem 0;
  overflow: hidden;
  white-space: nowrap;
}

span:not([class]) {
  display: inline-block;
  border: 1px dashed gray;
}

.baseline,
.text-bottom,
.text-top {
  display: inline-block;
  width: 200%;
  margin: 0 -100%;
}

.baseline {
  border-bottom: 1px solid red;
  vertical-align: baseline;  /* the default */
}

.text-bottom {
  border-bottom: 1px solid green;
  vertical-align: text-bottom;
}

.text-top {
  border-bottom: 1px solid green;
  vertical-align: text-top;
}

#examinee {
  position: relative;
  font-size: 100px;
  line-height: 200px;
}
Run Code Online (Sandbox Code Playgroud)
<p>
  Demonstrates that "overflow: hidden;" sets baseline of an inline-block element to its bottom margin.
</p>
<div>
  <span class="baseline"></span>
  <span class="text-top"></span>
  <span class="text-bottom"></span>
  &lt;div&gt;
  <span>
    &lt;span style=""&gt;&lt;/span&gt;
  </span>
  &lt;/div&gt;
</div>
<div>
  <span class="baseline"></span>
  <span class="text-top"></span>
  <span class="text-bottom"></span>
  &lt;div&gt;
  <span style="overflow: hidden;">
    &lt;span style="overflow: hidden;"&gt;&lt;/span&gt;
  </span>
  &lt;/div&gt;
</div>

<p>
  Demonstrates the position of baseline, text-top and text-bottom. <br>
  Demonstrates how "line-height" affects box sizing.
</p>

<ul>
  <li>Blue lines: top and bottom borders of line boxes
  <li>Red lines: baseline of texts
  <li>Green lines: text-top or text-bottom of texts
</ul>

<ul>
  <li>Between blue lines: the line-height
  <li>Between red line and green line: ascent or descent
</ul>

<div id="examinee">
  <span class="target">GgJjPpQqYy</span>
  <span class="baseline"></span>
  <span class="text-top"></span>
  <span class="text-bottom"></span>
</div>


Measured metrics:
<ul>
  <li>font-family: <span id="font-family"></span></li>
  <li>font-size: <span id="font-size"></span></li>
  <li>container line-height: <span id="container-line-height"></span></li>
  <li>text line-height: <span id="text-line-height"></span></li>
  <li>ascent: <span id="ascent"></span></li>
  <li>descent: <span id="descent"></span></li>
  <li>top half-leading: <span id="top-half-leading"></span></li>
  <li>bottom half-leading: <span id="bottom-half-leading"></span></li>
</ul>
Run Code Online (Sandbox Code Playgroud)
线高测量