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:
- Se ve
visibleEl valor por defecto: el desborde se ve afuera de la caja, encima de lo que venga después. - Se esconde
hiddenLo recorta y no muestra barras, pero la caja sigue siendo un contenedor de scroll. JavaScript la puede mover conscrollTo(), y si un elemento de adentro recibe el foco con Tab, el navegador scrollea hasta mostrarlo. - Se corta
clipLo recorta igual, pero no crea contenedor de scroll. No se puede scrollear ni por código. - Scroll si hace falta
autoLo recorta y muestra una barra solo cuando el contenido no entra. Es el que vas a usar casi siempre. - Scroll siempre
scrollLo 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.
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
.indicaciones {box-sizing: border-box;width: 240px;height: 120px;padding: 12px;overflow: visible;}.indicaciones p {overflow-wrap: anywhere;}
<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:
<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.
.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.
- Partir lo largo
overflow-wrap: anywhereCorta una palabra larga, como una URL, solo si no entra en la línea. Es lo que usa la demo enwrap. - Partir todo
word-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. - En flexbox
min-width: 0Los elementos flex tienenmin-width: autoy no se achican por debajo de su contenido. Ponémin-width: 0en 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.
.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;}
<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>
- No saltear
scroll-snap-stop: alwaysNo deja saltear elementos en un deslizamiento rápido. - Saltos suaves
scroll-behavior: smoothAnima los saltos de un ancla o descrollTo(), no el scroll del usuario. Aplicalo solo si la persona no pidió menos movimiento. - Sin contagio
overscroll-behavior: containEvita que, al llegar al final de un scroll interno, se empiece a scrollear la página. - Lugar fijo
scrollbar-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.
@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.
| CSS | Tailwind |
|---|---|
| overflow: hidden · overflow-x: auto | overflow-hidden · overflow-x-auto |
| nowrap + hidden + ellipsis | truncate |
| -webkit-line-clamp: 2 (y sus tres) | line-clamp-2 |
| overflow-wrap: anywhere · break-all | wrap-anywhere · break-all |
| scroll-snap-type: x mandatory | snap-x snap-mandatory · snap-start |
| overscroll-behavior: contain | overscroll-contain |
| scroll-behavior: smooth | motion-safe:scroll-smooth |
<!-- 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>
Overflow and scroll
Lesson 11 of 37 · 4 min
Not everything fits in its box. A long text, a URL or a row of cards can need more room than they have, and CSS lets you choose what happens to the rest.
What to do with the rest
When the content is bigger than its box, the part that doesn't fit is the overflow, and the overflow property decides what happens to it:
- Shown
visibleThe default: the overflow shows outside the box, on top of whatever comes next. - Hidden
hiddenClips it and shows no scrollbars, but the box is still a scroll container. JavaScript can move it withscrollTo(), and if an element inside gets focus with Tab, the browser scrolls to show it. - Clipped
clipClips it the same way, but doesn't create a scroll container. It can't be scrolled, not even by code. - Scroll when needed
autoClips it and shows a scrollbar only when the content doesn't fit. It's the one you'll use most of the time. - Always scroll
scrollClips it and always shows scrollbars, on both axes, even when they aren't needed.
Pick an overflow value and a text mode, and watch what happens to whatever doesn't fit in the 240 × 120px directions box. On the right, the gray line measures the box and the orange one how far the text runs.
From Route 40, take the gravel road toward the lake and follow the blue signs for about 4 miles. The key is in the box by the door. Map: https://bookings.example.com/cabins/moraine-lake/directions
.directions {box-sizing: border-box;width: 240px;height: 120px;padding: 12px;overflow: visible;}.directions p {overflow-wrap: anywhere;}
<div class="w-60 h-30 p-3 overflow-visible"><p class="wrap-anywhere">From Route 40, take the gravel road…</p></div>
With auto or scroll, the arrow keys scroll the box only when it has focus. Some browsers make it focusable on their own and some don't, so give it tabindex="0", role="region" and an aria-label, so a screen reader announces it by name:
<div class="orders" tabindex="0" role="region" aria-label="Recent orders">…</div>
Each axis has its own property: overflow-x and overflow-y. Watch out: if one axis is hidden, auto or scroll, a visible on the other one becomes auto. And on macOS or a phone, scrollbars overlay the content and only show while scrolling, so auto and scroll can look the same.
Cutting text
The ellipsis (text-overflow: ellipsis) works on a single line, and it needs three declarations together: the text must not wrap, it must be clipped and it must show the dots.
.title {white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}
To cut after several lines there's -webkit-line-clamp. It carries a prefix but works in every current browser, always together with display: -webkit-box, -webkit-box-orient: vertical and overflow: hidden. The spec defines an unprefixed line-clamp property, but it isn't in every browser yet.
- Break long words
overflow-wrap: anywhereBreaks a long word, such as a URL, only when it doesn't fit on the line. It's what the demo uses inwrap. - Break anywhere
word-break: break-allBreaks at any letter at the end of the line, even words that could move whole to the next one. Keep it for strings without spaces, like a hash. - In flexbox
min-width: 0Flex items havemin-width: autoand won't shrink below their content. Setmin-width: 0on the flex item so the ellipsis shows up.
How scrolling behaves
scroll-snap-type on the container and scroll-snap-align on the children make scrolling come to rest lined up with an item, like a carousel. With mandatory it always stops at a snap point; with proximity, only when it ends up close to one.
Turn on snap, change the alignment and scroll the row with the wheel, a finger or the arrow keys after focusing it with Tab. The orange line marks where each photo's edge lands when scrolling stops.
.carousel {display: flex;gap: 12px;overflow-x: auto;overscroll-behavior-x: contain;scroll-snap-type: x mandatory;}.photo {flex: none;width: 144px;scroll-snap-align: start;}
<div class="flex gap-3 overflow-x-auto overscroll-x-contain snap-x snap-mandatory"><figure class="flex-none w-36 snap-start">Moraine Lake</figure>…</div>
- No skipping
scroll-snap-stop: alwaysKeeps a fast swipe from skipping past items. - Smooth jumps
scroll-behavior: smoothAnimates jumps from an anchor link orscrollTo(), not the user's own scrolling. Apply it only when the person hasn't asked for reduced motion. - No chaining
overscroll-behavior: containStops the page from scrolling once an inner scroller reaches its end. - Steady gutter
scrollbar-gutter: stableReserves the scrollbar's room even when it isn't needed, so the content doesn't jump when it appears. It only affects classic scrollbars, not overlay ones.
@media (prefers-reduced-motion: no-preference) {html {scroll-behavior: smooth;}}.panel {overflow-y: auto;overscroll-behavior: contain;scrollbar-gutter: stable;}
In Tailwind
In Tailwind each overflow value is a class, per axis too. For cutting text there are shortcuts that bundle several declarations into one class.
| CSS | Tailwind |
|---|---|
| overflow: hidden · overflow-x: auto | overflow-hidden · overflow-x-auto |
| nowrap + hidden + ellipsis | truncate |
| -webkit-line-clamp: 2 (and its three) | line-clamp-2 |
| overflow-wrap: anywhere · break-all | wrap-anywhere · break-all |
| scroll-snap-type: x mandatory | snap-x snap-mandatory · snap-start |
| overscroll-behavior: contain | overscroll-contain |
| scroll-behavior: smooth | motion-safe:scroll-smooth |
<!-- snapping carousel, focusable with Tab --><div class="flex gap-3 overflow-x-auto overscroll-x-contain snap-x snap-mandatory" tabindex="0" role="region" aria-label="Products"><article class="w-36 flex-none snap-start">…</article><article class="w-36 flex-none snap-start">…</article></div><!-- one-line title inside a flex row --><div class="flex gap-2"><h3 class="min-w-0 truncate">…</h3></div>






