CSS
iOS
position fixed
web development
mobile browsers

position fixed doesn't work on iPad and iPhone

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

When position: fixed appears broken on iPhone or iPad, the issue is often not the CSS rule itself but how iOS Safari changes the visible viewport during scroll, address-bar collapse, and keyboard display. A stable solution usually involves better viewport sizing, safe-area handling, and avoiding layout patterns that confuse fixed-position anchoring.

Why iOS Makes Fixed Layouts Feel Unstable

On desktop browsers, a fixed header or footer usually stays attached to a predictable viewport. On iOS Safari, the visible viewport can change as browser chrome expands and collapses. That means a layout based on old assumptions such as static 100vh can jump or overlap content.

Typical symptoms include:

  • bottom bars shifting during scroll
  • fixed headers overlapping content after URL bar changes
  • controls moving unexpectedly when the keyboard opens

These are often viewport-model problems rather than proof that fixed positioning is unsupported.

Use Better Viewport Units and Safe-Area Insets

A good starting point is to configure the viewport correctly and size the page with dynamic viewport units.

html
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
css
1:root {
2  --bottom-safe: env(safe-area-inset-bottom);
3}
4
5.page {
6  min-height: 100dvh;
7}
8
9.footer {
10  position: fixed;
11  left: 0;
12  right: 0;
13  bottom: 0;
14  padding: 12px 16px calc(12px + var(--bottom-safe));
15  background: #111827;
16  color: white;
17}

100dvh tracks the dynamic viewport more accurately than older 100vh in the situations where iOS browser UI changes height.

Prefer sticky When Fixed Is More Than You Need

Some layouts use fixed positioning even though position: sticky would satisfy the requirement with fewer edge cases.

css
1.header {
2  position: sticky;
3  top: 0;
4  z-index: 1000;
5  background: #0f172a;
6  color: white;
7}

If the goal is just a persistent top bar during page scroll, sticky is often more forgiving on mobile browsers.

The rule of thumb is simple: use fixed only when the element must stay pinned to the viewport itself. Otherwise, sticky may be the better fit.

Watch Out for Ancestor Transforms

A fixed element can behave strangely if an ancestor establishes a new containing or compositing context. The usual suspects are properties such as:

  • 'transform'
  • 'filter'
  • 'perspective'
  • certain containment-related styles

If a supposedly fixed element behaves more like it is absolutely positioned inside a wrapper, audit the ancestor chain first. Removing an unnecessary transform on a layout wrapper often resolves the issue.

Handle Keyboard Resizing Deliberately

The on-screen keyboard can shrink the visible viewport and make fixed elements appear to jump or overlap form fields. If the screen includes fixed controls near inputs, you may need to react to viewport changes.

javascript
1const root = document.documentElement;
2
3function syncViewportHeight() {
4  const height = window.visualViewport ? window.visualViewport.height : window.innerHeight;
5  root.style.setProperty('--vvh', `${height}px`);
6}
7
8window.addEventListener('resize', syncViewportHeight);
9window.visualViewport?.addEventListener('resize', syncViewportHeight);
10syncViewportHeight();
css
.app-shell {
  min-height: var(--vvh);
}

This is not always necessary, but for input-heavy mobile screens it can make the layout much more predictable.

Test on Real Devices

Desktop emulation is helpful but not enough for this class of bug. Real-device testing matters because iOS Safari browser chrome and keyboard behavior are where the problem usually lives.

At minimum, test:

  • iPhone Safari with normal scrolling
  • keyboard-open states on forms
  • portrait and landscape
  • iPad Safari if the layout targets tablets

That gives you a much more realistic signal than desktop responsive mode alone.

Common Pitfalls

The biggest pitfall is using 100vh everywhere and expecting it to reflect the visible mobile viewport consistently. Another is ignoring safe-area insets for bottom-fixed controls on devices with a home indicator.

Developers also often leave transforms on large wrapper elements and then debug the fixed child instead of the containing context.

Finally, many layouts use fixed positioning where sticky would be simpler and more robust. Choosing the lighter behavior often solves the problem before any JavaScript is needed.

Summary

  • iOS fixed-position issues are usually viewport and container-context problems, not simple CSS syntax bugs.
  • Use dynamic viewport units and safe-area insets for more stable mobile layouts.
  • Prefer position: sticky when the element does not truly need viewport-level pinning.
  • Audit ancestor transforms if fixed elements behave like they are trapped in a wrapper.
  • Verify the result on real iPhone and iPad devices, especially around scroll and keyboard interactions.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.