Open Bug 2010760 Opened 7 months ago Updated 5 days ago

www.matriklen.dk - The red arrow is misaligned on the page

Categories

(Web Compatibility :: Site Reports, defect, P3)

Desktop
Windows 10

Tracking

(Webcompat Priority:P2, Webcompat Score:4, firefox147 affected, firefox148 affected, firefox149 affected)

Webcompat Priority P2
Webcompat Score 4
Tracking Status
firefox147 --- affected
firefox148 --- affected
firefox149 --- affected

People

(Reporter: bfarkas, Unassigned)

References

(Blocks 1 open bug, )

Details

(Keywords: webcompat:needs-diagnosis, webcompat:site-report, Whiteboard: [anchorpositioning:triage],[webcompat-source:web-bugs][autowebcompat:processed][autowebcompat:repro-success])

User Story

user-impact-score:100
platform:windows,mac,linux,android
impact:significant-visual
configuration:general
affects:all
branch:release
diagnosis-team:layout
autowebcompat-repro-status:success
autowebcompat-repro-chrome-mask-fixed:false
autowebcompat-repro-channels:nightly,stable,esr
autowebcompat-repro-report-os:all
autowebcompat-diagnosis-status:success

Attachments

(6 files, 1 obsolete file)

Environment:
Operating system: Windows 10 / Android 11
Firefox version: Firefox Nightly 149.0a1 (2026-01-15)

Steps to reproduce:

  1. Access: https://www.matriklen.dk/#/installer
  2. Select the OS and Browser
  3. Observe the alignment on page

Expected Behavior:
The page is displayed accordingly

Actual Behavior:
The red arrow is misaligned

Notes:

  • Reproduces regardless of the status of ETP
  • Reproduces in firefox-nightly, and firefox-release
  • Does not reproduce in chrome

Created from https://github.com/webcompat/web-bugs/issues/201149

Attached image Red arrow issue mobile
User Story: (updated)
Webcompat Score: --- → 1

This is Anchor Positioning! How exciting!

Severity: -- → S3
User Story: (updated)
Webcompat Priority: --- → P3
Webcompat Score: 1 → 3
Priority: -- → P3

Ouch.
Basically, the <output> element acts as the absolute containing block - but also, it's display: inline. Inside it is the <div class=browser-sketch>, which is a block element, and contains the anchor.
Because this is a block-inside-inline scenario, we create an IB split of <output> into 3 frames, inline-block-inline. Absolute containing block goes to the first inline frame, anchor and positioned elements are in the block frame. So we effectively end up putting the anchor after the positioned element, which causes us to not be a valid anchor.

Also notably, this creates a warning: WARNING: Out-of-flow frame got reflowed before its placeholder: file /home/dshin/firefox/layout/generic/nsPlaceholderFrame.cpp:131.

Workaround could be wrapping <output> in div and making that a relpos element, or adding display: inline-block.

Attached file Demonstrative case

(In reply to David Shin[:dshin] from comment #4)

Also notably, this creates a warning: WARNING: Out-of-flow frame got reflowed before its placeholder: file /home/dshin/firefox/layout/generic/nsPlaceholderFrame.cpp:131.

We end up laying out the positioned element before anchor, so even if we properly traversed containing blocks accounting for IB split continuations, we will not be able to layout w.r.t. the anchor element, which isn't laid out yet.

Whiteboard: [webcompat-source:web-bugs] → [anchorpositioning:triage],[webcompat-source:web-bugs]
User Story: (updated)
Webcompat Score: 3 → 5
See Also: → 878538
Webcompat Priority: P3 → P2
User Story: (updated)
User Story: (updated)
Webcompat Score: 5 → 4
See Also: → 2063785
Attachment #9538580 - Attachment is obsolete: true

I filed bug 2066154 on platform side (containing block is IB-split); removed bug 2063785 as a dependency because it is about anchor being IB-split.

User Story: (updated)
No longer depends on: 2063785
Whiteboard: [anchorpositioning:triage],[webcompat-source:web-bugs] → [anchorpositioning:triage],[webcompat-source:web-bugs][autowebcompat:processed]
User Story: (updated)
Whiteboard: [anchorpositioning:triage],[webcompat-source:web-bugs][autowebcompat:processed] → [anchorpositioning:triage],[webcompat-source:web-bugs][autowebcompat:processed][autowebcompat:repro-success][autowebcompat:diagnose]

On the matriklen.dk installation guide, the red arrow that should point at the install icon in the illustrated address bar is not rendered anywhere in Firefox. The arrow is an anchor-positioned SVG (position-anchor: --chrome-icon) inside a position:relative, display:inline <output>; Firefox paints nothing at the anchor, and after scrolling its box also drifts away from the anchor by the scroll offset. Chrome draws the arrow correctly beside the icon.

Whiteboard: [anchorpositioning:triage],[webcompat-source:web-bugs][autowebcompat:processed][autowebcompat:repro-success][autowebcompat:diagnose] → [anchorpositioning:triage],[webcompat-source:web-bugs][autowebcompat:processed][autowebcompat:repro-success][autowebcompat:diagnosis-in-progress]

Root cause analysis generated by autowebcompat bot:

Gecko bug in CSS anchor positioning: an absolutely-positioned element that has a valid anchor reference and whose containing block is established by an inline box that contains block-level children (Gecko's "ib-split" / block-in-inline frame split) is laid out at the correct anchor-relative position but is never painted and never hit-tested.

matriklen.dk builds the installation sketch like this (InstallView-DLqI8Oh7.css):
.browser-sketch > .chrome .icon { anchor-name: --chrome-icon }
.pointer { position: absolute; align-self: anchor-center; height: 1em; margin: .2em }
.chrome-pointer { position-anchor: --chrome-icon; left: anchor(right) }
The red arrow <svg class="pointer chrome-pointer"> and the anchor <svg class="icon"> both live inside a position: relative; display: inline <output> element whose children are <div>s — i.e. exactly the ib-split situation. Chrome paints the arrow next to the install icon; Firefox 157 gives the arrow a correct layout box (getBoundingClientRect() == anchor position) but paints nothing and document.elementsFromPoint() at that box does not return it, so the "click the install icon" instruction loses its pointer.

Both ingredients are required:

  • a valid anchor (removing position-anchor, or pointing it at a name that does not resolve, makes the same box paint fine in Firefox), and
  • an inline containing block that is split by block-level content (making the containing block display: block, or giving the inline only inline content, makes it paint in Firefox).

Relevant spec text: CSS Anchor Positioning §3 (position-anchor / anchor() only affect the used inset values — https://drafts.csswg.org/css-anchor-position-1/#anchor-pos) and CSS 2.1 §10.1 item 4 / CSS Display §2.1, which say an abspos box whose containing block is established by an inline box is positioned inside the box formed by that inline's fragments and is otherwise painted like any other abspos box (https://www.w3.org/TR/CSS22/visudet.html#containing-block-details, https://drafts.csswg.org/css-position-3/#painting). Nothing in those specs makes an anchored box unpaintable, so Firefox is wrong here. This is an engine difference, not UA sniffing (the site only uses the radio selection, and the same markup/CSS is served to both browsers).

Evidence:

Firefox 157.0 (rv:157.0) vs HeadlessChrome 152, 1280x1500 viewport, site with "Computer"+"Firefox" selected.

Live site:

  • Same DOM/CSS in both browsers (no UA branch): the arrow element exists in both, computed position:absolute; position-anchor:--chrome-icon; left:anchor(right) in both. Firefox even resolves the anchor correctly: icon rect right=580.9, arrow rect x=583.9 (Chrome: 585.3 / 588.3) — the box is in the right place.
  • Firefox: document.elementsFromPoint(iconRight+22, iconMidY) returns [OUTPUT, FORM, DIV.main, …] — the arrow is absent; Chrome returns [rect, polygon, svg.pointer, OUTPUT, …]. Full-page screenshots: Chrome shows the red arrow next to the install icon, Firefox shows no red pixels anywhere on the page.
  • Causal check on the live page: setting the containing <output>'s display to block (nothing else changed) makes the arrow hit-testable in Firefox (hit:falsehit:true at the same coordinates, arrow rect unchanged at [584,765]).
  • Injecting a fresh position:absolute div into the same <output>: with position-anchor:--chrome-icon; left:anchor(right) it is not hit-testable in Firefox; the identical div with plain left/top px is hit-testable. So the anchor reference is the trigger, not abspos-in-inline as such.
  • No console errors or failed requests in either browser.

Reduced testcase /app/diagnosis/testcase=xbnoynpb.html (row A = inline containing block with block children, row B = same but display:block):

  • Chrome: both rows paint the red bar; in-page check prints "row A … PASS / row B … PASS".
  • Firefox: only row B paints (screenshot); in-page check prints "row A: arrow box is 0px right of the icon, hit-testable at its own box: false => FAIL (Firefox bug) / row B: … true => PASS". Row A's getBoundingClientRect() is still correct, confirming it is a paint/hit-test failure, not a layout failure.
  • Extra variants confirmed in Firefox: inline containing block with only inline content + anchor() → paints; anchor name that does not resolve → paints; so both ingredients are needed.

Side note (not the reported bug, but hit repeatedly): setting position-visibility: always on such an anchored element hung the Firefox content process for me (page navigation/eval stopped responding, ~20% CPU spin) — reproduced twice, once on the live site and once in a local test file.

I could not reproduce the "box drifts by the scroll offset" part of the report: at scrollY=300 the arrow's offset from the icon stayed 3px in Firefox.

User Story: (updated)
Whiteboard: [anchorpositioning:triage],[webcompat-source:web-bugs][autowebcompat:processed][autowebcompat:repro-success][autowebcompat:diagnosis-in-progress] → [anchorpositioning:triage],[webcompat-source:web-bugs][autowebcompat:processed][autowebcompat:repro-success]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: