Saltar al contenido

CSS, de a poco

Curso de CSS

Overflow y scroll

Lección 11 de 37 · 4 min

No todo entra en su caja. Un texto largo, una URL o una fila de tarjetas pueden ocupar más lugar del que tienen, y CSS te deja elegir qué hacer con lo que sobra.

Qué hacer con lo que sobra

Cuando el contenido es más grande que su caja, lo que sobra es el desborde, y la propiedad overflow decide qué pasa con él:

  1. Se vevisibleEl valor por defecto: el desborde se ve afuera de la caja, encima de lo que venga después.
  2. Se escondehiddenLo recorta y no muestra barras, pero la caja sigue siendo un contenedor de scroll. JavaScript la puede mover con scrollTo(), y si un elemento de adentro recibe el foco con Tab, el navegador scrollea hasta mostrarlo.
  3. Se cortaclipLo recorta igual, pero no crea contenedor de scroll. No se puede scrollear ni por código.
  4. Scroll si hace faltaautoLo recorta y muestra una barra solo cuando el contenido no entra. Es el que vas a usar casi siempre.
  5. Scroll siemprescrollLo recorta y muestra barras siempre, en los dos ejes, aunque no hagan falta.

Elegí un valor de overflow y un modo de texto, y mirá qué pasa con lo que no entra en la caja de indicaciones, de 240 × 120px. A la derecha, la línea gris mide la caja y la naranja hasta dónde llega el texto.

overflow: visibleel texto sobra y se ve afuera
Cómo llegar a la cabaña

Desde la ruta 40, tomá el camino de ripio hacia el lago y seguí los carteles azules unos 6 km. La llave está en la caja junto a la puerta. Mapa: https://reservas.example.com/cabanas/lago-moraine/como-llegar

overflow
texto
indicaciones.css
.indicaciones {
box-sizing: border-box;
width: 240px;
height: 120px;
padding: 12px;
overflow: visible;
}
.indicaciones p {
overflow-wrap: anywhere;
}
indicaciones.html
<div class="w-60 h-30 p-3 overflow-visible">
<p class="wrap-anywhere">Desde la ruta 40, tomá el camino de ripio…</p>
</div>

Con auto o scroll, la caja se scrollea con las flechas solo si tiene el foco. Algunos navegadores la hacen enfocable solos y otros no, así que dale tabindex="0", role="region" y un aria-label, para que un lector de pantalla la anuncie con nombre:

pedidos.html
<div class="pedidos" tabindex="0" role="region" aria-label="Últimos pedidos">…</div>

Cada eje se controla por separado con overflow-x y overflow-y. Ojo: si un eje vale hidden, auto o scroll, un visible en el otro pasa a valer auto. Y en macOS o en el celular las barras se superponen y aparecen solo al scrollear, así que auto y scroll pueden verse iguales.

Cortar texto

Los puntos suspensivos (text-overflow: ellipsis) funcionan en una sola línea, y necesitan tres declaraciones juntas: que el texto no salte de línea, que se recorte y que muestre los puntos.

La misma tarjeta de una cabaña tres veces. Con ellipsis el título queda en una línea y termina en puntos; con line-clamp: 2 se corta en la segunda línea; con overflow-wrap: anywhere la URL se parte para entrar en la caja.
titulo.css
.titulo {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

Para cortar después de varias líneas está -webkit-line-clamp. Lleva prefijo pero anda en todos los navegadores actuales, siempre junto a display: -webkit-box, -webkit-box-orient: vertical y overflow: hidden. La especificación define una propiedad line-clamp sin prefijo, pero todavía no está en todos los navegadores.

  1. Partir lo largooverflow-wrap: anywhereCorta una palabra larga, como una URL, solo si no entra en la línea. Es lo que usa la demo en wrap.
  2. Partir todoword-break: break-allCorta en cualquier letra al final de la línea, incluso palabras que podrían pasar enteras a la siguiente. Dejalo para cadenas sin espacios, como un hash.
  3. En flexboxmin-width: 0Los elementos flex tienen min-width: auto y no se achican por debajo de su contenido. Poné min-width: 0 en el elemento flex para que la ellipsis aparezca.

Cómo se comporta el scroll

scroll-snap-type en el contenedor y scroll-snap-align en los hijos hacen que el scroll termine alineado a un elemento, como en un carrusel. Con mandatory siempre frena en un punto de snap; con proximity, solo si quedó cerca de uno.

Activá el snap, cambiá la alineación y scrolleá la fila con la rueda, el dedo o las flechas después de enfocarla con Tab. La línea naranja marca dónde queda el borde de cada foto cuando el scroll frena.

scroll-snap-type: x mandatorycada foto se alinea al inicio
Un lago turquesa rodeado de montañas y pinos
Lago MoraineCanadá
Dunas de arena naranja bajo un cielo pálido
MerzougaMarruecos
Una playa vista desde arriba, con agua turquesa y una palmera
Isla HolboxMéxico
Un bosque de pinos con niebla en el valle
Selva NegraAlemania
Un iceberg flotando en agua calma
IlulissatGroenlandia
Las luces de una ciudad extendida al anochecer
Los ÁngelesEstados Unidos
scroll-snap-align
carrusel.css
.carrusel {
display: flex;
gap: 12px;
overflow-x: auto;
overscroll-behavior-x: contain;
scroll-snap-type: x mandatory;
}
.foto {
flex: none;
width: 144px;
scroll-snap-align: start;
}
carrusel.html
<div class="flex gap-3 overflow-x-auto overscroll-x-contain snap-x snap-mandatory">
<figure class="flex-none w-36 snap-start">Lago Moraine</figure>
…
</div>
  1. No saltearscroll-snap-stop: alwaysNo deja saltear elementos en un deslizamiento rápido.
  2. Saltos suavesscroll-behavior: smoothAnima los saltos de un ancla o de scrollTo(), no el scroll del usuario. Aplicalo solo si la persona no pidió menos movimiento.
  3. Sin contagiooverscroll-behavior: containEvita que, al llegar al final de un scroll interno, se empiece a scrollear la página.
  4. Lugar fijoscrollbar-gutter: stableReserva el lugar de la barra aunque no haga falta, así el contenido no salta cuando aparece. Solo afecta a las barras clásicas, no a las superpuestas.
panel.css
@media (prefers-reduced-motion: no-preference) {
html {
scroll-behavior: smooth;
}
}
.panel {
overflow-y: auto;
overscroll-behavior: contain;
scrollbar-gutter: stable;
}

En Tailwind

En Tailwind cada valor de overflow es una clase, también por eje. Para cortar texto hay atajos que juntan varias declaraciones en una sola clase.

CSSTailwind
overflow: hidden · overflow-x: autooverflow-hidden · overflow-x-auto
nowrap + hidden + ellipsistruncate
-webkit-line-clamp: 2 (y sus tres)line-clamp-2
overflow-wrap: anywhere · break-allwrap-anywhere · break-all
scroll-snap-type: x mandatorysnap-x snap-mandatory · snap-start
overscroll-behavior: containoverscroll-contain
scroll-behavior: smoothmotion-safe:scroll-smooth
carrusel.html
<!-- carrusel con snap, enfocable con Tab -->
<div class="flex gap-3 overflow-x-auto overscroll-x-contain snap-x snap-mandatory" tabindex="0" role="region" aria-label="Productos">
<article class="w-36 flex-none snap-start">…</article>
<article class="w-36 flex-none snap-start">…</article>
</div>
<!-- título de una línea dentro de un flex -->
<div class="flex gap-2">
<h3 class="min-w-0 truncate">…</h3>
</div>