Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

3 Commits

Repository files navigation

🏗️ Mobile-Shell: Universal iOS Safari & Mobile Web UI Fix

Stabilize your mobile web layouts in 60 seconds. Solve jumping bottom menus, broken popups, and the "100vh lie" on iOS Safari, Chrome, and Firefox using modern CSS Dynamic Viewport units (dvh) and a robust shell architecture.

#iOS#Safari#NextJS#TailwindCSS#WebDev#PWA#MobileUX#Frontend


🚀 The 1-Minute Quick Fix

A professional, drop-in solution for Next.js 15+ and Tailwind CSS 4+ projects to solve "jumping" layouts, detached bottom menus, and broken popups on iOS browsers (Safari, Chrome, Firefox).

⚡ Quick Start: The 1-Minute Copy-Paste

1. Update layout.tsx (Metadata & Shell)

Add viewportFit: 'cover' to your viewport config and wrap your app in the Flexbox Shell.

// app/layout.tsximport{Viewport}from"next";exportconstviewport: Viewport={width: "device-width",initialScale: 1,viewportFit: 'cover',// Required to handle iPhone notches and toolbars};exportdefaultfunctionRootLayout({ children }: {children: React.ReactNode}){return(<htmllang="en">{/*  h-dvh: Dynamic Viewport Height (responsive to keyboard) overflow-hidden: Prevents the entire page from scrolling/bouncing */}<bodyclassName="h-dvh overflow-hidden flex flex-col bg-white">{/* FIXED HEADER */}<headerclassName="flex-none p-4 border-b">Header (Static)</header>{/* SCROLLABLE CONTENT (The Magic Box) */}<divclassName="flex-1 overflow-y-auto overscroll-contain [WebkitOverflowScrolling:touch]"><mainclassName="min-h-full">{children}</main><footerclassName="p-8 border-t bg-zinc-50">Footer (Inside Scroll)</footer></div></body></html>);}

2. Update globals.css (CSS Reset)

Lock the body height and disable the "rubber-banding" effect.

/* globals.css */@import"tailwindcss";
html,body {
max-width:100dvw;
overflow-x: hidden;
width:100%;
}
body {
/* h-dvh adapts to the virtual keyboard and Safari toolbars! */height:100dvh; overflow: hidden;
position: relative;
overscroll-behavior: none; /* Disables page bounce */
}

🧐 What Problem Does This Solve?

On iOS Safari, the browser toolbars are dynamic. When you use 100vh, the UI often gets "pushed" or buttons at the bottom become unclickable/hidden under the toolbar.

This solution provides:

  1. No Layout Jumps: When the keyboard opens, the dvh unit recalculates, and only the internal content area shrinks. Headers stay at the top, and bottom-docked elements stay visible.
  2. Safe Area Support: Uses viewportFit: 'cover' to ensure your app background covers the area behind the notch.
  3. Native Feel: Disables the annoying "page bounce" (rubber-banding) using overscroll-behavior: none.
  4. Universal Compatibility: Works on Safari, Chrome, and Firefox for iOS (all use WebKit).

🛠️ Requirements

  • Next.js 15+
  • Tailwind CSS 4+
  • TypeScript 5+

📄 License

MIT

About

The ultimate 1-minute fix for iOS Safari & Mobile Web layout stability. No more "jumping" bottom menus or broken popups on iPhone.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages