Use Scrollable Containing Block for any positioned element with a valid default anchor
Categories
(Core :: Layout: Positioned, task)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox147 | --- | fixed |
People
(Reporter: jwatt, Assigned: emilio)
References
(Blocks 1 open bug)
Details
(Whiteboard: [anchorpositioning:2026])
Attachments
(4 files)
https://drafts.csswg.org/css-anchor-position-1/#ref-for-valdef-position-area-none%E2%91%A0 says:
Values other than none have the following additional effects:
- The scrollable containing block is used in place of the local containing block where applicable, so that the entire scrollable overflow area (typically) is available for positioning.
- Any auto inset properties resolve to 0.
- The normal value for the self-alignment properties resolves to a corresponding value, see § 4.1 Area-specific Default Alignment.
We should look into doing the scrollable containing block thing from the first bullet point at some point.
Probably none of the interop tests we're currently aiming to pass are affected. Likely follow-up work post-release.
| Reporter | ||
Comment 1•9 months ago
|
||
Introduced in: https://github.com/w3c/csswg-drafts/issues/10861
Also note: https://github.com/w3c/csswg-drafts/issues/12607
Comment 2•9 months ago
|
||
FWIW, given the attached testcase:
ScrollContainer(div)(0)@7de14a8efba0 parent=7de14a8efa88 (x=0, y=0, w=6000, h=6000) normal-position=(0,0) [content=7de1463044c0][displayport][cs=7de14a82ec08] <
ScrollbarFrame(scrollbar)(-1)@7de14a8efe48 parent=7de14a8efba0 next=7de14a8f00c8 (x=0, y=5280, w=6000, h=720) [content=7de146304670][cs=7de17198b208] <
SliderFrame(slider)(-1)@7de14a8eff50 parent=7de14a8efe48 (x=0, y=0, w=6000, h=720) [content=7de146304820][cs=7de14a8d2308] <
Frame(thumb)(0)@7de14a8f0050 parent=7de14a8eff50 (x=0, y=0, w=6000, h=720) [content=7de146303240][cs=7de14a8d2f08]
>
>
ScrollbarFrame(scrollbar)(-1)@7de14a8f00c8 parent=7de14a8efba0 next=7de14a8f0348 (x=5280, y=0, w=720, h=6000) [content=7de146304700][cs=7de17198a808] <
SliderFrame(slider)(-1)@7de14a8f01d0 parent=7de14a8f00c8 (x=0, y=0, w=720, h=6000) [content=7de1463048b0][cs=7de17198b308] <
Frame(thumb)(0)@7de14a8f02d0 parent=7de14a8f01d0 (x=0, y=0, w=720, h=2520) [content=7de1463032f0][cs=7de14a8d1208]
>
>
Frame(scrollcorner)(-1)@7de14a8f0348 parent=7de14a8efba0 next=7de14a8f03c0 (x=6000, y=6000, w=0, h=0) [content=7de146304790][cs=7de14a82d908]
Block(div)(0)@7de14a8f03c0 parent=7de14a8efba0 (x=0, y=0, w=6000, h=6000) ink-overflow=(x=0, y=0, w=6000, h=12600) scr-overflow=(x=0, y=0, w=6000, h=12600) [content=7de1463044c0][cs=7de14a82d308][:-moz-scrolled-content] <
line@7de14a8f0698 count=1 state=block,clean,prevmarginclean,not-impacted,not-wrapped,no-break,clear-before:none,clear-after:none bm=4500 (x=0, y=7500, w=600, h=600) in-flow-scr-overflow=(x=0, y=0, w=600, h=12600) <
Block(div)(1)@7de14a8f0488 parent=7de14a8f03c0 next=7de14a8f0618 (x=0, y=7500, w=600, h=600) [content=7de146304550][cs=7de14a82e908] <
>
>
line@7de14a8f06e8 count=1 state=inline,clean,prevmarginclean,not-impacted,not-wrapped,no-break,clear-before:none,clear-after:none (x=0, y=12600, w=0, h=0) <
Placeholder(div id=dut)(3)@7de14a8f0618 parent=7de14a8f03c0 (x=0, y=12600, w=0, h=0) [content=7de1463045e0][cs=7de14a82ea08][:-moz-oof-placeholder] outOfFlowFrame=Block(div id=dut)(3)@7de14a8f0550
>
AbsoluteList@7de14dec7260 <
Block(div id=dut)(3)@7de14a8f0550 parent=7de14a8f03c0 (x=600, y=8100, w=600, h=600) [content=7de1463045e0][cs=7de14a82e508] <
>
>
>
>
So the positioned frame parents to the :-moz-scrolled-content.
Updated•9 months ago
|
Updated•8 months ago
|
Comment 3•8 months ago
•
|
||
Yeah - we have a backwards problem.
We always use the scrollable containing block for all anchor resolution and overflow evaluation.
As in comment 0, we should do it only for position-area.
The difference is demonstrated in the attached test case.
There are two anchors: --top and --bottom. The former is visible without scrolling, the latter is not.
The purple positioned element, which uses position-area, uses the scrollable containing block, so it is able to anchor to the --bottom anchor without overflow.
On the other hand, the violet positioned element, which uses anchor() functions, uses the local containing block, and attempting to anchor to the --bottom anchor results in an overflow. So it triggers the use of position-try-fallbacks, anchoring to the --top anchor instead.
A similar effect should apply to position-visibility: no-overflow.
Comment 4•8 months ago
|
||
anchor-center seems to use local containing block as well, but I don't know if that's desirable. Filed https://github.com/w3c/csswg-drafts/issues/12952
Comment 5•8 months ago
|
||
Likely, we need to replace calls like these - instead of just aPositioned->GetParent(), we need to define GetAnchorPositioningContainingBlock() and do something like
const auto* parent = positioned->GetParent();
const bool isScrolledContent = positioned->Style()->GetPseudoType() == PseudoStyleType::scrolledContent;
const bool isPositionAreaInEffect = !positioned->StylePosition()->mPositionArea.IsNone() && /* Default anchor is valid */;
if (parent && isScrolledContent && isPositionAreaInEffect) {
return parent->GetParent();
}
return parent;
Clarifying ticket title & re-queuing for triage.
Comment 6•8 months ago
|
||
... Or, we could take the intersection of scrollport and the current containing block's rect whenever we're checking for overflow.
Updated•8 months ago
|
| Reporter | ||
Updated•8 months ago
|
Updated•8 months ago
|
Comment 8•7 months ago
|
||
(Should be noted that the scrollable containing block vs. local containing block keys into "being able to find a default anchor")
Updated•7 months ago
|
Updated•7 months ago
|
Updated•7 months ago
|
| Assignee | ||
Updated•7 months ago
|
| Assignee | ||
Comment 9•6 months ago
|
||
More of a feedback request.
| Assignee | ||
Updated•6 months ago
|
| Assignee | ||
Updated•6 months ago
|
Comment 10•6 months ago
|
||
Comment 11•6 months ago
|
||
| bugherder | ||
Updated•6 months ago
|
Updated•4 months ago
|
Description
•