Keep bottom action buttons visible on iOS using React

maxmax
2 min read

If you've ever built a mobile-friendly web app, you've probably noticed that iOS Safari and Chrome handle the on-screen keyboard differently than Android. When the keyboard pops up, any element that's fixed to the bottom of the viewport disappears behind it.

I ran into this while building a form. Users couldn't see the "Submit" button once they focused an input field, because the keyboard covered it. CSS position: fixed just wasn't enough.

To solve this, I wrote a small React component that listens to the visualViewport API to detect the keyboard height and adjust the element's position in real time. It fades out when the user scrolls so it doesn't get in the way, and falls back to normal behaviour on non-iOS devices.

The component is open source; feel free to use it or contribute. You can install it from npm:

npm install react-bottom-fixed

Then wrap your bottom action in the BottomFixedArea component. It accepts any children and an optional edgeOffset prop in pixe

import BottomFixedArea from "react-bottom-fixed";

function Checkout() {
  return (
    <div>
      {/* ...other form fields... */}
      <BottomFixedArea edgeOffset={12}>
        <button type="submit">Confirm order</button>
      </BottomFixedArea>
    </div>
  );

The default edgeOffset is 0 but you can increase it if you need a bit more spacing above the keyboard.

Under the hood it listens to visualViewport changes and updates the bottom style accordingly. On browsers that don't support visualViewport (most Android), the component simply renders your children in place.


I'd love feedback or suggestions! If this helps you keep important actions visible on iOS, please give it a try and let me know how it goes. Pull requests are welcome

You can find the source code on GitHub: https://github.com/almond-bongbong/react-bottom-fixed ๐Ÿ™‚

0
Subscribe to my newsletter

Read articles from max directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

max
max