Почему элемент scrollHeight и clientHeight не то же самое для некоторых шрифтов?

Для некоторых шрифтов, когда line-height элемента меньше порога, scrollHeight больше, чем clientHeight.

Итак, что-то в свойствах шрифта вызывает это, но что это такое и как его можно избежать, предпочтительно используя CSS или даже редактор шрифтов для пользовательских шрифтов?

Например, в этом фрагменте scrollHeight для Tahoma больше, чем clientHeight хотя sans-serif кажется ОК, когда line-height равна 1. Это различие увеличивается, когда страница увеличена в Chrome (ctrl+) и происходит даже для sans-serif, Когда высота линии ниже 1 или размер шрифта увеличивается, разница увеличивается.

Для некоторых других шрифтов он поднимается до 5 пикселей на высоте линии 1 и уменьшается, увеличивая высоту линии до 2, что приводит к некорректному вычислению.

var a = document.getElementById('a');
console.log('tahoma - a.clientHeight: ' + a.clientHeight);
console.log('tahoma - a.scrollHeight: ' + a.scrollHeight);

var b = document.getElementById('b');
console.log('sans - b.clientHeight: ' + b.clientHeight);
console.log('sans - b.scrollHeight: ' + b.scrollHeight);

var c = document.getElementById('c');
console.log('sans - lineHeight:0.5 - c.clientHeight: ' + c.clientHeight);
console.log('sans - lineHeight:0.5 - c.scrollHeight: ' + c.scrollHeight);

var d = document.getElementById('d');
console.log('sans - font-size:200px - d.clientHeight: ' + d.clientHeight);
console.log('sans - font-size:200px - d.scrollHeight: ' + d.scrollHeight);
div[id] {
 overflow:auto;
 max-width:80%;
}
<div id='a' style='font-family:tahoma; line-height:1;'>Hello</div>
<div id='b' style='font-family:sans-serif; line-height:1;'>Hello</div>
<div id='c' style='font-family:sans-serif; line-height:0.5;'>Hello</div>
<div id='d' style='font-family:sans-serif; line-height: 1; font-size:500px;'>Hello</div>

Ответ 1

Я обнаружил, что scrollHeight является измерением высоты содержимого элемента, включая контент, невидимый на экране из-за переполнения, а clientHeight - это измерение высоты элемента.

Когда вы уменьшаете высоту линии, высота элемента div становится меньше - поэтому значение clientHeight будет меньше, но высота контента не будет изменена, поэтому scrollHeight останется прежним, поэтому это является причиной того, что ваши 2 измерения отличаются.

Если вы хотите, чтобы 2 разных измерения дали одинаковые результаты, вам нужно будет изменить высоту элемента контейнера. Например, добавьте в div min-height: 1.2em

var a = document.getElementById('a');
console.log('tahoma - a.clientHeight: ' + a.clientHeight);
console.log('tahoma - a.scrollHeight: ' + a.scrollHeight);

var c = document.getElementById('c');
console.log('sans - lineHeight:0.5 - c.clientHeight: ' + c.clientHeight);
console.log('sans - lineHeight:0.5 - c.scrollHeight: ' + c.scrollHeight);
.div {
  font-size: 40px;
  margin: 10px;
  border: 1px solid black;
  min-height: 1.2em;
}
<div class='div' id='a' style='font-family:tahoma; line-height:1;'>Hello</div>
<div class='div' id='c' style='font-family:sans-serif; line-height:0.5;'>Hello</div>

Ответ 2

Чтобы сделать проблему более заметной, введите span внутри div и добавьте границу/фон. Давайте начнем с использования большой line-height:

body {
 font-family:sans-serif;
}
div {
  border:1px solid;
  margin:10px;
}
span {
  background:red;
}
<div style='line-height:3;'><span>Hello</span></div>