-
-
Save MartijnHols/e9f4f787efa9190885a708468f63c5bb to your computer and use it in GitHub Desktop.
The latest version is available at https://martijnhols.nl/gists/how-to-get-document-height-ios-safari-osk |
import { useEffect } from 'react' | |
const useOnScreenKeyboardScrollFix = () => { | |
useEffect(() => { | |
const handleScroll = () => { | |
window.scrollTo(0, 0) | |
} | |
window.addEventListener('scroll', handleScroll) | |
return () => { | |
window.removeEventListener('scroll', handleScroll) | |
} | |
}, []) | |
} | |
export default useOnScreenKeyboardScrollFix |
You might need a few timeouts like I did in the useViewportSize
hook, but that will be kind of ugly for the user. Luckily it will only be ugly for the crazy browsers.
// Closing the OSK in iOS does not immediately update the visual viewport
// size :<
setTimeout(updateViewportSize, 1000)
One nice thing is that since you're setting scroll position to 0 every time, you can fairly easily start multiple timeouts without the user noticing.
It seems to work if I adjust the maxHeight instead of the height and it has a h-full class from tailwind ( which is just height:100% )
import { ElementType, HTMLAttributes } from "react";
import useViewportSize from "@/hooks/useViewportSize";
import useOnScreenKeyboardScrollFix from "@/hooks/useOnScreenKeyboardScrollFix";
import usePreventOverScrolling from "@/hooks/usePreventOverScrolling";
import useIsOnScreenKeyboardOpen from "@/hooks/useOnScreenKeyboardOpen";
interface Props extends HTMLAttributes<HTMLDivElement> {
element?: ElementType;
}
export function FullViewportContainer({
element: Element = "div",
...others
}: Props) {
useOnScreenKeyboardScrollFix();
const [, viewportHeight] = useViewportSize() ?? [];
const ref = usePreventOverScrolling();
const isOnScreenKeyboardOpen = useIsOnScreenKeyboardOpen();
return (
<Element
{...others}
ref={ref}
className="w-full h-full"
style={{
maxHeight: viewportHeight,
padding: isOnScreenKeyboardOpen
? "env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left)"
: "env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)",
transition: "padding 100ms, height 100ms",
}}
/>
);
}
Aaaand it must be the direct children of the root it seems
Little tricky. Sucks that mobile-PWA development is so harsh sometimes. But this solution works like a charm. Love it. Many thanks!
when i use useOnScreenKeyboardScrollFix, the scroll content in FullViewportContainer will stop scroll, so i can not scroll into view on focusin
how can i get keyboard height
I have added this line
So it always scrolls to 0 if the viewportHeight changes but it also doesnt work.
Browser is standard android google chrome btw