Lesson 28 of 30
A fixed bottom bar that looks perfect in the simulator can sit right on top of a device's home-indicator gesture area in real life. env() is how CSS asks the device how much room it actually needs.
10 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
A fixed bottom action bar uses `padding-bottom: max(1rem, env(safe-area-inset-bottom))`, but on a real test device the extra padding never seems to apply — it always looks like plain `1rem`. What's the most likely cause?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Modern mobile devices increasingly have screens that aren't simple rectangles: cutouts for cameras, rounded corners, and gesture bars along an edge (a home-indicator strip, for instance) all carve into the area where content would otherwise render. The operating system knows exactly how much space each of these cutouts needs, but a stylesheet written with a fixed padding: 1rem has no way to know that number — it's specific to the device and orientation the page happens to be running on.
env(safe-area-inset-*) solves this by having the browser expose that number to your CSS, instead of you having to guess it. There are four values — env(safe-area-inset-top), -right, -bottom, and -left — each resolving to the inset needed on that edge for the current device, or 0 on a device with no cutout to account for. You use them like any other length value, most often combined with max() so you never end up with less padding than your design already wanted:
.bottom-nav {
padding-bottom: max(1rem, env(safe-area-inset-bottom));
}
That single line means: use at least 1rem of padding, but use more if the device says it needs more room. On a device with no cutout, env(safe-area-inset-bottom) resolves to 0, max() picks 1rem, and nothing changes. On a device with a gesture bar carving into the bottom edge, the padding grows to whatever the device reports, and the nav bar's content stays clear of it.
.action-bar {
position: fixed;
inset-inline: 0;
bottom: 0;
padding-block: 0.75rem;
padding-inline: max(1rem, env(safe-area-inset-left)) max(1rem, env(safe-area-inset-right));
padding-bottom: calc(0.75rem + env(safe-area-inset-bottom));
}
Without the inset values, this bar looks correct in a desktop browser and in most simulators, then ships to a real device where its bottom edge sits directly under (or gets partially obscured by) the device's own gesture area — a button that's fully tappable on paper becomes awkward or unreliable to actually tap. The fix isn't a media query or a device-specific hack; it's asking the browser for the number it already knows.
viewport-fit=cover is a real, easy-to-miss prerequisite. Without it, every env(safe-area-inset-*) resolves to 0 and the fix silently does nothing — there's no error, no warning, just padding that looks like it was never applied.env() values should combine with your existing spacing, not replace it. padding-bottom: env(safe-area-inset-bottom) alone throws away your design's intended minimum padding on devices that report 0 — wrapping it in max(1rem, env(safe-area-inset-bottom)) keeps the deliberate spacing as a floor.safe-area-inset-bottom can still get clipped sideways after a device rotation."A user reports a button at the bottom of the screen is hard to tap on their phone, but you can't reproduce it in the browser simulator" is a realistic debugging scenario — recognizing env(safe-area-inset-bottom) and the viewport-fit=cover prerequisite as the likely cause shows real mobile-web experience past what a desktop-only testing habit would catch.