绝对位置增加元素的高度

时间:2020-10-07 23:58:30

标签: javascript html css

我试图找出一种方法来计算印刷动画在给定字体大小下任何给定字体的基线,并注意到一些极其奇怪的事情:由于某种原因,当以下情况时,元素的高度值似乎以任意方式增加他们的位置更改为绝对。

没有绝对位置的高度(单击以控制台记录高度)

const
  small = document.querySelector('#small'),
  large = document.querySelector('#large')

window.onclick = () => {
  console.log(small.getBoundingClientRect().height,
              large.getBoundingClientRect().height)
}
div {
  border: solid purple 2px;
}

#small {
  border: solid red 2px;
}

#large {
  border: solid black 2px;
  font-size: 10rem;
}
<div>
  <span id='small'>.</span>
  <span id='large'>.</span>
</div>

具有绝对位置的高度(单击以控制台记录高度)

const
  small = document.querySelector('#small'),
  large = document.querySelector('#large')

window.onclick = () => {
  console.log(small.getBoundingClientRect().height,
              large.getBoundingClientRect().height)
}
div {
  border: solid purple 2px;
}

#small {
  border: solid red 2px;
}

#large {
  border: solid black 2px;
  font-size: 10rem;
}

span {
  position: absolute;
}
<div>
  <span id='small'>.</span>
  <span id='large'>.</span>
</div>

有人可以解释吗?

1 个答案:

答案 0 :(得分:2)

诀窍在显示屏内,您将无法找到所获得的高度之间的任何逻辑关系,因为在两种情况下,计算结果均不同。

在第一种情况下,您具有内联元素,并且此规则适用:

“ height”属性不适用。 内容区域的高度应基于字体,但是此规范未指定具体方式。 UA可以例如使用em-box或字体的最大升序和降序。 (后者将确保在em-box上方或下方具有部分文字的字形仍位于内容区域内,但导致不同字体的大小不同的box;前者将确保作者可以控制相对于'line-height'的背景样式。 ,但导致字形在其内容区域之外绘画。)

内联不可替换框的垂直填充,边框和边距从内容区域的顶部和底部开始,与“行高”无关。但是在计算线框的高度时仅使用'line-height'。 ref

因此跨度的高度仅取决于字体属性(字体系列,字体大小等)+边框的顶部/底部。除非您深入研究字体属性,否则您将无法找到精确计算高度的方法,这是一项困难的练习,尤其是当我们处理默认字体时,浏览器与其他字体(以及操作系统与另一个字体)是不同的。

相关:

Can specific text character change the line height?

What determines the space between the highest and lowest letter and the top and bottom border of the element the letter's in?


在第二种情况下,因为您创建了position:absolute,所以span现在是一个块元素,因此您需要遵循此处详述的规则:https://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height,这将导致我们使用以下规则:{ {3}}

如果它仅具有内联级别的子级,则高度为最顶部的线框顶部与最底部的线框底部之间的距离

因此,元素的高度现在是由line-height定义的线框的高度(如此处详细说明:https://www.w3.org/TR/CSS21/visudet.html#root-height)。不仅行高,而且内部元素的垂直对齐,但由于只有一个字符,因此您没有这种复杂性

默认的line-height由浏览器定义,但是如果您对其进行了修复,则会得到所需的高度:

const
  small = document.querySelector('#small'),
  large = document.querySelector('#large')

window.onclick = () => {
  console.log(small.getBoundingClientRect().height,
              large.getBoundingClientRect().height)
}
div {
  border: solid purple 2px;
}

#small {
  border: solid red 2px;
  line-height:1; /* will give a height = 1*16 + 4 */
}

#large {
  border: solid black 2px;
  font-size: 10rem;
  line-height:1; /* will give a height = 1*10*16 + 4 */
}

span {
  position: absolute;
}
<div>
  <span id='small'>.</span>
  <span id='large'>.</span>
</div>

相关:https://www.w3.org/TR/CSS21/visudet.html#line-height


如果您将span元素设为inline-block,您将获得与第二种情况相同的行为,因为您遵循此处的规则:How does height will be calculated, based on font-size?将使我们遵循相同的规则绝对元素(https://www.w3.org/TR/CSS21/visudet.html#block-root-margin),这意味着line-height将控制您的身高:

const
  small = document.querySelector('#small'),
  large = document.querySelector('#large')

window.onclick = () => {
  console.log(small.getBoundingClientRect().height,
              large.getBoundingClientRect().height)
}
div {
  border: solid purple 2px;
}

#small {
  border: solid red 2px;
  display:inline-block;
  line-height:1;
}

#large {
  border: solid black 2px;
  font-size: 10rem;
  display:inline-block;
  line-height:1;
}
<div>
  <span id='small'>.</span>
  <span id='large'>.</span>
</div>