Scroll Horizontal con CSS y JavaScript: Guía Completa Paso a Paso

- Andrés Cruz - EN In english

Scroll Horizontal con CSS y JavaScript: Guía Completa Paso a Paso

Muchas veces, cuando estamos diseñando una web, necesitamos apilar de manera horizontal una serie de tarjetas o contenedores y permitir que el usuario los desplace de izquierda a derecha. Aunque no se limita solo a contenedores: puede que quieras que toda tu web tenga una navegación horizontal, lo que se conoce como un sitio horizontal.

La web es, por naturaleza, vertical. Sin embargo, hay muchos escenarios reales donde apilar contenido horizontalmente y permitir un desplazamiento lateral tiene todo el sentido: galerías de imágenes, listas de productos, cards, planes de precios o incluso sitios completos con navegación horizontal.

El scroll horizontal con CSS es algo que he implementado varias veces en proyectos reales. Aunque suele parecer algo trivial, la realidad es que no basta con una sola propiedad CSS para que funcione bien, sea usable y no se rompa en distintos dispositivos ni tamaños de pantalla.

En esta guía te voy a enseñar cómo crear un scroll horizontal en CSS correctamente, cuándo usar cada técnica, qué errores evitar y cómo potenciarlo con un toque de JavaScript cuando realmente lo necesites.

Qué es el scrolling horizontal y cuándo usarlo

El scrolling horizontal es una técnica que permite al usuario desplazarse de izquierda a derecha dentro de un contenedor, en lugar del clásico scroll vertical. Parece simple, pero aplicado bien puede transformar completamente la experiencia de usuario en ciertos contextos.

Scroll horizontal vs. scroll vertical

  • Scroll vertical: ideal para lectura larga y navegación tradicional.
  • Scroll horizontal: perfecto para elementos visuales repetitivos, cards o contenido que se consume "en bloques".

No se trata de reemplazar el scroll vertical, sino de usarlo estratégicamente donde aporta valor.

Casos reales donde tiene sentido usarlo

Algunos escenarios donde suelo aplicarlo:

  • Listas de tarjetas (cards)
  • Carruseles sin dependencias de JS
  • Galerías de imágenes
  • Secciones mobile-first
  • Planes de precios o comparativas de características

Cómo crear un scroll horizontal con CSS (método clásico)

Esta es la técnica más simple, estable y compatible. La he usado muchas veces porque funciona sin JavaScript y sin hacks raros. Aunque parezca obvio, olvidar una de las propiedades clave es uno de los errores más comunes.

Veamos cómo crear un div con scroll horizontal como el del siguiente ejemplo:

animación de un Scrolling Horizontal con CSS

En realidad es bastante sencillo y no necesitas JavaScript ni ningún plugin mágico; solo hay unos pocos pasos que debes tener en mente. Eso sí, tampoco es tan simple como definir una sola regla CSS: hay que combinar varias propiedades correctamente. Los pasos son:

  1. Definir la altura (height) del contenedor padre.
  2. Indicar que no queremos scrolling vertical.
  3. Habilitar el scrolling horizontal.

Propiedades clave: overflow-x y overflow-y

Para los dos últimos pasos nos bastan un par de reglas CSS con sus valores correspondientes:

overflow-x: auto;
overflow-y: hidden;
  • overflow-x: auto habilita el scroll horizontal solo cuando el contenido desborda el contenedor.
  • overflow-y: hidden evita que aparezca una barra de scroll vertical no deseada.

El valor auto es preferible a scroll porque solo muestra la barra de desplazamiento cuando realmente hace falta; con scroll la barra aparece siempre, aunque el contenido quepa. Si configuras bien el CSS, el overflow-y: hidden puede llegar a ser opcional, aunque yo lo suelo poner por precaución.

El contenedor padre: tamaño, altura y white-space

El siguiente CSS corresponde al contenedor padre, que es el encargado de realizar el desplazamiento horizontal. Aquí definimos su tamaño y el ancho de una sola vez:

Propiedades del contenedor padre

width: auto;
height: 50px;
padding: 10px;
white-space: nowrap;

Básicamente establecemos el tamaño del contenedor y el espaciado interno. La propiedad white-space especifica cómo se maneja el espacio en blanco dentro del contenedor; con el valor nowrap indicamos que no debe haber saltos de línea, es decir, todo el contenido se muestra en una sola fila. Esta es, en mi experiencia, la propiedad más importante del scroll horizontal clásico.

Además, definimos una altura fija de 50px para el contenedor, mientras que el ancho lo dejamos en auto para que pueda crecer tanto como lo requiera el contenido.

Aquí está el resumen de las claves:

  • white-space: nowrap evita los saltos de línea y fuerza el contenido a una sola fila.
  • El ancho se adapta al contenido gracias a width: auto.
  • La altura fija evita desbordes extraños en el eje vertical.

Los elementos hijos y por qué display: inline-block es importante

Ahora definimos el CSS para los hijos del contenedor. El concepto es sencillo: estamos creando pequeñas cajas que deben permanecer en una misma línea:

.horizontal-scroll-contenedor div {
 width: 100px;
 height: 50px;
 margin-right: 10px;
 display: inline-block;
}

Puntos importantes:

  • display: inline-block mantiene todos los elementos alineados en una sola fila horizontal, en lugar de apilarse verticalmente como haría display: block.
  • El tamaño de los hijos no debe superar la altura del padre; si lo hace, el contenido se cortará.
  • El margin-right crea la separación visual entre cada elemento.

Ejemplo práctico de scroll horizontal con divs en HTML y CSS

Lo más importante es que los hijos tengan el mismo tamaño o menor al del padre, y que usen display: inline-block para permanecer en una misma línea. El resto del código es contextual y puedes consultarlo en los enlaces de descarga. Así quedaría el HTML:

<div class="horizontal-scroll-contenedor">
	<div>Contenedor 1</div>
	<div>Contenedor 2</div>
	<div>Contenedor 3</div>
	<div>Contenedor 4</div>
	<div>Contenedor 5</div>
	<div>Contenedor 6</div>
	<div>Contenedor 7</div>
	<div>Contenedor 8</div>
	<div>Contenedor 9</div>
	<div>Contenedor 10</div>
	<div>Contenedor 11</div>
	<div>Contenedor 12</div>
	<div>Contenedor 13</div>
	<div>Contenedor 14</div>
	<div>Contenedor 15</div>
	<div>Contenedor 16</div>
	<div>Contenedor 17</div>
	<div>Contenedor 18</div>
	<div>Contenedor 19</div>
	<div>Contenedor 20</div>
</div>

CSS completo en base a lo explicado:

.horizontal-scroll-contenedor {
 width: auto;
 height: 50px;
 padding: 10px;
 overflow-x: auto;
 overflow-y: hidden;
 white-space: nowrap;
}
.horizontal-scroll-contenedor div {
 width: 100px;
 height: 50px;
 margin-right: 10px;
 display: inline-block;
}

Y puedes ver el resultado a continuación:

Contenedor 1
Contenedor 2
Contenedor 3
Contenedor 4
Contenedor 5
Contenedor 6
Contenedor 7
Contenedor 8
Contenedor 9
Contenedor 10
Contenedor 11
Contenedor 12
Contenedor 13
Contenedor 14
Contenedor 15
Contenedor 16
Contenedor 17
Contenedor 18
Contenedor 19
Contenedor 20

Este patrón es sencillo, predecible y fácil de mantener, por eso sigo usándolo cuando no necesito efectos avanzados.

Scroll horizontal con Flexbox (la opción moderna)

Hoy en día, si tengo que elegir, Flexbox suele ser mi primera opción. Es más limpio, más semántico y elimina la necesidad de usar white-space e inline-block, que son propiedades que conceptualmente no están pensadas para maquetar layouts.

Por qué Flexbox simplifica el scroll horizontal

Con Flexbox el código queda mucho más legible. El contenedor solo necesita tres propiedades:

.flex-container {
 display: flex;
 flex-wrap: nowrap;
 overflow-x: auto;
}

Y para los elementos hijos:

.flex-item {
 flex: 0 0 auto;
}
  • flex-wrap: nowrap evita que los elementos salten de línea, de forma equivalente a white-space: nowrap en el método clásico.
  • flex: 0 0 auto mantiene el tamaño natural de cada elemento sin que Flexbox lo estire ni lo encoja. Los tres valores son: flex-grow: 0 (no crecer), flex-shrink: 0 (no encoger) y flex-basis: auto (respetar el tamaño declarado).

Cuándo elegir Flexbox frente a inline-block

  • Uso Flexbox cuando:
    • El layout es moderno y ya usa Flexbox en otros lugares.
    • Necesito alineación vertical de los elementos.
    • Quiero un código más limpio y legible.
  • Uso inline-block cuando:
    • Busco máxima compatibilidad con navegadores antiguos.
    • Es un proyecto pequeño o muy simple.
    • No quiero introducir Flexbox si el resto del código no lo usa.

Scroll snapping: el efecto imán al desplazarse

Aquí entramos en un nivel más avanzado. El scroll snapping es una técnica CSS que hace que, al terminar de desplazarse, el scroll se "enganche" automáticamente al elemento más cercano, como si tuviese un imán. El resultado se siente pulido y profesional, especialmente en móvil.

scroll-snap-type y scroll-snap-align

Estas dos propiedades crean el famoso efecto "imán":

.slider {
 display: flex;
 overflow-x: scroll;
 scroll-snap-type: x proximity;
}
.card {
 scroll-snap-align: center;
}
  • scroll-snap-type: x proximity activa el snap en el eje horizontal con cierta tolerancia; puedes cambiar proximity por mandatory si quieres que el snap sea siempre obligatorio.
  • scroll-snap-align: center alinea cada elemento al centro del contenedor al hacer snap. Otros valores posibles son start y end.

Esto es ideal para:

  • Experiencias mobile-first
  • Carruseles táctiles
  • Secciones tipo "planes" o "features"

Lo he usado bastante en proyectos responsive porque mejora muchísimo la experiencia en móvil sin necesidad de JavaScript.

Errores comunes al implementar el scroll horizontal

  • El scroll no aparece
    • Falta overflow-x: auto o overflow-x: scroll.
    • El contenido no desborda realmente el ancho del contenedor.
    • El ancho del contenedor tiene un valor fijo que impide el desbordamiento.
  • Los elementos se rompen en varias líneas
    • Falta white-space: nowrap (método clásico).
    • Falta flex-wrap: nowrap (método Flexbox).
  • Problemas de altura y overflow
    • Altura del contenedor mal definida o no definida.
    • Elementos hijos más altos que el padre, lo que genera un scroll vertical no deseado.
  • Estos errores son más comunes de lo que parece; me los he encontrado más de una vez en proyectos de distinto tamaño.

¿Hace falta JavaScript para un scroll horizontal?

En la mayoría de los casos: no. CSS puro es:

  • Más rápido (sin overhead de JavaScript).
  • Más simple de mantener.
  • Más accesible para lectores de pantalla y tecnologías de asistencia.
  • Más mantenible a largo plazo.

JavaScript solo tiene sentido cuando necesitas funcionalidades adicionales: botones de navegación con flechas, autoplay, scroll programático o animaciones más complejas.

Preguntas frecuentes sobre scroll horizontal con CSS

  • ¿Se puede hacer scroll horizontal solo con CSS?
    • Sí, y en la mayoría de los casos es la mejor opción. No necesitas ninguna librería externa.
  • ¿Flexbox o inline-block?
    • Flexbox es más moderno y limpio; inline-block sigue siendo válido para casos simples.
  • ¿Funciona en móvil?
    • Sí, especialmente bien con gestos táctiles. Si le añades scroll-snap, la experiencia mejora todavía más.
  • ¿Afecta al SEO?
    • No, siempre que el contenido sea accesible y visible para los crawlers. Google indexa sin problemas el contenido dentro de un div con scroll horizontal.
  • ¿Cómo oculto la barra de scroll horizontal con CSS?
    • Puedes ocultarla visualmente usando la pseudoclase ::-webkit-scrollbar con display: none, aunque esto no es estándar en todos los navegadores:
.horizontal-scroll-contenedor::-webkit-scrollbar {
 display: none;
}
/* Para Firefox */
.horizontal-scroll-contenedor {
 scrollbar-width: none;
}

Extra: desplazamiento automático con JavaScript usando scrollLeft

Aunque con CSS puro tenemos más que suficiente para la mayoría de los casos, JavaScript nos abre la puerta a funcionalidades más dinámicas: botones de navegación, autoplay o animaciones controladas por código. Vamos a ver cómo hacerlo con la propiedad scrollLeft y el método scrollTo().

La propiedad scrollLeft nos permite leer o establecer la cantidad de píxeles que el contenedor está desplazado horizontalmente. Para mover el scroll 200 píxeles de golpe:

// Seleccionamos el contenedor
const contenedor = document.querySelector(".horizontal-scroll-contenedor");
// Asignamos el valor de desplazamiento
contenedor.scrollLeft = 200;

En JavaScript moderno puedes usar el método scrollTo() con un objeto de opciones para que el movimiento sea un deslizamiento fluido en lugar de un salto brusco:

const contenedor = document.querySelector(".horizontal-scroll-contenedor");
contenedor.scrollTo({
 left: 200,
 behavior: 'smooth' // Esto hace que el scroll se vea animado
});

Si quieres implementar botones de navegación con flechas (siguiente/anterior), la lógica básica es sumar o restar un valor al scrollLeft actual del contenedor:

const contenedor = document.querySelector(".horizontal-scroll-contenedor");
const btnSiguiente = document.querySelector("#btn-siguiente");
const btnAnterior = document.querySelector("#btn-anterior");

btnSiguiente.addEventListener("click", () => {
 contenedor.scrollBy({ left: 200, behavior: "smooth" });
});

btnAnterior.addEventListener("click", () => {
 contenedor.scrollBy({ left: -200, behavior: "smooth" });
});

El método scrollBy() desplaza relativamente al punto actual, lo que lo hace ideal para botones de tipo "siguiente" y "anterior" sin necesidad de calcular posiciones absolutas.

Conclusión

El scrolling horizontal con CSS no solo es posible, sino recomendable cuando se hace bien. No necesitas librerías mágicas ni JavaScript pesado; solo entender cómo funcionan overflow, display y el modelo de layout del navegador.

Después de probar varias soluciones en proyectos reales, mi recomendación es clara:

  • Empieza simple con overflow-x: auto y white-space: nowrap.
  • Usa Flexbox si puedes; el código queda mucho más limpio.
  • Añade scroll-snap solo cuando aporte valor real a la experiencia de usuario.
  • Evita hacks innecesarios y recurre a JavaScript solo para funcionalidades que CSS no puede cubrir.

Aprende a crear un scroll horizontal en CSS usando overflow-x, Flexbox y scroll-snap. Incluye ejemplos reales, errores comunes y cómo añadir botones de navegación con JavaScript.


Únete a la comunidad de desarrolladores que han decidido dejar de picar código y empezar a construir productos reales. Recibe mis mejores trucos de arquitectura cada semana:

Acepto recibir anuncios de interes sobre este Blog.