JavaScript height: работа с высотой элементов
Высота элементов в JavaScript: методы и свойства
Как получить общую высоту элемента с учетом границ и полей?
Свойство offsetHeight возвращает целое число, равное высоте элемента, включая padding, border и горизонтальную полосу прокрутки (если она отображается). Это наиболее простой и производительный способ, не требующий пересчета стилей. Оно подходит для большинства случаев, когда нужна точная высота в пикселях, округленная до целого.
const element = document.getElementById('myDiv');
console.log(element.offsetHeight); // 200 (например)Js height (высота в javascript)
Проблемы: offsetHeight не учитывает margin, возвращает 0 для скрытых элементов (display: none), зависит от box-sizing (стандартный border-box). Для дробных значений используйте getBoundingClientRect.
Когда использовать: при позиционировании, проверке видимости, работе с Drag & Drop, вычислении прокрутки.
Как получить высоту видимой области содержимого (без границ)?
Свойство clientHeight возвращает высоту видимой части элемента, включая padding, но без border, margin и полосы прокрутки. Полезно для определения области, доступной для отображения контента.
const element = document.getElementById('myDiv');
console.log(element.clientHeight); // 180 (padding включён)
Проблемы: не учитывает подскролленный контент, не работает с элементами с overflow: hidden (возвращает видимую высоту).
Цель: измерение области просмотра элемента, расчет положения скроллбара, определение переполнения.
Как получить полную высоту элемента вместе с прокручиваемым содержимым?
Свойство scrollHeight возвращает высоту всего содержимого элемента, включая ту часть, которая скрыта за скроллом. Применяется для проверки переполнения и динамического изменения размеров.
const element = document.getElementById('scrollableDiv');
console.log(element.scrollHeight); // 800 (если контент высокий)
Ошибка: если элемент скрыт (display: none), scrollHeight тоже равен 0. Для вычислений используйте временное отображение.
Случаи: создание «читай дальше», автоматическое расширение textarea, определение необходимости прокрутки.
Как получить точные дробные значения высоты с учетом трансформаций?
Метод element.getBoundingClientRect() возвращает объект DOMRect с дробными координатами и размерами (height, width) относительно viewport. Учитывает CSS-трансформации (scale, rotate).
const rect = element.getBoundingClientRect();
console.log(rect.height); // 202.5 (дробное)
Проблемы: вызов метода немного медленнее прямого чтения свойства; возвращает высоту после применения трансформаций, что может быть неожиданно, если элемент масштабирован.
Когда использовать: при точном позиционировании в пределах viewport, работе с канвасом, SVG, анимации с transform.
Как получить высоту, заданную в CSS (включая единицы em, %)?
Свойство element.style.height возвращает только инлайн-высоту. Для вычисленного значения используется getComputedStyle(element).height, которое возвращает строку с px (даже если задано в %).
const style = getComputedStyle(element);
console.log(style.height); // '200px'
Важно: getComputedStyle не возвращает дробные пиксели в старых браузерах; для auto возвращает 'auto', что бесполезно. Для скрытых элементов (display: none) возвращает 'auto' или 0.
Цель: отладка, сопоставление с CSS-правилами, сброс стилей.
Расширенные примеры работы с высотой
Пример 1: Измерение высоты элемента с трансформацией (scale)
Метод getBoundingClientRect учитывает CSS-трансформации, offsetHeight - нет. Это важно при анимации масштаба.
<div id="scaled" style="transform: scale(0.5); width: 200px; height: 100px;"></div>
const el = document.getElementById('scaled');
console.log('offsetHeight:', el.offsetHeight); // 100 (без масштаба)
console.log('getBoundingClientRect:', el.getBoundingClientRect().height); // 50 (с учётом scale 0.5)
offsetHeight: 100 getBoundingClientRect: 50
Пример 2: Получение высоты скрытого элемента (display: none)
Для скрытых элементов offsetHeight, clientHeight, scrollHeight равны 0. Чтобы измерить, можно временно показать элемент, измерить и скрыть, или использовать getComputedStyle, если высота задана явно.
const hidden = document.getElementById('hiddenDiv');
// Сохраняем текущие стили
const display = hidden.style.display;
hidden.style.display = 'block';
const h = hidden.offsetHeight;
hidden.style.display = display;
console.log('Высота скрытого:', h);
Высота скрытого: 150
Пример 3: Анимация высоты с плавным изменением и ресайзом
Используем requestAnimationFrame для отслеживания текущей высоты и ResizeObserver для реагирования на изменения.
const animDiv = document.getElementById('anim');
let startHeight = animDiv.offsetHeight;
let targetHeight = 300;
function animate() {
let current = animDiv.offsetHeight;
if (current < targetHeight) {
animDiv.style.height = (current + 2) + 'px';
requestAnimationFrame(animate);
}
}
// Отслеживание изменений через ResizeObserver
const observer = new ResizeObserver(entries => {
for (let entry of entries) {
console.log('Новая высота:', entry.contentRect.height);
}
});
observer.observe(animDiv);
animate();
Новая высота: 150 Новая высота: 152 ... Новая высота: 300
Пример 4: Определение высоты с учетом box-sizing и padding
Если элемент использует box-sizing: border-box, то height в CSS включает padding и border. offsetHeight совпадает с заданной высотой. Для content-box height содержит только контент.
<div id="box1" style="box-sizing: content-box; height: 100px; padding: 20px; border: 5px solid;"></div>
<div id="box2" style="box-sizing: border-box; height: 100px; padding: 20px; border: 5px solid;"></div>
const b1 = document.getElementById('box1');
const b2 = document.getElementById('box2');
console.log('content-box offsetHeight:', b1.offsetHeight); // 100 + 40 + 10 = 150
console.log('border-box offsetHeight:', b2.offsetHeight); // 100 (включает padding и border)
content-box offsetHeight: 150 border-box offsetHeight: 100
Пример 5: Получение высоты до полной загрузки изображений (layout shift)
Для элементов с изображениями offsetHeight может измениться после загрузки. Используем событие load или ResizeObserver для фиксации конечной высоты.
<img id="img" src="http://placehold.it/400x300" />
const img = document.getElementById('img');
console.log('до загрузки:', img.offsetHeight); // 0 или 22 (placeholder)
img.addEventListener('load', () => {
console.log('после загрузки:', img.offsetHeight); // 300
});
до загрузки: 22 после загрузки: 300