Pure TailwindMIT licensed

Tailwind Off-Canvas Push Sidebar Menu

The true off-canvas pattern: instead of overlapping, the whole app shell is pushed right by exactly the drawer's width — and in this port it also scales back to 96% with a rounded edge, so the menu reads as a layer underneath the page. The nav slides in on a parallax offset (one-third of its width) for the depth of a native mobile app. Pure Tailwind.

Live Demo
Plain CSSTailwind v4
Try it

Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time

Untitled UI React · Affiliate link

Get Untitled UI Pro

The code

<section class="tsm-03 group relative isolate w-full min-h-svh overflow-hidden bg-tsm03-nav font-tsm03-sans text-tsm03-ink [--tsm03-w:16.25rem]" aria-label="Off-canvas push sidebar demo">
  <input type="checkbox" id="tsm-03-toggle" class="peer sr-only">
  <nav aria-label="Main" class="invisible absolute inset-y-0 left-0 z-0 flex w-(--tsm03-w) -translate-x-1/3 flex-col py-6 opacity-60 transition-[translate,opacity,visibility] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked:visible group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none">
    <div class="mx-5 mb-4 flex items-center gap-2.5 border-b border-tsm03-acc/15 pb-5">
      <span aria-hidden="true" class="grid size-8 place-items-center rounded-lg bg-tsm03-acc text-sm font-bold text-black">G</span>
      <p class="font-bold">Grove</p>
    </div>
    <ul class="grid gap-1 px-2.5">
      <li><a href="#" class="flex min-h-11 items-center gap-3 rounded-lg px-3.5 text-sm font-medium text-tsm03-mut transition-colors hover:bg-tsm03-acc/10 hover:text-tsm03-ink focus-visible:outline-2 focus-visible:outline-tsm03-acc2 aria-[current=page]:bg-tsm03-acc/12 aria-[current=page]:font-semibold aria-[current=page]:text-tsm03-acc2" aria-current="page"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 10.5 12 3l9 7.5"/><path d="M5 9.5V20h14V9.5"/><path d="M10 20v-6h4v6"/></svg>Home</a></li>
      <li><a href="#" class="flex min-h-11 items-center gap-3 rounded-lg px-3.5 text-sm font-medium text-tsm03-mut transition-colors hover:bg-tsm03-acc/10 hover:text-tsm03-ink focus-visible:outline-2 focus-visible:outline-tsm03-acc2 aria-[current=page]:bg-tsm03-acc/12 aria-[current=page]:font-semibold aria-[current=page]:text-tsm03-acc2"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3v18h18"/><path d="m7 15 4-4 3 3 5-6"/></svg>Analytics</a></li>
      <li><a href="#" class="flex min-h-11 items-center gap-3 rounded-lg px-3.5 text-sm font-medium text-tsm03-mut transition-colors hover:bg-tsm03-acc/10 hover:text-tsm03-ink focus-visible:outline-2 focus-visible:outline-tsm03-acc2 aria-[current=page]:bg-tsm03-acc/12 aria-[current=page]:font-semibold aria-[current=page]:text-tsm03-acc2"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6v18h12V7z"/><path d="M14 3v4h4"/><path d="M9 13h6M9 17h6"/></svg>Reports</a></li>
      <li><a href="#" class="flex min-h-11 items-center gap-3 rounded-lg px-3.5 text-sm font-medium text-tsm03-mut transition-colors hover:bg-tsm03-acc/10 hover:text-tsm03-ink focus-visible:outline-2 focus-visible:outline-tsm03-acc2 aria-[current=page]:bg-tsm03-acc/12 aria-[current=page]:font-semibold aria-[current=page]:text-tsm03-acc2"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0"/><path d="M16 4.5a3.5 3.5 0 0 1 0 7"/><path d="M18 14.5a6.5 6.5 0 0 1 3.5 5.5"/></svg>Team</a></li>
      <li><a href="#" class="flex min-h-11 items-center gap-3 rounded-lg px-3.5 text-sm font-medium text-tsm03-mut transition-colors hover:bg-tsm03-acc/10 hover:text-tsm03-ink focus-visible:outline-2 focus-visible:outline-tsm03-acc2 aria-[current=page]:bg-tsm03-acc/12 aria-[current=page]:font-semibold aria-[current=page]:text-tsm03-acc2"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h9"/><path d="M19 6h1"/><circle cx="16" cy="6" r="2.5"/><path d="M4 12h2"/><path d="M12 12h8"/><circle cx="9" cy="12" r="2.5"/><path d="M4 18h11"/><circle cx="18" cy="18" r="2.5"/></svg>Settings</a></li>
    </ul>
  </nav>
  <div class="relative z-10 min-h-svh origin-left bg-tsm03-bg transition-[translate,scale,border-radius,box-shadow] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked:translate-x-(--tsm03-w) group-has-checked:scale-[0.96] group-has-checked:overflow-hidden group-has-checked:rounded-2xl group-has-checked:shadow-[-24px_0_60px_oklch(0_0_0/0.5)] motion-reduce:transition-none">
    <label for="tsm-03-toggle" aria-hidden="true" class="pointer-events-none absolute inset-0 z-20 group-has-checked:pointer-events-auto group-has-checked:cursor-pointer"></label>
    <div class="flex items-center gap-3.5 border-b border-tsm03-acc/15 px-5 py-4">
      <label for="tsm-03-toggle" data-tsm03-burger class="relative z-30 grid size-11 cursor-pointer place-content-center gap-[5px] rounded-lg border border-tsm03-acc/15 bg-tsm03-surface transition-colors hover:bg-tsm03-acc/20 group-has-[input:focus-visible]:outline-2 group-has-[input:focus-visible]:outline-offset-2 group-has-[input:focus-visible]:outline-tsm03-acc2">
        <span class="sr-only">Toggle navigation menu</span>
        <span aria-hidden="true" class="block h-0.5 w-4 rounded-full bg-tsm03-acc2 transition-transform duration-450 group-has-checked:translate-y-[7px] group-has-checked:rotate-45"></span>
        <span aria-hidden="true" class="block h-0.5 w-4 rounded-full bg-tsm03-acc2 transition-opacity duration-450 group-has-checked:opacity-0"></span>
        <span aria-hidden="true" class="block h-0.5 w-4 rounded-full bg-tsm03-acc2 transition-transform duration-450 group-has-checked:-translate-y-[7px] group-has-checked:-rotate-45"></span>
      </label>
      <h1 class="text-[17px] font-bold">Dashboard</h1>
    </div>
    <div class="mx-auto max-w-3xl p-5">
      <p class="mb-5 max-w-prose text-sm leading-relaxed text-tsm03-mut text-pretty">The whole page slides right and recedes when the menu opens — a genuine push, not an overlay. Tap the pushed page to close it.</p>
      <div class="grid grid-cols-2 gap-2.5 md:grid-cols-4">
          <div class="rounded-xl border border-tsm03-acc/15 bg-tsm03-surface p-4"><p class="text-[22px] font-bold tabular-nums text-tsm03-acc2">7,291</p><p class="mt-1 text-[11px] text-tsm03-mut">Visitors</p></div>
          <div class="rounded-xl border border-tsm03-acc/15 bg-tsm03-surface p-4"><p class="text-[22px] font-bold tabular-nums text-tsm03-acc2">89%</p><p class="mt-1 text-[11px] text-tsm03-mut">Retention</p></div>
          <div class="rounded-xl border border-tsm03-acc/15 bg-tsm03-surface p-4"><p class="text-[22px] font-bold tabular-nums text-tsm03-acc2">$9.1k</p><p class="mt-1 text-[11px] text-tsm03-mut">Revenue</p></div>
          <div class="rounded-xl border border-tsm03-acc/15 bg-tsm03-surface p-4"><p class="text-[22px] font-bold tabular-nums text-tsm03-acc2">312</p><p class="mt-1 text-[11px] text-tsm03-mut">Sign-ups</p></div>
      </div>
    </div>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tsm03-bg: #0a0f0d;
  --color-tsm03-bg: oklch(0.162 0.009 168.9);
  --color-tsm03-surface: #131a16;
  --color-tsm03-surface: oklch(0.209 0.013 160);
  --color-tsm03-nav: #0d1a13;
  --color-tsm03-nav: oklch(0.203 0.023 159.9);
  --color-tsm03-acc: #10b981;
  --color-tsm03-acc: oklch(0.696 0.149 162.5);
  --color-tsm03-acc2: #34d399;
  --color-tsm03-acc2: oklch(0.773 0.153 163.2);
  --color-tsm03-ink: #ecfdf5;
  --color-tsm03-ink: oklch(0.979 0.021 166.1);
  --color-tsm03-mut: #a1aaa6;
  --color-tsm03-mut: oklch(0.73 0.012 167.7);
  --font-tsm03-sans: 'DM Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.tsm-03 {
  width: 100%;
  min-height: 100svh;
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>

Compiles in the browser — perfect for a CodePen or a quick test, not for production.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tsm03-bg: #0a0f0d;
  --color-tsm03-bg: oklch(0.162 0.009 168.9);
  --color-tsm03-surface: #131a16;
  --color-tsm03-surface: oklch(0.209 0.013 160);
  --color-tsm03-nav: #0d1a13;
  --color-tsm03-nav: oklch(0.203 0.023 159.9);
  --color-tsm03-acc: #10b981;
  --color-tsm03-acc: oklch(0.696 0.149 162.5);
  --color-tsm03-acc2: #34d399;
  --color-tsm03-acc2: oklch(0.773 0.153 163.2);
  --color-tsm03-ink: #ecfdf5;
  --color-tsm03-ink: oklch(0.979 0.021 166.1);
  --color-tsm03-mut: #a1aaa6;
  --color-tsm03-mut: oklch(0.73 0.012 167.7);
  --font-tsm03-sans: 'DM Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.tsm-03 {
  width: 100%;
  min-height: 100svh;
}
3Fonts used by this demooptional — skip if you have your own type stack
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400..700&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • --w moved from a custom property in the stylesheet to an arbitrary property on the root ([--tsm03-w:16.25rem]), read with v4's w-(--tsm03-w) and translate-x-(--tsm03-w) shorthands.
  • UI upgrade from the CSS original: the pushed shell now recedes (scale-[0.96], rounded-2xl, a left shadow) and the nav enters on a one-third parallax offset, so the push reads as layered depth rather than a flat slide.
  • UI upgrade: tapping the pushed page closes the menu — the original could only be closed with the burger, which had slid 260px away from the user's thumb.
  • UI upgrade: the burger now has a visible keyboard focus ring (group-has-[input:focus-visible]:) and muted text rose from #6b7280 to 7.5:1.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Off-Canvas Push Sidebar Menu
Source: https://codefronts.com/navigation/tailwind-css-side-menus/tailwind-off-canvas-push-sidebar-menu/

The true off-canvas pattern: instead of overlapping, the whole app shell is pushed right by exactly the drawer's width — and in this port it also scales back to 96% with a rounded edge, so the menu reads as a layer underneath the page. The nav slides in on a parallax offset (one-third of its width) for the depth of a native mobile app. Pure Tailwind.
## HTML
```html
<section class="tsm-03 group relative isolate w-full min-h-svh overflow-hidden bg-tsm03-nav font-tsm03-sans text-tsm03-ink [--tsm03-w:16.25rem]" aria-label="Off-canvas push sidebar demo">
  <input type="checkbox" id="tsm-03-toggle" class="peer sr-only">
  <nav aria-label="Main" class="invisible absolute inset-y-0 left-0 z-0 flex w-(--tsm03-w) -translate-x-1/3 flex-col py-6 opacity-60 transition-[translate,opacity,visibility] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked:visible group-has-checked:translate-x-0 group-has-checked:opacity-100 motion-reduce:transition-none">
    <div class="mx-5 mb-4 flex items-center gap-2.5 border-b border-tsm03-acc/15 pb-5">
      <span aria-hidden="true" class="grid size-8 place-items-center rounded-lg bg-tsm03-acc text-sm font-bold text-black">G</span>
      <p class="font-bold">Grove</p>
    </div>
    <ul class="grid gap-1 px-2.5">
      <li><a href="#" class="flex min-h-11 items-center gap-3 rounded-lg px-3.5 text-sm font-medium text-tsm03-mut transition-colors hover:bg-tsm03-acc/10 hover:text-tsm03-ink focus-visible:outline-2 focus-visible:outline-tsm03-acc2 aria-[current=page]:bg-tsm03-acc/12 aria-[current=page]:font-semibold aria-[current=page]:text-tsm03-acc2" aria-current="page"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 10.5 12 3l9 7.5"/><path d="M5 9.5V20h14V9.5"/><path d="M10 20v-6h4v6"/></svg>Home</a></li>
      <li><a href="#" class="flex min-h-11 items-center gap-3 rounded-lg px-3.5 text-sm font-medium text-tsm03-mut transition-colors hover:bg-tsm03-acc/10 hover:text-tsm03-ink focus-visible:outline-2 focus-visible:outline-tsm03-acc2 aria-[current=page]:bg-tsm03-acc/12 aria-[current=page]:font-semibold aria-[current=page]:text-tsm03-acc2"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 3v18h18"/><path d="m7 15 4-4 3 3 5-6"/></svg>Analytics</a></li>
      <li><a href="#" class="flex min-h-11 items-center gap-3 rounded-lg px-3.5 text-sm font-medium text-tsm03-mut transition-colors hover:bg-tsm03-acc/10 hover:text-tsm03-ink focus-visible:outline-2 focus-visible:outline-tsm03-acc2 aria-[current=page]:bg-tsm03-acc/12 aria-[current=page]:font-semibold aria-[current=page]:text-tsm03-acc2"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6v18h12V7z"/><path d="M14 3v4h4"/><path d="M9 13h6M9 17h6"/></svg>Reports</a></li>
      <li><a href="#" class="flex min-h-11 items-center gap-3 rounded-lg px-3.5 text-sm font-medium text-tsm03-mut transition-colors hover:bg-tsm03-acc/10 hover:text-tsm03-ink focus-visible:outline-2 focus-visible:outline-tsm03-acc2 aria-[current=page]:bg-tsm03-acc/12 aria-[current=page]:font-semibold aria-[current=page]:text-tsm03-acc2"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0"/><path d="M16 4.5a3.5 3.5 0 0 1 0 7"/><path d="M18 14.5a6.5 6.5 0 0 1 3.5 5.5"/></svg>Team</a></li>
      <li><a href="#" class="flex min-h-11 items-center gap-3 rounded-lg px-3.5 text-sm font-medium text-tsm03-mut transition-colors hover:bg-tsm03-acc/10 hover:text-tsm03-ink focus-visible:outline-2 focus-visible:outline-tsm03-acc2 aria-[current=page]:bg-tsm03-acc/12 aria-[current=page]:font-semibold aria-[current=page]:text-tsm03-acc2"><svg class="size-[18px] shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6h9"/><path d="M19 6h1"/><circle cx="16" cy="6" r="2.5"/><path d="M4 12h2"/><path d="M12 12h8"/><circle cx="9" cy="12" r="2.5"/><path d="M4 18h11"/><circle cx="18" cy="18" r="2.5"/></svg>Settings</a></li>
    </ul>
  </nav>
  <div class="relative z-10 min-h-svh origin-left bg-tsm03-bg transition-[translate,scale,border-radius,box-shadow] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] group-has-checked:translate-x-(--tsm03-w) group-has-checked:scale-[0.96] group-has-checked:overflow-hidden group-has-checked:rounded-2xl group-has-checked:shadow-[-24px_0_60px_oklch(0_0_0/0.5)] motion-reduce:transition-none">
    <label for="tsm-03-toggle" aria-hidden="true" class="pointer-events-none absolute inset-0 z-20 group-has-checked:pointer-events-auto group-has-checked:cursor-pointer"></label>
    <div class="flex items-center gap-3.5 border-b border-tsm03-acc/15 px-5 py-4">
      <label for="tsm-03-toggle" data-tsm03-burger class="relative z-30 grid size-11 cursor-pointer place-content-center gap-[5px] rounded-lg border border-tsm03-acc/15 bg-tsm03-surface transition-colors hover:bg-tsm03-acc/20 group-has-[input:focus-visible]:outline-2 group-has-[input:focus-visible]:outline-offset-2 group-has-[input:focus-visible]:outline-tsm03-acc2">
        <span class="sr-only">Toggle navigation menu</span>
        <span aria-hidden="true" class="block h-0.5 w-4 rounded-full bg-tsm03-acc2 transition-transform duration-450 group-has-checked:translate-y-[7px] group-has-checked:rotate-45"></span>
        <span aria-hidden="true" class="block h-0.5 w-4 rounded-full bg-tsm03-acc2 transition-opacity duration-450 group-has-checked:opacity-0"></span>
        <span aria-hidden="true" class="block h-0.5 w-4 rounded-full bg-tsm03-acc2 transition-transform duration-450 group-has-checked:-translate-y-[7px] group-has-checked:-rotate-45"></span>
      </label>
      <h1 class="text-[17px] font-bold">Dashboard</h1>
    </div>
    <div class="mx-auto max-w-3xl p-5">
      <p class="mb-5 max-w-prose text-sm leading-relaxed text-tsm03-mut text-pretty">The whole page slides right and recedes when the menu opens — a genuine push, not an overlay. Tap the pushed page to close it.</p>
      <div class="grid grid-cols-2 gap-2.5 md:grid-cols-4">
          <div class="rounded-xl border border-tsm03-acc/15 bg-tsm03-surface p-4"><p class="text-[22px] font-bold tabular-nums text-tsm03-acc2">7,291</p><p class="mt-1 text-[11px] text-tsm03-mut">Visitors</p></div>
          <div class="rounded-xl border border-tsm03-acc/15 bg-tsm03-surface p-4"><p class="text-[22px] font-bold tabular-nums text-tsm03-acc2">89%</p><p class="mt-1 text-[11px] text-tsm03-mut">Retention</p></div>
          <div class="rounded-xl border border-tsm03-acc/15 bg-tsm03-surface p-4"><p class="text-[22px] font-bold tabular-nums text-tsm03-acc2">$9.1k</p><p class="mt-1 text-[11px] text-tsm03-mut">Revenue</p></div>
          <div class="rounded-xl border border-tsm03-acc/15 bg-tsm03-surface p-4"><p class="text-[22px] font-bold tabular-nums text-tsm03-acc2">312</p><p class="mt-1 text-[11px] text-tsm03-mut">Sign-ups</p></div>
      </div>
    </div>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tsm03-bg: #0a0f0d;
  --color-tsm03-bg: oklch(0.162 0.009 168.9);
  --color-tsm03-surface: #131a16;
  --color-tsm03-surface: oklch(0.209 0.013 160);
  --color-tsm03-nav: #0d1a13;
  --color-tsm03-nav: oklch(0.203 0.023 159.9);
  --color-tsm03-acc: #10b981;
  --color-tsm03-acc: oklch(0.696 0.149 162.5);
  --color-tsm03-acc2: #34d399;
  --color-tsm03-acc2: oklch(0.773 0.153 163.2);
  --color-tsm03-ink: #ecfdf5;
  --color-tsm03-ink: oklch(0.979 0.021 166.1);
  --color-tsm03-mut: #a1aaa6;
  --color-tsm03-mut: oklch(0.73 0.012 167.7);
  --font-tsm03-sans: 'DM Sans', system-ui, sans-serif;
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
   stage is sized before the browser build compiles. */

.tsm-03 {
  width: 100%;
  min-height: 100svh;
}
```

How this works

The shell moves, the nav waits underneath. The nav is absolute at z-0; the shell sits above it at z-10 with an opaque background. Opening translates the shell by the custom property that also sizes the nav:

<section class="group [--tsm03-w:16.25rem] …">
  <nav class="w-(--tsm03-w) -translate-x-1/3 group-has-checked:translate-x-0">
  <div class="transition-[translate,scale,border-radius]
    group-has-checked:translate-x-(--tsm03-w)
    group-has-checked:scale-[0.96] group-has-checked:rounded-2xl">

Why scale and translate don't fight. v4 writes them to the separate translate and scale properties, so the shell can shrink around its own centre while it slides — no hand-written transform list to keep in order.

v4's translate-x-(--var) is shorthand for translate-x-[var(--var)]; renaming the property re-tunes both elements at once.

Make it yours

  • Push distance: change [--tsm03-w:16.25rem] on the root — nav width and shell offset stay locked together.
  • Flat push: delete group-has-checked:scale-[0.96] and group-has-checked:rounded-2xl for the classic edge-to-edge shift.
  • No parallax: replace -translate-x-1/3 with -translate-x-full so the nav moves 1:1 with the shell.
  • Right-hand push: put the nav at right-0 and use group-has-checked:-translate-x-(--tsm03-w) on the shell.

Gotchas — read before shipping

  • position:fixed children inside a transformed shell become relative to the shell, not the viewport — sticky headers will ride along with the push.
  • Keep overflow-hidden on the root (the stage), not the shell, or the shell clips its own shadow and rounded corner.
  • The close-label must sit inside the shell so it moves with it; outside, it would cover the nav too.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

Individual translate/scale properties are Chrome 104 / Safari 14.1 / Firefox 72; the floor is v4's own sheet.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Theme tokensset in @theme, used by a utility

Search CodeFronts

Loading…