Debugging scroll-related issues just got easier with DevTools' new scroll badge! This post explains what scrollable elements are, why they can be difficult to find, and how this new feature helps you quickly locate them. We'll also take you behind the scenes to see how we developed the scroll badge.
What is a scrollable element?
If you can scroll the content inside an element, it's a scrollable element (or scroll container). It doesn't matter if it has scroll bars or not.
Why is it hard to find the scrollable element?
Debugging scroll issues is hard. Without a tool to clearly show the scrollable element, it's easy to get lost, especially on complex pages when there are no scrollbars.
Manually finding the element that's scrolling can be a tedious process of trial and error:
- You pick an element and modify its styles.
- Did the scrollbar disappear? If not, you repeat the process.
Introducing scroll badge
In Chrome 130, you can use the new scroll badge in the Elements Panel to locate the scrollable elements!
For example, try to find which element is causing the scrollbars to appear in the following example using the new scroll badge.
Technical implementation of the new scroll badge
Behind the scenes, the implementation is split into two parts:
- Identifying scrollable elements. Use the
Blink’s
(Chrome’s render engine) signals to identify elements that are scrollable or have become scrollable due to a change in the page. - Displaying the scroll badge. Upon receiving the signals, we incorporate a new badge (similar to the existing grid badges) next to the scrollable elements in the Elements panel.
Identifying scrollable elements
To identify scrollable elements, we utilized the IsUserScrollable
method in Blink. This method determines whether a node is scrollable by checking if it overflows along either the X or Y axis, indicating that the content exceeds the container dimensions and can be scrolled. We call this method each time a new element is loaded in DevTools to identify scrollable containers.
For dynamically updating the scrollability state of elements that are already loaded, we had to dive deep into the Blink rendering engine codebase to track where the scrollable area for a node is added or removed.
The core logic handling overflow is managed by the PaintLayerScrollableArea
component. Specifically, the UpdateScrollableAreaSet
method is responsible for detecting when overflow has occurred or has been resolved.
This information is relayed to the DevTools backend by sending the reference of the node that changed its ScrollableArea
.
The backend then rechecks the node using the IsUserScrollable
method to get its new state. After verifying the scrollability, a signal is sent to the frontend using the Chrome DevTools Protocol
, ensuring that the UI accurately reflects changes in scrollable content.
Displaying the scroll badge
To add the new badge in DevTools frontend, we created a handler method in the ElementsTreeOutline
that received the nodeId of the element that changed its scrollability state by an Event.
In that handler we retrieve the ElementsTreeElement
object using the nodeId
and instruct it to update its scroll badge.
Updating the scroll badge involves checking if the element is scrollable and whether it already has a scroll badge. Based on these conditions, the following actions are taken:
- If the element is scrollable and doesn't have a scroll badge yet, one is added.
- If the element is not scrollable but has a scroll badge, the existing badge is removed.
The special logic to handle scrollable top-level document
When the top-level document is scrollable, we have a special case because we don't display the #document
element for the main document—only for iframes. As a result, we can't show the badge directly on #document
elements
We decided displaying the scroll badge on the </html>
element instead, including those in Quirks mode
where document.scrollingElement()
returns the <body>
or null
. This decision prevents confusion between scrollable documents and scrollable body elements, particularly on pages where the body can be scrolled independently.
We've found this to be the clearest way to show developers which elements can be scrolled.
Chrome DevTools Protocol (CDP) changes
To integrate the new scroll badge, changes to Chrome DevTools Protocol (CDP)
were required. CDP serves as a communication protocol between DevTools and Chrome.
We had to change the protocol to cover the two cases:
- Is this node scrollable when it is loaded in the DevTools?
- Has this node updated its scrollable state?
Is this node scrollable when it is loaded in the DevTools?
We added a new property named isScrollable
to the DOM.Node
data type that is sent every time a new node is loaded in DevTools frontend.
We decided to populate this property only when it's true, to avoid loading unnecessary data. Therefore, when the property is not sent, we assume that the element is not scrollable.
Has this node updated its scrollable state?
To detect if a node has updated its scrollable state, we introduced a new event scrollableFlagUpdated
in CDP, which is triggered whenever an element gains or loses a scrollable area. The event has the following structure:
# Fired when a node's scrollability state changes.
experimental event scrollableFlagUpdated
parameters
# The id of the node.
DOM.NodeId nodeId
# If the node is scrollable.
boolean isScrollable
Pro tip: Examine the new CDP changes in your browser
If you're curious about how Chrome communicates with DevTools, there's a simple way to explore it.
The Protocol Monitor panel lets you view real-time events exchanged between Chrome and DevTools, including the newly added event for the Scroll badge. For example, when you modify the style of an element that affects its scrollability, you can immediately see the related CDP events as they happen.
For a more detailed guide, see Protocol monitor: View and send CDP requests
.
Beyond Scrolling: Introducing the overflow badge
Even better, we're working on a new overflow badge to pinpoint the cause of that scrolling. This badge will appear next to elements that overflow their container, helping you quickly diagnose layout issues.
Here's how it will work:
- Interactive debugging. Click the scroll badge to trigger a DevTools Protocol command that identifies overflowing child elements.
- Visualizing overflow. We'll map the element boundaries within the scrollable container to detect any overflow.
- Highlighting the culprit. The overflow badge will flag these overflowing elements, and clicking it will highlight them directly in the DOM.
This will give developers a powerful new tool to understand and fix layout problems caused by overflowing content. We believe this deeper level of analysis will significantly streamline your debugging workflow.