W3docs

Tamaños de ventana y desplazamiento en JavaScript

Aprende a medir el viewport, obtener el tamaño del documento y controlar el desplazamiento programáticamente con JavaScript.

Comprender las dimensiones de la ventana y el comportamiento del desplazamiento es esencial para construir interfaces web responsivas. Este artículo explica cómo medir el viewport (el área visible de la página), cómo leer el tamaño completo del documento, cómo averiguar cuánto se ha desplazado la página y cómo desplazarse programáticamente — incluyendo el desplazamiento suave y el desplazamiento hacia un elemento. Cada concepto incluye un ejemplo ejecutable.

La distinción clave que hay que tener en cuenta: el viewport es lo que el usuario puede ver en este momento, mientras que el documento es la página completa, de la cual la mayor parte puede estar fuera de la vista.

Medir el viewport (la ventana visible)

El viewport es el rectángulo de la página que el usuario ve en este momento. Hay dos formas de leer su tamaño, y la diferencia importa.

  • document.documentElement.clientWidth / clientHeight — el ancho y alto del viewport excluyendo la barra de desplazamiento. Esta es la opción correcta cuando necesitas el área real disponible para el contenido.
  • window.innerWidth / innerHeight — el interior completo de la ventana incluyendo el ancho de la barra de desplazamiento. Útil para comprobaciones rápidas, pero puede ser unos píxeles mayor que clientWidth cuando hay una barra de desplazamiento.

Usa clientWidth/clientHeight cuando hagas cálculos de maquetación (p. ej., centrar un elemento); usa innerWidth/innerHeight para comprobaciones de tipo breakpoint donde unos pocos píxeles no importan.

// Viewport size excluding the scrollbar (recommended for layout)
console.log(document.documentElement.clientWidth);
console.log(document.documentElement.clientHeight);

// Window interior including the scrollbar
console.log(window.innerWidth);
console.log(window.innerHeight);

El siguiente ejemplo muestra el tamaño del viewport en tiempo real y se actualiza cada vez que se redimensiona la ventana.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Window Size Display</title>
</head>
<body>
    <div id="window-info"></div>
    <script>
        function displayWindowSize() {
            const w = document.documentElement.clientWidth;
            const h = document.documentElement.clientHeight;
            document.getElementById('window-info').innerHTML =
                'Viewport width: ' + w + 'px<br>' +
                'Viewport height: ' + h + 'px';
        }
        window.addEventListener('resize', displayWindowSize);
        window.addEventListener('load', displayWindowSize);
    </script>
</body>
</html>

Medir el tamaño completo del documento

Para obtener la altura de la página completa — incluida la parte desplazada fuera de la vista — lee las propiedades scroll* del elemento del documento. Debido a inconsistencias históricas entre navegadores, la manera fiable es tomar el máximo de varias mediciones:

const scrollHeight = Math.max(
  document.body.scrollHeight, document.documentElement.scrollHeight,
  document.body.offsetHeight, document.documentElement.offsetHeight,
  document.body.clientHeight, document.documentElement.clientHeight
);
console.log('Full document height: ' + scrollHeight);

Este es exactamente el valor que necesitas para construir una barra de progreso, un disparador de desplazamiento infinito ("¿estoy cerca del final?") o un botón "ir al final". scrollWidth funciona de la misma manera para el desbordamiento horizontal.

Leer la posición de desplazamiento actual

Para averiguar cuánto se ha desplazado la página, usa:

  • window.scrollX — desplazamiento horizontal en píxeles (también llamado window.pageXOffset, un alias más antiguo).
  • window.scrollY — desplazamiento vertical en píxeles (alias window.pageYOffset).

scrollX/scrollY son los nombres modernos; pageXOffset/pageYOffset son idénticos y siguen siendo compatibles por compatibilidad con versiones anteriores.

console.log(window.scrollX); // same as window.pageXOffset
console.log(window.scrollY); // same as window.pageYOffset

Desplazamiento programático

La ventana expone tres métodos para mover la página por tu cuenta.

  • window.scrollTo(x, y) — se desplaza a una posición absoluta. scrollTo(0, 0) vuelve al inicio.
  • window.scrollBy(dx, dy) — se desplaza de forma relativa a la posición actual. scrollBy(0, 100) mueve 100px hacia abajo desde donde estés.
  • element.scrollIntoView() — desplaza la página para que un elemento específico quede visible.

Los tres aceptan un objeto de opciones con behavior: 'smooth' para un desplazamiento animado en lugar de un salto instantáneo:

// Smoothly scroll back to the top of the page
window.scrollTo({ top: 0, left: 0, behavior: 'smooth' });

// Nudge the page down by one viewport height
window.scrollBy({ top: window.innerHeight, behavior: 'smooth' });

Desplazamiento suave hacia un elemento

scrollIntoView es la forma más sencilla de ir a una sección — por ejemplo, un botón "volver arriba" o "ir a los comentarios". Pasar { behavior: 'smooth' } anima el movimiento:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Smooth Scrolling</title>
</head>
<body>
    <button onclick="document.getElementById('target').scrollIntoView({ behavior: 'smooth' });">Go to Target</button>
    <div style="height: 2000px;">
        <div id="target" style="margin-top: 1800px;">Target Element</div>
    </div>
</body>
</html>

Seguimiento de la posición de desplazamiento

Crea efectos dinámicos basados en la posición de desplazamiento del usuario. El siguiente ejemplo actualiza un elemento fijo para mostrar el desplazamiento vertical actual en cada evento scroll.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Scroll Position Detector</title>
</head>
<body>
    <div style="height: 3000px;">
      <div style="position: fixed;">Scroll position: <span id="position">0</span>px</div>
    </div>
    <script>
        const positionSpan = document.getElementById('position');
        window.addEventListener('scroll', function() {
            positionSpan.innerHTML = window.scrollY;
        });
    </script>
</body>
</html>

Nota: Para mayor compatibilidad con navegadores, document.documentElement.scrollTop puede usarse como alternativa a window.scrollY.

Encontrar la posición de un elemento con getBoundingClientRect

element.getBoundingClientRect() devuelve el tamaño del elemento y su posición relativa al viewport (no al documento). El objeto devuelto tiene top, bottom, left, right, width y height.

Dado que los valores son relativos al viewport, cambian conforme se desplaza la página. Para convertir la posición de un elemento a coordenadas del documento, añade el desplazamiento actual:

const box = element.getBoundingClientRect();

// Distance from the top of the viewport (changes while scrolling)
console.log(box.top);

// Distance from the top of the whole document (stable)
const documentTop = box.top + window.scrollY;
console.log(documentTop);

Un uso habitual es comprobar si un elemento está actualmente visible en la pantalla:

function isInViewport(el) {
  const r = el.getBoundingClientRect();
  return r.top >= 0 &&
         r.bottom <= document.documentElement.clientHeight;
}

Para profundizar en la diferencia entre coordenadas del viewport y del documento, consulta Coordenadas en JavaScript.

Personalizar las barras de desplazamiento para mejorar la estética

Las barras de desplazamiento personalizadas pueden mejorar el atractivo visual de tu sitio web:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Custom Scrollbars</title>
    <style>
        body {
            height: 2000px; /* For demonstration */
        }
        /* Custom scrollbar styling */
        ::-webkit-scrollbar {
            width: 12px;
        }
        ::-webkit-scrollbar-track {
            background: darkblue;
        }
        ::-webkit-scrollbar-thumb {
            background-color: lightgreen;
            border-radius: 10px;
            border: 3px solid darkcyan;
        }
    </style>
</head>
<body>
    Scroll to see the custom scrollbar!
</body>
</html>

En este ejemplo usamos pseudoelementos para seleccionar y dar estilo a las distintas partes de la barra de desplazamiento. A continuación se explica cada propiedad CSS utilizada:

  • ::-webkit-scrollbar: Este pseudoelemento apunta a la barra de desplazamiento en sí. Hemos establecido su ancho en 12 píxeles, lo que determina el grosor de la barra de desplazamiento.
  • ::-webkit-scrollbar-track: Este pseudoelemento representa la pista (o ranura) por la que se mueve el thumb de la barra de desplazamiento. Le hemos dado un fondo azul oscuro. Los colores usados aquí se han elegido para mostrar la diferencia entre cada parte de la barra de desplazamiento. Se recomiendan colores más sutiles para una aplicación en el mundo real.
  • ::-webkit-scrollbar-thumb: Este pseudoelemento apunta a la parte arrastrable de la barra de desplazamiento, conocida como thumb. Hemos elegido verde claro para el thumb, lo que lo hace destacar sobre la pista para una mejor visibilidad. border-radius: 10px aplica esquinas redondeadas al thumb, dándole un aspecto moderno y elegante. También se usa un borde de 3 píxeles sólido de color cian oscuro.

Nota: Los pseudoelementos ::-webkit-scrollbar son específicos de los navegadores basados en Chromium. Para Firefox y los estándares modernos, considera usar las propiedades CSS scrollbar-width y scrollbar-color. Ejemplo: scrollbar-width: thin; scrollbar-color: lightgreen darkblue;

Conclusión

Dominando las técnicas de dimensionado de ventana y desplazamiento en JavaScript, puedes mejorar significativamente la experiencia de usuario y la responsividad de tus proyectos web. Recuerda la distinción fundamental: clientWidth/clientHeight miden el viewport visible, las propiedades scroll* miden el documento completo, y scrollX/scrollY (alias pageXOffset/pageYOffset) indican cuánto se ha desplazado la página. Usa scrollTo, scrollBy y scrollIntoView con behavior: 'smooth' para mover la página por tu cuenta.

Para continuar, explora:

Práctica

Práctica
¿Qué métodos se pueden usar para medir los tamaños y los desplazamientos en JavaScript?
¿Qué métodos se pueden usar para medir los tamaños y los desplazamientos en JavaScript?
Was this page helpful?