motion · navigation
Sliding indicator
also called magic line (community), animated tab indicator (community), sliding underline (community), moving pill (community), spring pill (community), magic indicator (community)
A single underline or pill that travels between tabs to mark the selection instead of each tab drawing its own, so the move itself says which way the selection went.
There is one bar, and it belongs to the group rather than to any tab in it. Selecting a tab does not switch a border on and another one off: it tells the single bar where to go next, and the bar travels there. What the reader gets out of that trip is direction. A selection that blinks from the second tab to the fourth says only that something changed, while a bar that slides right past the third says which way the selection moved and how far, which is the same information a scrollbar thumb gives about a long document.
Building it is a measuring job. The indicator is taken out of the flow, usually
absolutely positioned in a rail under the row, and every move reads the target tab’s
box and writes that geometry onto the one bar. Two ways to write it: left and width,
which are honest and easy to read but recalculate layout on every frame, or a
translateX plus a scaleX against a fixed reference width, which the compositor can
run without touching layout at all and which is what most polished implementations use.
The scale version needs the bar’s own content to be nothing but flat colour, since
anything inside it would be stretched along with it. Either way this is the everyday
face of FLIP: read the box you are going to, and animate a transform
that turns where you are into where you will be.
The same move appears wherever a group has exactly one selection and all the options are on screen: the thumb of a segmented control, the highlight in a bottom navigation bar, the pill behind a filter row. It stops working the moment the set is not a fixed row. A wrapping menu makes the bar jump lines, an overflowing tab strip makes it slide to somewhere off screen, and a set whose items are added or removed while the reader watches needs a re-measure on every change, which is what a ResizeObserver is usually doing in these implementations. Web fonts are the classic first bug: measure before the real face has loaded and the bar sits under a width that no longer exists.
Two things keep it honest. The bar is decoration, so the actual state has to live in
aria-selected (or aria-current for navigation) on the tab itself, or a screen reader
gets a group of identical buttons with nothing selected. And a bar that travels is
motion the reader did not ask for, so under prefers-reduced-motion it should simply be
where it belongs, with no trip at all. That is also the reason to keep the duration
short, in the 150 to 250 millisecond range: past that the reader has already read the
new panel and the bar is still on its way.
Which word?
| If you want | say |
|---|---|
| selection should move between items rather than blink between them | sliding indicator |
| showing which nav item is the page you are on | current page indicator |
Related
See also: Tabs · Segmented control