@@ -875,8 +875,10 @@ export class Modal implements ComponentInterface, OverlayInterface {
875875 */
876876 private setInitialSafeAreaOverrides ( presentingElement : HTMLElement | undefined ) {
877877 const style = this . el . style ;
878+ const mode = getIonMode ( this ) ;
878879 const isSheetModal = this . breakpoints !== undefined && this . initialBreakpoint !== undefined ;
879- const isCardModal = presentingElement !== undefined ;
880+ // Card modals only exist in iOS mode - in MD mode, presentingElement is ignored
881+ const isCardModal = presentingElement !== undefined && mode === 'ios' ;
880882 const isTablet = window . innerWidth >= 768 ;
881883
882884 // Sheet modals always touch bottom edge, never top/left/right
@@ -949,9 +951,23 @@ export class Modal implements ComponentInterface, OverlayInterface {
949951 style . setProperty ( '--ion-safe-area-right' , '0px' ) ;
950952 }
951953
954+ /**
955+ * Gets the root safe-area values from the document element.
956+ * These represent the actual device safe areas before any overlay overrides.
957+ */
958+ private getRootSafeAreaValues ( ) : { top : number ; bottom : number ; left : number ; right : number } {
959+ const rootStyle = getComputedStyle ( document . documentElement ) ;
960+ return {
961+ top : parseFloat ( rootStyle . getPropertyValue ( '--ion-safe-area-top' ) ) || 0 ,
962+ bottom : parseFloat ( rootStyle . getPropertyValue ( '--ion-safe-area-bottom' ) ) || 0 ,
963+ left : parseFloat ( rootStyle . getPropertyValue ( '--ion-safe-area-left' ) ) || 0 ,
964+ right : parseFloat ( rootStyle . getPropertyValue ( '--ion-safe-area-right' ) ) || 0 ,
965+ } ;
966+ }
967+
952968 /**
953969 * Updates safe-area CSS variable overrides based on whether the modal
954- * is touching each edge of the viewport . Called after animation
970+ * extends into each safe-area region . Called after animation
955971 * and during gestures to handle dynamic position changes.
956972 */
957973 private updateSafeAreaOverrides ( ) {
@@ -965,20 +981,22 @@ export class Modal implements ComponentInterface, OverlayInterface {
965981 }
966982
967983 const rect = wrapper . getBoundingClientRect ( ) ;
968- const threshold = 2 ;
984+ const safeAreas = this . getRootSafeAreaValues ( ) ;
969985
970- const touchingTop = rect . top <= threshold ;
971- const touchingBottom = rect . bottom >= window . innerHeight - threshold ;
972- const touchingLeft = rect . left <= threshold ;
973- const touchingRight = rect . right >= window . innerWidth - threshold ;
986+ const extendsIntoTop = rect . top < safeAreas . top ;
987+ const extendsIntoBottom = rect . bottom > window . innerHeight - safeAreas . bottom ;
988+ const extendsIntoLeft = rect . left < safeAreas . left ;
989+ const extendsIntoRight = rect . right > window . innerWidth - safeAreas . right ;
974990
975991 const style = this . el . style ;
976- touchingTop ? style . removeProperty ( '--ion-safe-area-top' ) : style . setProperty ( '--ion-safe-area-top' , '0px' ) ;
977- touchingBottom
992+ extendsIntoTop ? style . removeProperty ( '--ion-safe-area-top' ) : style . setProperty ( '--ion-safe-area-top' , '0px' ) ;
993+ extendsIntoBottom
978994 ? style . removeProperty ( '--ion-safe-area-bottom' )
979995 : style . setProperty ( '--ion-safe-area-bottom' , '0px' ) ;
980- touchingLeft ? style . removeProperty ( '--ion-safe-area-left' ) : style . setProperty ( '--ion-safe-area-left' , '0px' ) ;
981- touchingRight ? style . removeProperty ( '--ion-safe-area-right' ) : style . setProperty ( '--ion-safe-area-right' , '0px' ) ;
996+ extendsIntoLeft ? style . removeProperty ( '--ion-safe-area-left' ) : style . setProperty ( '--ion-safe-area-left' , '0px' ) ;
997+ extendsIntoRight
998+ ? style . removeProperty ( '--ion-safe-area-right' )
999+ : style . setProperty ( '--ion-safe-area-right' , '0px' ) ;
9821000 }
9831001
9841002 private sheetOnDismiss ( ) {
0 commit comments