Repository navigation
Theme the system navigation bar for edge-to-edge #110
Copy link
Copy link
Open
Description
Goal
On Android 15+ (we target SDK 36) the system status and navigation bars are transparent overlays. We want them to blend with the app's Material You theme in light and dark, including 3-button navigation mode where the navigation bar region is clearly visible.
Why this is blocked
Attempted in #107 (closed). The supported, no-custom-code approach does not fully work yet, and the gap is upstream in MAUI.
- Direct bar coloring is gone on API 35+.
Window.setStatusBarColorandsetNavigationBarColorare deprecated no-ops. The only supported model is to render edge-to-edge (content under the bars) and let the page background show through the transparent bars. - Letterboxing leaves the nav bar black. With the supported
SafeAreaEdges="All", MAUI pads around the BlazorWebView, so the page sits inset inside the bars. The transparent navigation bar then reveals the uncolored window background, which renders black. Setting the MAUI pageBackgroundColordoes not fill the region behind the system bars. This is the "nav bar is still black" symptom, most obvious with 3-button navigation. - True edge-to-edge in a Blazor Hybrid app is upstream-broken. Pushing the WebView content under the bars requires the DOM to pad itself with
env(safe-area-inset-*), which is unreliable in Android WebView below Chromium 140, and MAUI's own Blazor Hybrid safe-area handling is broken: dotnet/maui#34462 (open, milestone .NET 10 SR9). - We prototyped a custom
WindowInsetsto CSS-variable bridge that did achieve true edge-to-edge, but chose not to maintain hand-rolled platform plumbing for something the framework is expected to handle.
What unblocks this
Revisit after upgrading to the .NET 10 SR9 servicing release (we are on 10.0.80 today), by which point Chromium 140+ WebViews are widespread. At that point true edge-to-edge should be reachable by flipping SafeAreaEdges to None and letting the env(safe-area-inset-*) variables already present in app.css pad the UI, with no custom platform code.
MAUI issues to subscribe to
- dotnet/maui#34462 — Safe area handling broken on Android in Blazor Hybrid templates (open, .NET 10 SR9) — primary blocker
- dotnet/maui#35568 — Edge-to-edge: Shell/NavigationPage bar colour not used for status bar (closed, SR9)
- dotnet/maui#33344 — Bar background does not extend into the system navigation bar area in edge-to-edge (closed, SR6)
- dotnet/maui#24742 — Android 15 / API 35 apps default to edge-to-edge (closed, SR1)
Notes for whoever picks this up
- Reference implementation lives on the
claude/edge-to-edgebranch (PR Blend the system bars into the theme with native safe areas #107): both the custom insets bridge and the native letterbox with themed page approach. - Bar icon contrast (light/dark icons via
WindowInsetsControllerCompat.AppearanceLight*Bars) works today and is independent of the background problem, so it can ship on its own. - Caveats observed in 10.0.80:
SafeAreaEdges="SoftInput"incorrectly pads the status bar rather than only the keyboard, andSafeAreaEdges="None"disables MAUI's IME inset handling so the keyboard stops resizing the view.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
danielchalmers commentedon Jul 17, 2026
Noted while testing the v12 polish pass on an API 35 emulator: when the system theme changes while the app is running, the navigation bar keeps the previous theme's tone (e.g. stays light after switching to dark) until the app is restarted. Fresh launches pick up the correct color, and the status bar follows the theme correctly at runtime, so it's just the nav bar with no supported recolor path on API 35+ (setNavigationBarColor is a deprecated no-op there). Folding this into the edge-to-edge work here rather than fighting it separately.
[-]Theme the system navigation bar for edge-to-edge (blocked on MAUI Blazor safe-area support)[/-][+]Theme the system navigation bar for edge-to-edge[/+]danielchalmers commentedon Sep 17, 2026
Update after #116: edge-to-edge itself works now. The unblock was never the MAUI CSS fix, it was Android WebView 144+ forwarding the system bar insets to
env(safe-area-inset-*)on its own. WithSafeAreaEdges="None"on the page and theenv()padding already inapp.css, the page draws under both bars on Android 15 with no custom insets plumbing, and the keyboard dodge from #114 keeps working.What is still missing is a supported way to control the bars themselves. MAUI 10 has no public API for status or navigation bar icon appearance, and its own guess (
ConfigureTranslucentSystemBars, internal) reads the theme's colorPrimary luminance once per activity and lands on light icons in both modes for us. Below Android 15 there is also no framework path to tint the opaque bars to the surface color. Making #116 work on 10.0.101 meant writing toWindowInsetsControlleron every resume, disabling the 3-button scrim by hand, and relying on a CommunityToolkit side effect to letterbox older web views. It works, but it is the kind of platform code we decided not to carry in #107..NET 11 covers this properly:
Window.StatusBarTheme(dotnet/maui#34902, merged in dotnet/maui#34903) gives the app the icon appearance knob, and dotnet/maui#36226 moves MAUI ontoWindowCompat.EnableEdgeToEdge, makes the bars transparent below API 35 too, drops the 3-button scrim and re-applies the icon appearance on configuration changes. That removes nearly all of the code in #116 except theSafeAreaEdges="None"flip and the CSS.So this waits on .NET 11. Plan when it ships: bump MAUI, set
SafeAreaEdges="None", keep the CSS from #116, setWindow.StatusBarThemefrom the in-app theme, and keep the WebView version guard that letterboxes anything below 144. The tested branch isclaude/edge-to-edge-maui-5bb030if anything from it is worth lifting.