Last active
March 20, 2025 17:14
-
-
Save MartijnHols/e9f4f787efa9190885a708468f63c5bb to your computer and use it in GitHub Desktop.
React hooks for getting the document height that updates when the On Screen Keyboard/Virtual Keyboard toggles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The latest version is available at https://martijnhols.nl/gists/how-to-get-document-height-ios-safari-osk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.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.