Prerequisites
- I have read the Contributing Guidelines.
- I agree to follow the Code of Conduct.
- I have searched for existing issues that already report this problem, without success.
Ionic Framework Version
v8.x (8.8.1)
Current Behavior
After upgrading from @ionic/angular 8.7.17 to 8.8.1, fullscreen modals (presented via ModalController with cssClass: "fullscreen") that contain ion-content but no ion-footer display a white gap at the bottom on iOS devices with a home indicator (safe area).
This is caused by the new applyFullscreenSafeArea() method in modal.tsx (introduced in PR #30949, included in 8.8.1). The method contains this logic:
let hasContent = false; let hasFooter = false; for (const child of Array.from(el.children)) { if (child.tagName === 'ION-CONTENT') hasContent = true; if (child.tagName === 'ION-FOOTER') hasFooter = true; for (const grandchild of Array.from(child.children)) { if (grandchild.tagName === 'ION-CONTENT') hasContent = true; if (grandchild.tagName === 'ION-FOOTER') hasFooter = true; } } if (!hasContent || hasFooter) return; wrapperEl.style.setProperty('height', 'calc(var(--height) - var(--ion-safe-area-bottom, 0px))'); wrapperEl.style.setProperty('padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
When ion-content is present without ion-footer, the wrapper height is reduced by --ion-safe-area-bottom and equivalent padding is added. This creates a visible white gap at the bottom of the modal because the flex content area shrinks but the modal's visual boundary doesn't move.
This is a regression — the same templates worked correctly on 8.7.17.
Expected Behavior
Fullscreen modals with ion-content and no ion-footer should render identically to how they did in 8.7.x — filling the entire screen without a gap at the bottom. The content inside ion-content already handles its own safe-area padding via --ion-safe-area-bottom on the scroll container. Applying it a second time at the wrapper level causes double safe-area compensation.
Steps to Reproduce
- Create an Ionic Angular app with
@ionic/angular8.8.1 - Create a modal component with this template:
<ion-header> <ion-toolbar> <ion-title>Modal Title</ion-title> </ion-toolbar> </ion-header> <ion-content> <p>Some content here</p> </ion-content> <!-- No ion-footer -->
- Present it as a fullscreen modal:
const modal = await this.modalCtrl.create({ component: MyModalComponent, cssClass: 'fullscreen' }); await modal.present();
- Run on an iOS device/simulator with a home indicator (iPhone X or later)
- Observe a white gap at the bottom of the modal
Code Reproduction URL
Reproduction project can be provided upon request.
Ionic Info
Ionic:
Ionic CLI : 7.2.1
Ionic Framework : @ionic/angular 8.8.1
@angular/cli : 21.3.1
@ionic/angular-toolkit : 12.3.0
Capacitor:
Capacitor CLI : 8.1.0
@capacitor/android : 8.1.0
@capacitor/core : 8.1.0
@capacitor/ios : 8.1.0
System:
NodeJS : v22.17.0
npm : 10.9.2
OS : macOS
Additional Information
Root cause: PR #30949 (resolving #28411 and #30900) added applyFullscreenSafeArea() to handle safe-area insets dynamically for modals. The heuristic if (!hasContent || hasFooter) return; assumes that any modal with ion-content and no ion-footer needs wrapper-level safe-area compensation. However, ion-content already handles bottom safe-area internally via its scroll container, so this creates a double safe-area effect.
Affected templates: Any modal that uses ion-content without ion-footer — a very common pattern for settings modals, info modals, selection modals, etc.
Current workaround: Add an empty <ion-footer></ion-footer> after </ion-content> in the modal template. This triggers the hasFooter early-exit path, preventing the wrapper height reduction:
<ion-content> <!-- modal content --> </ion-content> <!-- Workaround: empty ion-footer prevents applyFullscreenSafeArea() regression --> <ion-footer></ion-footer>
Suggested fix considerations:
ion-contentalready applies--ion-safe-area-bottomto its scroll padding. The wrapper-level adjustment creates double compensation.- Consider only applying the wrapper adjustment when the modal does NOT contain
ion-content(raw HTML modals), or whenion-contenthasfullscreen="false", rather than whenion-footeris absent. - Alternatively, check whether the modal's
--heightis100%(fullscreen) before reducing it.