Issue: I am making a ReactJS app with a series of input fields midway down the page. These fields have been positioned so that the virtual keyboard doesn't conflict with them. However, when I focus on the textfields on an Apple device, the viewport is scrolled such that the input fields are vertically centered. I want to disable this so that the page stays unaffected and the virtual keyboard just covers the bottom of the page. I am using ReactJs, Typescript, and mui for the TextField.
Here is a side-by-side screenshot: Note that on the left, the text field is unfocused and correctly placed vertically. On the right, when the text field is focused, the viewport is scrolled to center the textfield.
The desired condition is for the textField to retain it's original position and be located just above the keyboard, not centered in the smaller viewport.
Code Sandbox I've created a simplified example of this problem in the below Sandbox. It's just create-react-app with mui. https://codesandbox.io/s/serene-morning-38b4xi?file=/public/index.html
I have tried:
- setting a container element to
position:fixed
- adding a
window.ScrollTo(0,0)
event toonFocus
from: iOS Safari: Prevent (or Control) Scroll on Input Focus and How to prevent iOS keyboard from pushing the view off screen with CSS or JS
- disabling scroll
from: Disable auto scroll on Safari iOS16 and iOS 15 + single tab enabled
-ensuring meta tag is set to:
<meta name="viewport" content="viewport-fit=cover, shrink-to-fit=no, minimum-scale=1, initial-scale=1, width=device-width" />
Here's the code:
App.tsx:
import { TextField } from "@mui/material";
export default function App() {
return (
<div style={{ position: "fixed", height: "100%", width: "100%" }}>
<div style={{ position: "absolute", top: "200px" }}>
<TextField
fullWidth
variant="filled"
autoComplete="off"
onChange={() => {}}
onFocus={() => {
setTimeout(() => window.scrollTo(0, 0), 50);
}}
value={"test"}
/>
</div>
</div>
);
}
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="viewport-fit=cover, minimum-scale=1, width=device-width, initial-scale=1"
/>
<meta name="theme-color" content="#000000" />
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>