Need help setting up p-safe class strategy for a Next.js pwa app with a fixed top and bottom navbar
Hi there. Thanks for the plugin. I'm trying to perform an optmized UX for my pwa app (Next.js 12 / Tailwindcss / Shadcn ui) when installed on iOS fullscreen / standalone mode.
The issue is I can't find the right "recipe" when applying p-safe classes to my app's layout structure, as it is shown bellow...
The top and bottom navbars are working as expected with the safe padding apllied properly when in fullscreen / standalone mode. However, I'm still having issues with the body that ends up getting a huge extra top padding when the app is opened on iOS standalone mode, it also seems to block interactivity until it is touched or scrolled, which is when it kind of falls back to a normal acceptable padding.
Even if I remove the safe padding from the body and then try to apply a top and bottom padding to the main layout, something is just not right in fullscreen mode. I'd really appreciate any guidance regarding the layout. Thanks in advance!
global.css
html {
display: flex;
flex-direction: column;
}
html,
body {
height: -webkit-fill-available;
}
body {
flex-grow: 1;
/* PWA enhancements */
-webkit-overflow-scrolling: touch;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
overflow-x: hidden;
@apply flex flex-col bg-background text-foreground antialiased select-none pt-safe pb-safe;
}
top-navbar.tsx
interface TopNavProps {
title?: string
}
export const TopNav = ({ title }: TopNavProps) => {
return (
<header className='site-header fixed left-0 top-0 z-40 w-full border-b border-border bg-secondary px-safe pt-safe'>
<div className='mx-auto flex h-16 w-full max-w-screen-lg items-center justify-between px-6'>
...
</div>
</header>
)
}
bottom-nav.tsx
export const BottomNav = () => {
return (
<nav className='bottom-nav fixed bottom-0 left-0 z-40 w-full border-t border-border bg-secondary pb-safe'>
<div className='mx-auto flex h-16 max-w-md items-center justify-around px-6'>
...
</div>
</nav>
)
}
layout.tsx
import Head from 'next/head'
import { Appbar } from '@/components/nav-top'
import { BottomNav } from '@/components/nav-bottom'
import { cn } from '@/lib/utils'
interface PageLayoutProps {
title?: string
className?: string
children: React.ReactNode
}
export const PageLayout = ({ title, className, children }: PageLayoutProps): JSX.Element => (
<>
{title ? (
<Head>
<title>{title} - Mio Vino</title>
</Head>
) : null}
<Appbar title={title} />
<main
/**
* Padding top = `appbar` height
* Padding bottom = `bottom-nav` height
*/
className={cn('mx-auto max-w-screen-lg px-safe pt-16 pb-20', className)}
>
<div className='px-6 py-4'>{children}</div>
</main>
<BottomNav />
</>
)