Lesson 35: Overflow

When content spills out of its parent, you have many choices for how to handle it. You can scroll to add more space. You can clip the edges that overflow. You can show a cut-off with three dots, and much more. Overflow really matters when you build for phones and lots of screen sizes.

CSS gives you two ways to clip content. The text-overflow property helps with single lines of text. The overflow properties help control overflow in the box model.

Single line overflow with text-overflow

Use the text-overflow property on any element that holds text, like a paragraph, <p>. It sets how the text looks when it doesn’t fit in the space the element has. All the readable text on a page lives in text nodes. To use text-overflow you need a single line of text that doesn’t wrap. So you must also set overflow to hidden and use a white-space value that stops wrapping.

p {
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
}

Using overflow properties

You set overflow properties on an element to control what happens when its children need more space than it has. This can be on purpose, like in an interactive map such as Google Maps, where a user pans around a large image that is clipped to a set size. It can also happen by accident, like in a chat app where a user types a long message that doesn’t fit in the text bubble.

You can think of overflow in two parts. The parent element has a firm space that won’t change. You can think of this as a window. The child elements are content that wants more space from the parent. You can think of this as what you are looking at through the window. Managing overflow helps guide how the window frames this content.

Scrolling on the vertical and horizontal axis

The overflow-y property controls overflow up and down, so the box scrolls up and down.

The overflow-x property controls overflow left and right, so the box scrolls left and right.

Logical properties for scroll direction

The overflow-inline and overflow-block properties set the overflow based on the document direction and writing mode.

The overflow shorthand

The overflow shorthand sets both overflow-x and overflow-y in one line.

overflow: hidden scroll;

If you give two keywords, the first one applies to overflow-x and the second to overflow-y. If you give one keyword, both overflow-x and overflow-y use the same value.

Values

Take a closer look at the values and keywords you can use for the overflow properties.

overflow: visible is the default value for the web. Without setting the property, content is shown. This makes sure content is never hidden by accident. It follows the core idea of never hide content.

overflow: hidden clips content in the direction you set, and gives no scrollbars to show it.

overflow: scroll turns on scrollbars so users can scroll through content. The scrollbars show up even when content isn’t overflowing. This is a nice way to cut down on future layout shift if a container might be scrollable later, for example after a resize. It also tells the user in advance that an area can scroll.

overflow: clip clips content to the element’s padding box, just like overflow: hidden. The difference is that clip also blocks all scrolling, even scrolling from code.

overflow: auto is the value people use most. It respects the user’s preferences and shows scrollbars only if they are needed. It hides them by default and hands scrolling over to the user and the browser.

[!NOTE] Using the overflow property with any value other than visible creates a block formatting context.

Scrolling and overflow

Many of these overflow behaviors add a scrollbar. There are also a few scroll behaviors and properties that help you control scrolling on your overflow container.

Scrolling and accessibility

It’s important to make sure the scrollable area can take focus. That way a keyboard user can tab to the box, then use the arrow keys to scroll.

To let a scrolling box take focus, add tabindex="0", a name with the aria-labelledby attribute, and a fitting role attribute. Here is an example.

<div tabindex="0" role="region" aria-labelledby="id-of-descriptive-text">
    content
</div>

You can then use CSS to show that the box has focus. Use the outline property to give a visual clue that it will now scroll.

In Using CSS to Enforce Accessibility Adrian Roselli shows how CSS can help prevent accessibility regressions. For example, you can turn on scrolling and the focus indicator only if the right attributes are used. The rules below only make the box scrollable if it has a tabindex, aria-labelledby, and role attribute.

[role][aria-labelledby][tabindex] {
  overflow: auto;
}

[role][aria-labelledby][tabindex]:focus {
  outline: .1em solid blue;
}

Scrollbar positioning within the box model

Scrollbars take up space inside the padding box. They can compete for space if they are inline and not overlaid. The box model module goes into more detail on this source of layout shift.

root-scroller versus implicit-scroller

You may notice that some scrollers have a pull-to-refresh behavior and other special behaviors, especially when you build for mobile and hybrid apps. This scroll behavior happens on the root scroller. There is only ever one root scroller on a page. By default, the documentElement is the page’s root scroller. But you can change which element is the root scroller. Then the special behaviors apply to a scroller other than the documentElement. We call this new scroller the implicit root scroller.

To create a root scroller, you can use something called scroller promotion. You position a container as fixed, make sure it covers the whole viewport, and put it on top with z-index, with a scroller. Experience a root scroller versus a nested implicit scroller here. The video shows a root scroller with bounce behavior and new styling features, next to an implicit scroller with no enhanced scroll behavior.

Styling your scrollbar

You can style your scrollbar to fit it into your site’s design. scrollbar-color sets the color for the scrollbar’s thumb and gutter.

To change the width of the scrollbar, use scrollbar-width. You can’t set this to any length you like. You can ask for a thin scrollbar or none.

scroll-behavior

scroll-behavior lets you opt into browser-controlled scrolling to elements. This lets you set how in-page navigation, like .scrollTo() or links, is handled.

This is handy with prefers-reduced-motion so you can set scroll behavior based on what the user prefers.

@media (prefers-reduced-motion: no-preference) {
  .scroll-view {
    scroll-behavior: auto;
  }
}

overscroll-behavior

Have you ever reached the end of a modal overlay, kept scrolling, and had the page behind the overlay move? That is scroll chaining, where the scroll bubbles up to the parent scroll container. The overscroll-behavior property lets you stop overflow scrolling from leaking into a parent container.

Scroll snapping

Scrolling is usually smooth. It lets you place the content within the scrollport wherever you want. For some designs, like image galleries or content that acts like pages or slides, you may want the content to snap to the scrollport.

Setting up the scroll container

To turn on scroll snapping, add scroll-snap-type to the scroll container. First you set which axis the scroll snapping happens on. This can be a logical property (block or inline), a physical property (x or y), or both.

You can also set how strict scroll snapping is. The default strictness is proximity, which means the scroll container will try to snap when it can. You can set the strictness to mandatory to make sure the scroll container always snaps.

.scroll-container {
    scroll-snap-type: block mandatory;
}

[!NOTE] When you use mandatory scroll snapping, you can create content that is hard to reach between snap positions. Test your content on a range of screen sizes to make sure it stays accessible.

Scroll snapping lines up an element within the full bounds of the scroll container. But what happens if part of the scroll container is not visible? For example, you might have a fixed header that covers part of the scroll container. To line up the snapped elements with the visible part of the scroll container, you can set scroll-padding.

Controlling the snappable elements

To make an element snappable, set the scroll-snap-align property to start, end, or center. If the scroll snap direction is both, you can set two values. This sets whether an edge of the element lines up with the scrollport’s edge, or whether it is centered.

You can adjust the spacing around the edges of the snapped element with scroll-margin.

scroll-margin also sets the padding when scrolling to an element.

To make the scrolling more sticky, you can add scroll-snap-stop: always to an item in a scroll container. It doesn’t stop you from scrolling past several items in a single scroll. If you end a scroll in a way that would keep going with inertia, the scroll stops at the next snap position instead of continuing past it.

Resources

To learn more about overflow, take a look at this resource.


Adapted from Learn CSS © Google and contributors, licensed under CC BY 4.0 (prose) and Apache 2.0 (code samples).