@@ -186,6 +186,18 @@ function staticLocationStrategy (data: LocationStrategyData, props: StrategyProp
186186 return { updateLocation }
187187}
188188
189+ /** Resolve a CSS length the browser understands (calc(), min(), vw, …) to pixels */
190+ function resolveCssLength ( value : string , container : HTMLElement , isWidth : boolean ) {
191+ const probe = document . createElement ( 'div' )
192+ probe . style . position = 'absolute'
193+ probe . style . visibility = 'hidden'
194+ probe . style [ isWidth ? 'width' : 'height' ] = value
195+ container . appendChild ( probe )
196+ const size = isWidth ? probe . offsetWidth : probe . offsetHeight
197+ container . removeChild ( probe )
198+ return size > 0 ? size : Infinity
199+ }
200+
189201/** Get size of element ignoring max-width/max-height */
190202function getIntrinsicSize ( el : HTMLElement , isRtl : boolean ) {
191203 // const scrollables = new Map<Element, [number, number]>()
@@ -257,14 +269,20 @@ function connectedLocationStrategy (data: LocationStrategyData, props: StrategyP
257269 const isWidth = key . endsWith ( 'Width' )
258270 return ( ) => {
259271 const raw = props [ key ]
260- const val = parseFloat ( raw ! )
261- if ( isNaN ( val ) ) return Infinity
262- if ( typeof raw === 'string' && raw . endsWith ( '%' ) ) {
272+ if ( raw == null ) return Infinity
273+
274+ const container = ( data . contentEl . value ?. parentElement ?? document . documentElement ) as HTMLElement
275+
276+ if ( typeof raw === 'number' || / ^ - ? [ \d . ] + (?: p x ) ? $ / . test ( raw . trim ( ) ) ) {
277+ return parseFloat ( raw as string )
278+ }
279+ if ( raw . endsWith ( '%' ) ) {
263280 // resolve against the overlay container, like CSS would
264- const box = getElementBox ( data . contentEl . value ?. parentElement ?? document . documentElement )
265- return val * ( isWidth ? box . width : box . height ) / 100
281+ const box = getElementBox ( container )
282+ return parseFloat ( raw ) * ( isWidth ? box . width : box . height ) / 100
266283 }
267- return val
284+ // let the browser resolve viewport units, calc(), min(), max(), clamp(), etc.
285+ return resolveCssLength ( raw , container , isWidth )
268286 }
269287 } )
270288
0 commit comments