Representative interview topic

Frontend interview: How would you use CSS Anchor Positioning for an overflow-safe popover?

FrontendMedium
Offer.cc Editorial TeamPublished Updated

Question

Implement a popover attached to a button. It must flip near viewport edges, stay associated while scrolling, and degrade cleanly when CSS Anchor Positioning is unavailable.

Prompt and scope

A button opens a menu, hint, or command panel. The popover should stay near the button, flip when space is unavailable, avoid clipping by the viewport or a scroll container, and support keyboard focus and dismissal. Compare JavaScript coordinate calculations with CSS Anchor Positioning and propose progressive enhancement.

MDN describes anchor positioning as placing one element relative to another with fallback mechanisms such as position-try. Chrome's guide shows the relationship through anchor-name and position-anchor. A strong answer covers layout, scrolling, browser support, and interaction semantics together.

What the interviewer evaluates

  • Whether you separate visual placement, DOM semantics, and focus management.
  • Whether you understand anchor relationships and fallback candidates rather than memorizing property names.
  • Whether you reason about scroll containers, clipping, and stacking contexts.
  • Whether you design a minimal JavaScript fallback when the CSS feature is unavailable.
  • Whether you define a browser, input, and accessibility test matrix.

Frontend interviews commonly test browser layout fundamentals, maintainable components, and edge handling. A strong answer puts a new CSS feature inside real compatibility and product constraints instead of assuming universal support.

Clarifying questions before answering

  • Is the popover a menu, tooltip, or dialog? The semantic role changes focus and Escape behavior.
  • Is the reference a button, icon, or list item? Can it move or be virtualized?
  • May it escape a scroll container? Does it need a top-level rendering layer to avoid clipping?
  • Which browsers and WebViews are supported? Must the fallback preserve all behavior?
  • Must movement animate, and what happens when the user prefers reduced motion?

30-second answer framework

I would first define the popover semantics and focus model. Then I would name the button as an anchor and associate the popover with it. I would place it below by default and provide ordered position-try fallbacks above and to the sides; I would not rely on one fixed offset. Unsupported browsers would use a small positioning adapter or an inline fallback, validated by the same accessibility tests.

Step-by-step deep answer

Step 1: Handle semantics and focus first

A menu needs focusable menu items and an explicit expanded state; a tooltip must not carry required actions; a complex command panel may be dialog-like. On open, record the trigger; on close, restore focus. Escape and outside-click rules must agree. CSS controls placement, not these interaction guarantees.

Step 2: Establish the anchor relationship

Name the trigger as an anchor and point the popover at that position anchor. Keep the relationship stable or instance-scoped so multiple list items do not share one name. Component destruction, reuse, and virtual scrolling must clear stale associations.

Step 3: Define default and fallback positions

Declare the common below-trigger position, then list above, start-side, and end-side candidates. Candidate order expresses product preference, such as preserving horizontal alignment before shrinking content. Use the position-try mechanism to let the browser choose a viable candidate and expose failed candidates for debugging.

Step 4: Handle boundaries and scrolling

Check clipping by scroll containers, transformed ancestors, and new stacking contexts. If the popover must cross a container boundary, render it in a top-level layer while retaining an instance-level anchor relationship. Test scrolling and zooming when the trigger leaves the viewport, nested containers, and right-to-left text.

Step 5: Keep progressive enhancement

Use CSS placement after capability detection; activate a JavaScript adapter only when needed. The adapter reads the trigger rectangle, evaluates candidates, and observes only necessary scroll, size, and layout signals. Do not let both implementations write position styles at once, or they can race and flicker.

Step 6: Constrain size and content

Define maximum width and height, padding, and an internal scroll area. Candidate selection should consider available space and minimum readable size; long content should scroll inside the popover rather than overflow the page. Re-evaluate after dynamic content loads because the initial measurement may be stale.

Step 7: Handle motion and input devices

Give position changes an explicit duration and a reduced-motion path. Keyboard, touch, and pointer input should share open, close, and focus rules; a hover tooltip cannot replace keyboard-accessible help. Animation must not delay focus restoration or expose the wrong state to assistive technology.

Step 8: Build a verification matrix

Test the default position, each fallback, narrow viewports, nested scrolling, zoom, right-to-left text, long content, dynamic content, and unsupported browsers. Assert no clipping, correct trigger-content relation, Escape dismissal, focus restoration, and consistent accessibility-tree state. Compare CSS and fallback paths instead of accepting a wide-screen screenshot.

Model answer

I would distinguish menu, tooltip, and dialog semantics and establish focus and dismissal behavior first. The trigger gets an anchor name; the popover uses position-anchor, defaults below, and lists position-try fallbacks above and to the sides. If a scroll container clips it, I would render it in a top-level layer while retaining an instance relationship. Unsupported browsers use one JavaScript adapter with the same semantics. I would test narrow viewports, nested scroll, right-to-left text, dynamic content, keyboard, and screen readers, while honoring reduced motion.

Common mistakes

  • Compute coordinates only once → scrolling and zoom break placement → make CSS or the adapter react to layout changes.
  • Treat a tooltip as a menu → keyboard and assistive technology fail → define semantics and focus first.
  • Provide only a below position → viewport edges overflow → order several candidates.
  • Ignore overflow: hidden → an ancestor clips the popover → choose the right top-level rendering boundary.
  • Let CSS and JavaScript both position → races and flicker → enable exactly one path after capability detection.
  • Test only wide screens with a mouse → mobile and keyboard fail → cover input devices, directionality, and accessibility.

Follow-ups and responses

Can Anchor Positioning replace every floating-element library?

No. It handles layout relationships and fallback placement, not focus, roles, dismissal, dragging, or complex business collision rules. Components still need interaction and compatibility layers.

What if a scroll container clips the popover?

Decide whether crossing the boundary is required. If it is, use a top-level rendering layer with an instance relationship; otherwise constrain candidates and scroll content inside the container.

How do you avoid anchor-name collisions in a list?

Generate a stable per-instance relationship or manage names with the component lifecycle. Clear associations when virtualized nodes are recycled.

What is the fallback when CSS is unsupported?

Use capability detection to enable one JavaScript positioning adapter with identical semantics, focus, and dismissal. For non-critical content, an inline block below the trigger can be an even simpler fallback.

What if dynamic content changes the position?

Let size changes trigger layout again; on the fallback path observe only necessary size and scroll signals. Do not hide an unstable layout behind a fixed timeout.

How do you prove fallback candidates work?

Create reproducible viewports and scroll states at each edge, then assert final placement, clipping, readable size, and anchor distance rather than checking a CSS class name.

When would you still choose a JavaScript floating library?

Choose one when broad browser support, advanced collision rules, cross-document placement, or mature accessibility behavior outweighs the value of a native CSS path. CSS can remain the progressive layout layer.

Public sources

Related questions