Skip to content
animorio
IT
All components

The notched tab bar

Menus, SVG, TransitionsGSAPMediumCompressed weight: Demo 4.8 KBGSAP 28 KBFreeDownload the zip

A dark navigation bar with a notch in its edge and a coral disc floating in it: choosing a tab, notch and disc slide there on a spring, the notch widens as it runs, the disc dips and squashes like a drop, and the icon rises into the disc with its own little move.

The code

A folder that runs on its own: index.html, style.css, script.js and the libraries from a CDN. The React and Vue tabs hold the same demo as a ready component, which switches its animations off when it leaves the page.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>The notched tab bar</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/lexend@5.3.0/index.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the tab bar: a dark bar with a notch cut in its top edge and a coral disc floating in it. Choosing a tab, the
         notch and the disc slide there on a spring (the notch widens while it runs, the disc dips and squashes),
         the old icon drops back into the bar and the new one rises into the disc. The bar's shape is drawn by the
         script -->
    <nav class="bar" aria-label="Main" data-bar>
      <svg class="bar__shape" aria-hidden="true" data-shape><path data-path/></svg>
      <span class="bar__bubble" aria-hidden="true" data-bubble></span>
      <span class="bar__label" aria-hidden="true" data-label></span>
      <button class="tab" type="button" data-tab="Home" data-autoclic>
        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 11.2 12 4.8l8 6.4V20h-5.6v-5.6H9.6V20H4z"/></svg>
        <span class="sr">Home</span>
      </button>
      <button class="tab" type="button" data-tab="Search">
        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M10.5 4.5a6 6 0 1 0 0 12a6 6 0 1 0 0-12zM15 15l4.5 4.5"/></svg>
        <span class="sr">Search</span>
      </button>
      <button class="tab" type="button" data-tab="New">
        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
        <span class="sr">New</span>
      </button>
      <button class="tab" type="button" data-tab="Saved">
        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 19.5s-7.5-4.6-7.5-10A4.2 4.2 0 0 1 12 7a4.2 4.2 0 0 1 7.5 2.5c0 5.4-7.5 10-7.5 10z"/></svg>
        <span class="sr">Saved</span>
      </button>
      <button class="tab" type="button" data-tab="Profile">
        <svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 4.5a3.6 3.6 0 1 0 0 7.2a3.6 3.6 0 1 0 0-7.2zM5 19.5c.8-3.4 3.6-5.5 7-5.5s6.2 2.1 7 5.5"/></svg>
        <span class="sr">Profile</span>
      </button>
    </nav>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

Change values, colours and text with the controls and watch the animation respond live. Or write in the code yourself. Then download the folder with your changes.

18 values to change

Or ask Claude Code for it

With the Animorio connector, Claude Code takes it from here, guide included, and fits it into your project. Paste this request:

Take “The notched tab bar” from Animorio and fit it into my site

What it does

On a white background a near-black bar with rounded ends and five grey icons: house, lens, plus, heart and person. There is a notch in its top edge, and in the notch floats a coral disc holding the chosen tab’s icon, in white, with its name underneath. When the page opens the bar rises, the notch opens and the disc drops into it with a bounce. Choosing another tab, the notch and the disc slide over to it on a spring: running, the notch widens and the disc dips into the bar and squashes like a drop, then slows down, rounds out again and goes just past the spot. The previous icon sinks back into the bar and turns grey, the new one rises into the disc and does its move: the house hops, the lens wiggles, the plus makes half a turn, the heart beats, the person nods; the name under the disc disappears and comes back as the new one.

How it works

One outline

The bar is an SVG path the script redraws on every frame: a rectangle with rounded ends and, around the point c, a notch made of two Bézier curves. Half its width is NOTCH[0] plus the speed times STRETCH, and it never cuts into the rounded corners.

The spring

The point c follows the chosen tab on a hand-written spring (SPRING), worked out on GSAP’s ticker in steps of 4 milliseconds. Its speed gives the notch’s width, how far the disc sinks into the bar (DIP) and how much it squashes: wider and lower by the same amount.

The icons

The previous icon sinks back to y 0 with power3.inOut; the new one rises by RISE pixels with back.out, after a delay that grows with the distance between the two tabs, so it arrives together with the disc. Once there it does its move (MOVES), on the icon and not on the button, so it does not fight the rise.

The name

Under the disc there is a single name that follows c on every frame: on a new choice it fades out dropping slightly, changes its text and comes back.

Keyboard and preview

The tabs are buttons in a nav, and the chosen one has aria-current="page"; the arrows move the focus between the tabs, Home and End go to the ends. The library’s preview clicks the data-autoclic mark, which the script moves to the next tab every time.

Values to change

NameFileDefaultWhat it changes
STARTscript.js0The tab chosen when the page opens (0 is the first).
SPRINGscript.js[210, 0.62]The spring of the notch and the disc: how stiff it is and how much it is held back.
NOTCHscript.js[42, 34]The notch at rest: half its width and its depth, in pixels.
STRETCHscript.js0.03How much the notch widens with its speed.
DIPscript.js0.012How far the disc dips into the bar with its speed.
RISEscript.js40How far an icon rises into the disc, in pixels.

Try them in the Playground

When to use it

For the navigation at the bottom of the screen in a web app or a phone-first site, for an app’s sections, for a toolbar.

On phones

The bar takes the width of the screen minus a margin and the tabs move closer; next to the ends the notch narrows so as not to cut into the rounded corners. Two quick taps do not zoom the page.

With reduced motion

Notch, disc and icons go straight to their places: no slide, no drop, no icon moves and no entrance.

Pitfalls

  • Next to the bar’s ends the notch would cut into the rounded corners and break the outline: its half width is limited by the distance from the corners.
  • The icon’s rise (y on the button) and its move (scale, rotation and y on the icon) sit on two different elements: on the same one, the person’s nod would fight the rise.
  • From the first tab to the last the distance is large: the spring must be worked out in steps of 4 milliseconds at most, or a slow frame would blow it up.
  • The new icon must reach the disc when the disc gets there: its delay grows with the distance between the two tabs.

Libraries

GSAP 3.15.0, Lexend (font variabile) 5.3.0.

Compressed with gzip, the three demo files weigh 4.8 KB; the libraries: GSAP 28 KB.

Testing

Tested on 3 October 2026

  • Desktop: Done
  • Phone: Done
  • Reduced motion: Done
  • Safari on iPhone: Done

License

Use it in your own projects and in your clients’ projects. Do not resell it or redistribute it as is. GSAP stays under its own Standard license. Full license.

All components