Prompt and scope
A help panel or accordion card shows only a heading by default, then grows to a content-defined height. The product wants a smooth transition to auto, max-content, or fit-content while preserving keyboard, screen-reader, and older-browser behavior. Explain how you would use interpolate-size or calc-size() and how you would validate the result.
This fits frontend, design-system, and performance interviews. MDN marks interpolate-size as limited-availability and not Baseline; it requires an explicit opt-in for intrinsic-size interpolation and is not a universally safe animation shortcut.
What the interviewer evaluates
- Whether you understand the boundary between length values and intrinsic-size keywords.
- Whether you know that
interpolate-sizeis inherited and that global opt-in affects descendants. - Whether you distinguish
interpolate-sizefromcalc-size(). - Whether unsupported browsers retain a usable static state and reduced-motion behavior.
- Whether you test content changes, layout shifts, focus order, and performance rather than only visual smoothness.
Clarifications to ask first
Confirm:
- Which target browsers and minimum versions matter, and is progressive enhancement acceptable?
- Is this a semantic disclosure control, and must the content stay present in the document and accessibility tree?
- Are you animating height, width, or both, and can content change asynchronously during the transition?
- Must the component support reduced motion, keyboard interaction, focus return, and reversing mid-animation?
If unspecified, assume modern Chromium, Firefox, and Safari with different support levels; older browsers must remain usable without smooth intrinsic-size animation.
Thirty-second answer framework
I would build a semantic button and content region first, then treat the animation as progressive enhancement. In supported browsers, enable interpolate-size: allow-keywords on the local container and transition from an explicit collapsed length to max-content or auto; evaluate calc-size() only when the intrinsic size needs further calculation. Unsupported browsers use a static expansion, bounded maximum height, or an immediate toggle. Business state cannot depend on animation completion. Finally, test keyboard, screen readers, reduced motion, long content, reversal, and real performance.
Step-by-step deep dive
1. Establish semantic state
Use a button with aria-expanded pointing to the content region, and choose a hiding strategy that matches the product semantics. Animation changes visual and layout transition only; it does not decide whether content is operable. Never strand focus in a collapsed region. If focus remains inside hidden content, return it to the trigger or a clearly visible control.
2. Choose the interpolation mechanism
interpolate-size: allow-keywords enables interpolation between a length or percentage and an intrinsic-size value, but it does not animate between two intrinsic keywords directly. Use calc-size() when the intrinsic size must participate in a calculation; ordinary calc() cannot calculate auto or max-content. Start with a local scope instead of enabling it on the root and surprising unrelated components.
3. Define content and layout boundaries
Give the animated container explicit overflow, maximum-size, and positioning boundaries. Async content changes the target size, so choose whether to wait for stable content, recompute, or jump to the final state. Nested grids, absolute positioning, and scroll containers can make intrinsic size differ from intuition; measure the actual component composition.
4. Compatibility and fallback
Gate the enhancement behind support detection. Older browsers should use a static height, a bounded max-height approximation, or an immediate toggle. The fallback must preserve readable content, usable controls, focusable links, and an understandable closed state. Do not measure layout on every animation frame in JavaScript just to hide missing CSS support; that introduces forced layout and more state paths.
5. Motion preferences and interaction
Under prefers-reduced-motion: reduce, shorten or remove the transition while keeping state and focus logic. Enter, Space, Tab, and Escape behavior should follow the component contract. If the user clicks again mid-transition, reverse naturally or jump to the new target; do not leave concurrent animations fighting over layout and aria-expanded.
6. Validation metrics
Use short and long text, asynchronous errors, and localized wrapping. Measure layout shift, dropped frames, style and layout time, interaction latency, focus visibility, and assistive-technology output. Compare supported and unsupported paths, including the case where the property is ignored. A browser compatibility table is not a product performance guarantee; the benefit must come from measurement.
High-quality sample answer
I would implement a semantic button and content region with aria-expanded as the state source; CSS animation is only an enhancement. On supported browsers, set interpolate-size: allow-keywords on the panel container and transition from an explicit collapsed length to max-content or auto. If a calculation over the intrinsic size is required, use calc-size(). I would avoid a blind root-level opt-in because the property inherits.
When unsupported, the panel still opens immediately or uses a bounded max-height; content and focus do not depend on animation finishing. Reduced motion removes the transition but not the state change. If async content changes during the transition, I would wait for stability, recompute, or jump to the final state according to a documented policy, while updating aria-expanded once.
Validation covers short and long content, localization, keyboard, screen readers, focus return, reversal, older browsers, and reduced motion. For performance, compare style, layout, frame rate, layout shift, and interaction latency. If the enhanced path causes jitter or compatibility failures, narrow its selector or disable it; a CSS experiment must not reduce baseline usability.
Common mistakes
- Treating intrinsic-size keywords as ordinary numeric endpoints that can all interpolate with one another.
- Setting
interpolate-sizeon the root and unintentionally changing unrelated descendants. - Treating
calc-size()as a drop-in replacement forcalc()without explaining its boundary. - Testing only supported browsers and ignoring content or focus when the property is dropped.
- Hiding real height behind a huge
max-height, which distorts animation speed and layout. - Reading layout and writing styles every JavaScript frame, forcing synchronous layout.
- Ignoring reduced motion, keyboard reversal, and asynchronous content changes.
- Showing a smooth demo without measuring CLS, interaction latency, or screen-reader state.
Follow-up questions and responses
Why cannot you transition directly from zero to auto?
Traditional interpolation needs numeric endpoints; auto and max-content are intrinsic sizes. interpolate-size permits selected length-to-intrinsic interpolation, subject to browser support.
When would you use calc-size?
Use it when the target needs a calculation based on intrinsic size, such as adding spacing or applying a limit. If you only need length-to-intrinsic interpolation, local interpolate-size is clearer.
What if content grows during the animation?
Define a policy: wait for stable data, recompute the target, or jump to the final state. Keep scrolling, focus, and aria-expanded consistent, and test rapid repeated interaction.
What do unsupported browsers do?
Keep an immediate or bounded static expansion so content, links, and keyboard paths remain complete. Progressive-enhancement failure should reduce visual polish, not business usability.
How do you verify accessibility?
Use the keyboard to open, close, reopen, and move focus, then check that assistive technology reports the same state and content. Repeat with reduced motion and ensure hidden content never retains unreachable focus.