safe-area-inset-bottom Is 0 or Ignored? Fix an iPhone Footer
If env(safe-area-inset-bottom) is 0px or an iPhone home indicator still covers a footer, first separate three cases: the browser reports no inset, the inset is applied to the wrong box, or the footer works but covers its scroll container. Use viewport-fit=cover for an edge-to-edge layout, add the inset to the footer’s padding, and reserve the footer’s full height in the element that scrolls.
Use the smallest working pattern
Opt into the full display area, then keep the base spacing separate from the device inset:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">:root { --safe-area-bottom: env(safe-area-inset-bottom, 0px);}
.mobile-footer { position: fixed; right: 0; bottom: 0; left: 0; padding: 0.75rem 1rem calc(0.75rem + var(--safe-area-bottom)); background: Canvas;}
main { padding-bottom: calc(4rem + var(--safe-area-bottom));}The footer’s padding moves its buttons above the home-indicator area while keeping the background edge-to-edge. The main padding prevents the last content from hiding behind the fixed footer. Adjust 4rem to the actual footer height; the safe-area inset is only the additional device spacing.
Why the inset is 0px
env() reports the environment value for the current viewport. Common reasons for a zero value are:
| Situation | What it means |
|---|---|
| Desktop browser or rectangular phone | There is no bottom obstruction to reserve |
viewport-fit=cover is missing | The page may already be laid out inside a safe area |
| Browser tab versus installed web app | Standalone and browser contexts can expose different viewport behavior |
| Padding is on the wrong element | The inset may be applied to a wrapper while the fixed controls remain covered |
| Invalid or unsupported CSS path | Use the fallback argument and inspect the computed rule |
The fallback in env(safe-area-inset-bottom, 0px) keeps the declaration valid when the environment variable is unavailable. It does not manufacture an inset on a device that reports none.
Measure the computed inset instead of guessing
Reading a custom property’s source text can leave you looking at env(...) rather than the length used by a layout property. Put the environment value on a temporary probe and read its computed padding:
<div id="safe-area-probe" aria-hidden="true"></div>#safe-area-probe { position: fixed; right: 0; bottom: 0; left: 0; padding-bottom: env(safe-area-inset-bottom, 0px); visibility: hidden; pointer-events: none;}const probe = document.querySelector('#safe-area-probe');const viewport = document.querySelector('meta[name="viewport"]');
console.table({ paddingBottom: getComputedStyle(probe).paddingBottom, viewport: viewport?.content ?? 'missing', displayMode: matchMedia('(display-mode: standalone)').matches ? 'standalone' : 'browser',});Run this on the device and display mode that shows the problem. Then use the result to choose the next check:
| Probe result | Visible symptom | Next check |
|---|---|---|
0px on desktop or a rectangular viewport | No obstruction | Expected; keep normal base padding |
0px on the affected iPhone | Home indicator covers controls | Confirm the effective viewport meta includes viewport-fit=cover, then retest in browser and standalone modes |
| A positive value | Controls are still covered | Inspect whether another rule overrides the footer padding or the inset is attached to a wrapper instead of the footer |
| A positive value and controls are clear | Last page item is hidden | Add the footer’s full occupied height to the actual scrolling container |
The safe-area inset describes the unsafe edge, not the entire footer and not every browser toolbar or software-keyboard transition. A positive inset can therefore be correct while a separate viewport or scrolling problem remains.
Put padding on the obscured box and the scroll container
Two layout problems are often conflated:
- The home indicator covers the footer’s buttons. Add the inset to the footer’s bottom padding.
- The fixed footer covers the page’s last link or form field. Add enough bottom padding to the element that scrolls, such as
mainor the app’s scroll wrapper.
Changing only bottom: env(safe-area-inset-bottom) can move the whole footer upward and leave an unwanted gap below its background. Padding is usually the better first fix because it preserves the full-width surface while moving the controls.
If the page scrolls inside a nested element, padding on body may not affect the scrollable content. Apply the reservation to that nested scroll container and verify the final focusable element can scroll above the footer.
Check the viewport declaration and CSS box model
Make sure there is one effective viewport declaration and that the page is allowed to use the display area. Then check:
box-sizingand the footer’s actual rendered height after padding;- whether another rule overrides the
padding-bottomdeclaration; - whether the fixed footer has a higher stacking order than content;
- whether a keyboard, browser toolbar, or dynamic viewport change is being mistaken for the safe-area inset;
- whether a sticky element has the same scroll container you are testing.
Do not use a hard-coded iPhone-only height. The safe-area variable is a runtime value, and the base padding should remain useful on devices that report 0px.
Test in the context that fails
Desktop emulation can confirm that the declaration parses, but it cannot fully prove a home-indicator layout. Test the real target in a browser tab and, if relevant, as an installed home-screen web app. Scroll to the last interactive element, rotate the device, open the keyboard, and check that the footer background and controls behave independently.
Use the computed-padding probe above rather than inferring support from desktop emulation. If it reports 0px, test the target device and display mode before changing the formula. If it reports a positive value, move on to the footer box and scroll-container checks instead of adding a larger hard-coded inset.
FAQ
Q: Does env(safe-area-inset-bottom) work without viewport-fit=cover?
A: The reliable pattern for edge-to-edge layouts is to declare viewport-fit=cover and then apply the environment inset. Without it, the browser may keep the page inside a safe region, so the value or visual result may not match an edge-to-edge footer.
Q: Should I use the inset on bottom or padding-bottom?
A: Use padding-bottom when the footer background should remain edge-to-edge and its controls need lifting. Reserve additional bottom space on the scrolling content so a fixed footer does not hide the last item.
Q: Why is the value zero on my desktop browser?
A: Desktop and rectangular viewports normally have no unsafe bottom region, so a zero value is expected. Validate the behavior on the mobile browser or installed web-app context that has the obstruction.
Q: How can I tell whether safe-area-inset-bottom is actually applied?
A: Assign the environment value to a real property such as padding-bottom on a temporary element, then read that property’s computed value. A positive value means the browser supplied an inset; if the controls remain covered, inspect which box owns the padding and which element scrolls.
References:
MDN:
env()CSS environment variablesWebKit: Designing Websites for iPhone X
WebKit Bug 236445: safe-area values for home-screen websites
Report a typo or broken link, or suggest a related topic.