Command Palette

Search for a command to run...

Dimensiones del DOM: Offset, Client y Scroll en JavaScript

Domina las propiedades de medición del DOM: offset para tamaño total, client para área interna, scroll para contenido desbordado, viewport dimensions y casos de uso prácticos.

Lectura: 15 min
Nivel: Intermedio

TL;DR - Resumen rápido

  • offsetWidth/Height: Tamaño total visible del elemento (content + padding + border + scrollbar).
  • clientWidth/Height: Área interior útil (content + padding), excluye border y scrollbar.
  • scrollWidth/Height: Tamaño total del contenido, incluyendo el desbordado (overflow).
  • scrollTop/Left son lectura/escritura, permiten scroll programático con asignación directa.
  • Usa scrollIntoView(), scrollTo() y scrollBy() para scroll animado y suave con behavior: 'smooth'.
  • Todos retornan enteros redondeados; para precisión decimal usa getBoundingClientRect().
  • offsetParent es el ancestro posicionado más cercano (position !== static) para calcular offsetTop/Left.

El Box Model en JavaScript

En CSS, definimos width y height, pero en JavaScript la realidad es más compleja debido al box model. Un elemento tiene múltiples "dimensiones" dependiendo de qué quieras medir: ¿el tamaño total incluyendo el borde? ¿solo el área interior útil? ¿el contenido completo aunque esté oculto por overflow? El DOM ofrece tres familias de propiedades para responder a estas preguntas.

Cada familia de propiedades (offset, client, scroll) mide diferentes aspectos del elemento, y elegir la correcta es crucial para implementar features como scroll infinito, lazy loading, posicionamiento dinámico o detección de visibilidad. Confundir estas propiedades es una fuente común de bugs en aplicaciones web.

  • <strong>offset*</strong>: Dimensión total visible (border + padding + content + scrollbar). Útil para colisiones y posicionamiento.
  • <strong>client*</strong>: Área interior útil (padding + content). Excluye border y scrollbar. Útil para contenido disponible.
  • <strong>scroll*</strong>: Tamaño total del contenido (visible + oculto por overflow). Útil para detectar desbordamiento.

offset: La Caja Completa

Las propiedades offsetWidth y offsetHeight te dan el tamaño "físico" que ocupa el elemento en la pantalla.

offset-dims.js
Loading code...

Este código muestra cómo offsetWidth y offsetHeight incluyen todo el espacio visual del elemento: contenido, padding, border y scrollbar si existe. Es el tamaño "real" que ocupa en la página. También introduce offsetTop y offsetLeft, que miden la distancia desde el borde exterior del elemento hasta su offsetParent.

¿Qué incluye offset?

Content + Padding + Border + Scrollbar (si existe). NO incluye Margin. Es el tamaño total "borde a borde" del elemento.

offsetParent: El Contexto de Posicionamiento

offsetTop y offsetLeft no miden desde la esquina de la página, sino desde el offsetParent del elemento. El offsetParent es el ancestro posicionado más cercano (con position: relative, absolute, fixed o sticky). Si no hay ninguno, es el body o html.

offsetparent.js
Loading code...

Entender offsetParent es fundamental para calcular posiciones absolutas correctamente. Si intentas posicionar un tooltip o dropdown sin considerar el offsetParent, terminarás con coordenadas incorrectas, especialmente en layouts complejos con múltiples contenedores posicionados.

client: El Área Interna

clientWidth y clientHeight miden el espacio disponible dentro de los bordes. Es útil para saber cuánto espacio tienes para dibujar o colocar contenido.

client-dims.js
Loading code...

Las propiedades client* te dan el área interior útil del elemento, excluyendo borders y scrollbars. Es el espacio disponible para el contenido. Además, clientTop y clientLeft te dicen el grosor del borde superior e izquierdo respectivamente, lo cual es útil para cálculos de posicionamiento precisos.

Área client: lo interior

Content + Padding. NO incluye border ni scrollbar. Es el espacio donde el contenido realmente vive.

scroll: El Contenido Total

A veces un elemento tiene más contenido del que puede mostrar (overflow). scrollWidth y scrollHeight te dicen cuánto mediría el elemento si todo el contenido fuera visible sin barras de desplazamiento.

scroll-dims.js
Loading code...

El código muestra cómo detectar si un elemento tiene contenido desbordado comparando scrollHeight con clientHeight. También introduce scrollTop y scrollLeft, propiedades de lectura/escritura que permiten tanto leer cuánto se ha scrolleado como hacer scroll programático asignando valores directamente.

Métodos de Scroll Programático

Además de asignar valores a scrollTop y scrollLeft, JavaScript ofrece métodos más potentes y flexibles para controlar el scroll, incluyendo animaciones suaves y scroll a elementos específicos.

scroll-methods.js
Loading code...

scrollTo() y scrollBy() aceptan un objeto con behavior: 'smooth' para crear animaciones suaves, muy superior a la asignación directa de scrollTop. scrollIntoView() es especialmente útil para navegar a secciones específicas, como en un sistema de anclas o "scroll to top". El parámetro block controla la alineación vertical del elemento.

Casos de Uso Prácticos

Las propiedades de dimensión y scroll son fundamentales para implementar patrones comunes en aplicaciones web modernas. Aquí están los casos de uso más frecuentes que encontrarás en producción.

practical-cases.js
Loading code...

Estos patrones son omnipresentes en aplicaciones web: el scroll infinito para feeds sociales, lazy loading para optimizar carga de imágenes, y detección de llegada al final para botones "cargar más". La clave es entender qué propiedades combinar para cada caso: scrollTop + clientHeight ≈ scrollHeight significa "llegamos al final".

Performance tip

Usa IntersectionObserver para lazy loading en lugar de listeners de scroll cuando sea posible. Es más eficiente porque no requiere cálculos manuales y no bloquea el thread principal.

Dimensiones del Viewport

Medir el viewport (la ventana visible del navegador) es diferente a medir elementos individuales. JavaScript ofrece varias propiedades para esto, cada una con sutilezas importantes que debes conocer.

viewport-dimensions.js
Loading code...

La diferencia principal es que window.innerWidth incluye la scrollbar, mientras que document.documentElement.clientWidth la excluye. En la mayoría de casos prácticos, querrás window.innerWidth para responsive design, pero clientWidth si necesitas el espacio exacto disponible para contenido.

offset/client/scroll vs getBoundingClientRect()

Existe otra API para medir elementos: getBoundingClientRect(). Aunque similar, tiene diferencias cruciales que determinan cuándo usar cada una.

comparison-getboundingclientrect.js
Loading code...

La diferencia clave es que offset/client/scroll retornan enteros redondeados, mientras que getBoundingClientRect() retorna valores decimales con precisión sub-pixel. Además, getBoundingClientRect() incluye transformaciones CSS (scale, rotate), mientras que offsetWidth no. Usa getBoundingClientRect() para posicionamiento relativo al viewport y detección de visibilidad.

  1. <strong>offset/client/scroll</strong>: Valores enteros, no consideran transforms, más rápidos, útiles para dimensiones brutas.
  2. <strong>getBoundingClientRect()</strong>: Valores decimales, consideran transforms CSS, relativos al viewport, útiles para posicionamiento visual preciso.

Errores Comunes que Debes Evitar

Trabajar con dimensiones del DOM tiene varias trampas que pueden causar bugs sutiles o mediciones incorrectas. Estos son los errores más frecuentes.

common-mistakes.js
Loading code...

El error más común es confundir qué incluye cada propiedad (border, scrollbar, etc.). Otro error frecuente es leer dimensiones durante animaciones o transiciones, cuando los valores pueden estar cambiando. Siempre espera a que las animaciones terminen, o usa getBoundingClientRect() si necesitas valores en tiempo real durante la animación.

Box-sizing: border-box

Con box-sizing: border-box, el width de CSS incluye padding y border. Sin embargo, offsetWidth SIEMPRE incluye border y padding, independientemente de box-sizing. No confundas el modelo CSS con las propiedades JavaScript.

Resumen: Dimensiones y Scroll del DOM

Conceptos principales:

  • offsetWidth/Height: Tamaño total (content + padding + border + scrollbar). Borde a borde.
  • clientWidth/Height: Área interior (content + padding). Excluye border y scrollbar.
  • scrollWidth/Height: Tamaño total del contenido, incluyendo desbordado por overflow.
  • offsetParent: Ancestro posicionado más cercano (position !== static) para calcular offsetTop/Left.
  • Todas retornan enteros redondeados. Para decimales usa getBoundingClientRect().

Mejores prácticas:

  • Usa scrollIntoView({behavior: 'smooth'}) para scroll animado en lugar de asignación directa.
  • Compara scrollTop + clientHeight ≈ scrollHeight para detectar scroll al final (scroll infinito).
  • Prefiere IntersectionObserver sobre listeners de scroll para lazy loading (mejor performance).
  • Usa getBoundingClientRect() para posicionamiento relativo al viewport o cuando necesites precisión decimal.
  • window.innerWidth incluye scrollbar; document.documentElement.clientWidth la excluye.