How to make fixed elements respect the virtual keyboard on iOS
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!