@@ -133,10 +133,10 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
133133 * safe-area inset to ensure the popover doesn't overlap with system UI
134134 * (status bars, home indicators, navigation bars on Android API 36+, etc.)
135135 */
136- const safeAreaTop = ' + var(--ion-safe-area-top, 0 )' ;
137- const safeAreaBottom = ' + var(--ion-safe-area-bottom, 0 )' ;
138- const safeAreaLeft = ' + var(--ion-safe-area-left, 0 )' ;
139- const safeAreaRight = ' - var(--ion-safe-area-right, 0 )' ;
136+ const safeAreaTop = ' + var(--ion-safe-area-top, 0px )' ;
137+ const safeAreaBottom = ' + var(--ion-safe-area-bottom, 0px )' ;
138+ const safeAreaLeft = ' + var(--ion-safe-area-left, 0px )' ;
139+ const safeAreaRight = ' - var(--ion-safe-area-right, 0px )' ;
140140
141141 let topValue = `${ top } px` ;
142142 let bottomValue = bottom !== undefined ? `${ bottom } px` : undefined ;
@@ -159,20 +159,27 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
159159 contentEl . style . setProperty ( 'bottom' , `calc(${ bottomValue } )` ) ;
160160 /**
161161 * When both top and bottom are explicitly constrained (isFullyConstrained),
162- * we need to override the height: var(--height) style to allow the
163- * top/bottom constraint to determine the height .
162+ * we need to explicitly calculate the height to ensure the popover
163+ * fits within the safe area boundaries .
164164 *
165- * We only do this when fully constrained because setting height: unset
166- * when only bottom is set (without explicit top) would result in an
167- * incorrectly sized popover .
165+ * Using CSS calc with 100vh minus top and bottom values ensures the
166+ * popover height respects both safe areas. We also override max-height
167+ * to prevent it from interfering with the calculated height .
168168 */
169169 if ( isFullyConstrained ) {
170- contentEl . style . setProperty ( 'height' , 'unset' ) ;
170+ /**
171+ * Wrap topValue and bottomValue in parentheses to ensure correct
172+ * order of operations in the CSS calc. Without parentheses, the
173+ * safe-area additions would have wrong signs.
174+ */
175+ const heightCalc = `calc(100vh - (${ topValue } ) - (${ bottomValue } ) - var(--offset-y, 0px))` ;
176+ contentEl . style . setProperty ( 'height' , heightCalc ) ;
177+ contentEl . style . setProperty ( 'max-height' , heightCalc ) ;
171178 }
172179 }
173180
174- contentEl . style . setProperty ( 'top' , `calc(${ topValue } + var(--offset-y, 0 ))` ) ;
175- contentEl . style . setProperty ( 'left' , `calc(${ leftValue } + var(--offset-x, 0 ))` ) ;
181+ contentEl . style . setProperty ( 'top' , `calc(${ topValue } + var(--offset-y, 0px ))` ) ;
182+ contentEl . style . setProperty ( 'left' , `calc(${ leftValue } + var(--offset-x, 0px ))` ) ;
176183 contentEl . style . setProperty ( 'transform-origin' , `${ originY } ${ originX } ` ) ;
177184
178185 if ( arrowEl !== null ) {
0 commit comments