How to make fixed elements respect the virtual keyboard on iOS

How to make fixed elements respect the virtual keyboard on iOS

ยท

2 min read

Featured on Hashnode

Apple likes to "think different" (and tell us about it too).

Sometimes this leads to cool stuff, and other times it results in position: fixed elements that get hidden behind the virtual keyboard on iOS... No matter how hard you try to coerce them otherwise.

Meanwhile, to fix an element to the bottom of the screen while still respecting the virtual keyboard on Android you simply need the following CSS:

.stick-to-my-keyboard-damnit {
  position: fixed;
  bottom: 0;
  right: 32px; /* or wherever else you want it horizontally */
}

In my humble opinion, this is exactly how it should be universally.

But because Apple is Apple, we need to make use of JavaScript's Visual Viewport API to fix elements to the bottom of the screen while still accounting for the virtual keyboard.

The results

That's right iOS - get some!

The solution

The solution is to listen for window.visualViewport resize events, get the Visual Viewport's height, position the elements you want flush with the bottom edge using this height and the top property (not bottom), and then lastly translate the element by -100% on the Y axis via the CSS transform property.

A simple implementation in vanilla HTML, CSS and JavaScript might look something like this:

<footer class="stick-it-to-the-man">
  <p>Look I'm at the bottom!</p>
</footer>
.stick-it-to-the-man {
  position: fixed;
  left: 0;
  width: 100%;
  transform: translateY(-100%);
  text-align: center;
}
const footer = document.querySelector('.stick-it-to-the-man');

if (window.visualViewport) {
  const vv = window.visualViewport;

  function fixPosition() {
    footer.style.top = `${vv.height}px`;
  }  

  vv.addEventListener('resize', fixPosition);
  fixPosition(); // Make sure we call it once before resizing too
}

Note that my implementation for ContentCats was done in Next.js / React, so it looks a bit different. That said, the above simple vanilla implementation should work without a problem as it's leveraging the same API and concepts.

What's your favourite thing about Apple?

What's the thing you loathe most about them? ๐Ÿ˜น

Let me know in the comments!

Until next time, keep creating!

ย