offsetHeight vs clientHeight vs scrollHeight in JS

When working with DOM elements in JavaScript, determining an element’s size requires choosing the right dimension property. While offsetHeight, clientHeight, and scrollHeight all return measurements in pixels, they differ fundamentally in how they handle borders, padding, scrollbars, and overflowing content. This guide breaks down exactly what each property measures, how they differ, and when to use each one.


1. clientHeight

clientHeight returns the inner height of an element in pixels. It represents the visible area of the content and its padding, excluding borders, margins, and any horizontal scrollbar.

Best used for: Measuring the visible, usable content area within an element (e.g., determining the viewport size of a custom UI container).


2. offsetHeight

offsetHeight represents the total visual height of the element as rendered on the screen. It captures the complete outer box of the element, including its visible content, padding, borders, and horizontal scrollbar.

Best used for: Layout calculations, collision detection, or determining the physical space an element occupies in the document flow.


3. scrollHeight

scrollHeight measures the total height of an element’s content, including content that is not currently visible on the screen due to overflow. If an element has no scrollable overflow, its scrollHeight is equal to its clientHeight.

Best used for: Detecting scroll progress, implementing infinite scrolling, or checking if an element has overflowing content (element.scrollHeight > element.clientHeight).


Quick Comparison

Property Content Height Padding Borders Scrollbar Hidden Overflow
clientHeight Visible only Yes No No No
offsetHeight Visible only Yes Yes Yes No
scrollHeight Total (Visible + Hidden) Yes No No Yes

Example: Detecting When a User Scrolls to the Bottom

A common scenario combining these properties is checking whether a user has scrolled to the bottom of a container:

const element = document.getElementById('scrollable-container');

element.addEventListener('scroll', () => {
  // Check if the scroll position + visible height equals total scrollable height
  const isAtBottom = element.scrollTop + element.clientHeight >= element.scrollHeight;

  if (isAtBottom) {
    console.log('Reached the bottom of the container');
  }
});