Skip to content

bug: applyFullscreenSafeArea() shrinks fullscreen modal wrapper when ion-content exists without ion-footer (8.8.1 regression) #31015

@a-hazaiti

Description

@a-hazaiti

Prerequisites

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

  1. Create an Ionic Angular app with @ionic/angular 8.8.1
  2. 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 -->
  1. Present it as a fullscreen modal:
const modal = await this.modalCtrl.create({
  component: MyModalComponent,
  cssClass: 'fullscreen'
});
await modal.present();
  1. Run on an iOS device/simulator with a home indicator (iPhone X or later)
  2. 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-content already applies --ion-safe-area-bottom to 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 when ion-content has fullscreen="false", rather than when ion-footer is absent.
  • Alternatively, check whether the modal's --height is 100% (fullscreen) before reducing it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions