npx claudepluginhub davidortinau/maui-skills --plugin maui-skillsThis skill uses the workspace's default tool permissions.
`ContentPage` now defaults to edge-to-edge (`None`) on **all platforms**. In .NET 9,
Guides .NET MAUI safe area and edge-to-edge layouts for .NET 10+ using SafeAreaEdges, SafeAreaRegions, keyboard avoidance on Android, iOS, Mac Catalyst, with Blazor Hybrid support and legacy migrations.
Guards .NET MAUI projects against deprecated, obsolete, or removed APIs in XAML/C#, Blazor Hybrid, and MauiReactor. Detects target frameworks/library versions and provides replacement patterns for code generation/review/editing.
Guides safe area handling in Capacitor apps for iPhone notch, Dynamic Island, home indicator, and Android cutouts using CSS, JavaScript, and native solutions. Fixes layout issues on modern devices.
Share bugs, ideas, or general feedback.
NoneContentPage now defaults to edge-to-edge (None) on all platforms. In .NET 9,
Android ContentPage behaved like Container. If your Android content goes under
the status bar after upgrading, add SafeAreaEdges="Container" explicitly.
<!-- ❌ .NET 10 default — content goes under status bar on Android -->
<ContentPage>
<!-- ✅ Restore .NET 9 Android behavior -->
<ContentPage SafeAreaEdges="Container">
If you used WindowSoftInputModeAdjust.Resize in .NET 9, you may need
SafeAreaEdges="All" on the ContentPage to maintain keyboard avoidance.
Container, not NoneFor true edge-to-edge, set SafeAreaEdges="None" on both the page and layouts:
<!-- ❌ Grid still respects system bars (its default is Container) -->
<ContentPage SafeAreaEdges="None">
<Grid>
<Image Source="bg.jpg" Aspect="AspectFill" />
</Grid>
</ContentPage>
<!-- ✅ Both page and layout set to None -->
<ContentPage SafeAreaEdges="None">
<Grid SafeAreaEdges="None">
<Image Source="bg.jpg" Aspect="AspectFill" />
</Grid>
</ContentPage>
SoftInput on ScrollView has no effectScrollView manages its own content insets. Wrap it in a Grid/StackLayout instead:
<!-- ❌ SoftInput is ignored on ScrollView -->
<ScrollView SafeAreaEdges="SoftInput">
<!-- ✅ Set SoftInput on the wrapper layout -->
<Grid SafeAreaEdges="Container, Container, Container, SoftInput">
<ScrollView> ... </ScrollView>
</Grid>
Default is not NoneDefault = "use platform defaults for this control type." None = "edge-to-edge."
They differ significantly on ScrollView (iOS maps Default to automatic content insets).
<!-- ❌ XAML safe area + CSS env() = double padding -->
<ContentPage SafeAreaEdges="Container">
<BlazorWebView ... /> <!-- CSS also uses env(safe-area-inset-*) -->
<!-- ✅ Pick ONE approach — CSS is recommended for Blazor -->
<ContentPage SafeAreaEdges="None">
<BlazorWebView ... /> <!-- CSS handles all insets with env() -->
Content won't extend behind the nav bar unless you set a transparent background AND hide the separator:
<Shell Shell.BackgroundColor="#80000000"
Shell.NavBarHasShadow="False" />
| Scenario | SafeAreaEdges value |
|---|---|
| Forms, critical inputs | All |
| Photo viewer, video player, game | None (on page AND layout) |
| Scrollable content with fixed header/footer | Container |
| Chat/messaging with bottom input bar | Per-edge: Container, Container, Container, SoftInput |
| Blazor Hybrid app | None on page, CSS env() for insets |
| Legacy (.NET 9) | New (.NET 10+) |
|---|---|
ios:Page.UseSafeArea="True" | SafeAreaEdges="Container" |
IgnoreSafeArea="True" | SafeAreaEdges="None" |
WindowSoftInputModeAdjust.Resize | SafeAreaEdges="All" on ContentPage |
Legacy properties still work but are obsolete.
Combine SafeAreaEdges with Padding — safe area handles insets, Padding adds visual spacing:
<ContentPage SafeAreaEdges="All">
<VerticalStackLayout Padding="20">
<!-- Both applied — no conflict -->
</VerticalStackLayout>
</ContentPage>
Use per-control settings for mixed layouts (edge-to-edge header + safe body + keyboard-aware footer).
For Blazor Hybrid, prefer CSS env() and leave SafeAreaEdges="None".
Add viewport-fit=cover to the <meta viewport> tag.
Test on notched devices (iPhone X+, Android cutouts), tablets in landscape, and varying screen sizes.
SafeAreaEdges="Container" added if content goes under status barNone set on both page and layoutSafeAreaEdgesviewport-fit=cover in Blazor's index.html <meta viewport> tagUseSafeArea / IgnoreSafeArea migrated to SafeAreaEdges