Skip to content

[css-anchor-position] Fragmentation and bounding boxes #12287

Open
@mstensho

Description

@mstensho

https://drafts.csswg.org/css-anchor-position-1/#anchor-pos says:

If the target anchor element is fragmented, the axis-aligned bounding rectangle of the fragments' border boxes is used instead.

Using the bounding is a straight-forward thing to do and reason about if the anchor-positioned element is on the outside of the fragmentation context. Just use the bounding box of the visual result.

For example:

<!DOCTYPE html>
<style>
  #multicol {
    columns: 3;
    width: 400px;
    column-fill: auto;
    height: 100px;
    background: yellow;
  }
  #cb {
    position: relative;
    display: flow-root;
    height: 200px;
    background: lightgray;
  }
  #anchor {
    anchor-name: --a;
    margin: 20px;
    width: 50px;
    height: 70px;
    background: cyan;
  }
  .anchored {
    box-sizing: border-box;
    position: absolute;
    position-anchor: --a;
    width: 100%;
    height: 100%;
  }
</style>
<div id="multicol">
  <div style="height:50px;"></div>
  <div id="cb">
    <div id="anchor"></div>
  </div>
  <div class="anchored" style="position-area:bottom right; border:solid blue;"></div>
  <div class="anchored" style="position-area:center; border:solid hotpink;"></div>
</div>

Image

So far, so good.

However, if the anchor-positioned element also participates in the fragmentation context, it becomes more interesting. Then its containing block is inside the fragmentation context, which means that it undergoes fragmentation, and the true visual bounding box is only something that can be observed when done with fragmented layout. Furthermore, using the true visual bounding box in such cases would pose the question: In which fragmentainer should the anchor-positioned element start, since we've effectively left fragmented flow to determine the bounding box, and now want to place ourselves back into the fragmentation context artificially?

Let me start with a non-anchor example, with a fragmented out-of-flow element that uses inset properties, just to illustrate how out-of-positioning works on a general basis inside block fragmentation.

<!DOCTYPE html>
<style>
  #multicol {
    columns: 3;
    width: 400px;
    column-fill: auto;
    height: 100px;
    background: yellow;
  }
  #cb {
    position: relative;
    height: 200px;
    background: lightgray;
  }
  .abs {
    position: absolute;
    width: 10px;
    height: 10px;
  }
</style>
<div id="multicol">
  <div style="height:50px;"></div>
  <div id="cb">
    <div class="abs" style="top:0; background:cyan;"></div>
    <div class="abs" style="top:60px; background:black;"></div>
    <div class="abs" style="bottom:0; right:0; background:blue;"></div>
    <div class="abs" style="left:50%; top:50%; height:40%; background:lime;"></div>
  </div>
</div>

Image

The important observation here is that inset and size properties on out-of-flow positioned elements whose containing block participates in block fragmentation will be in the coordinate system of the fragmented flow, so that e.g. bottom:0 will be at the bottom of the last fragment generated by the (lightgray) containing block, and percentage-heights will be resolved against the size of the node (imagining all fragments stitched together, essentially), not the height of the bounding box or anything like that.

I think the same should be true for anchor-positioned elements. Otherwise the containing block of such elements will not play the correct role. Example:

<!DOCTYPE html>
<style>
  #multicol {
    columns: 3;
    width: 400px;
    column-fill: auto;
    height: 100px;
    background: yellow;
  }
  #cb {
    position: relative;
    display: flow-root;
    height: 200px;
    background: lightgray;
  }
  #anchor {
    anchor-name: --a;
    margin: 20px;
    width: 50px;
    height: 70px;
    background: cyan;
  }
  .anchored {
    box-sizing: border-box;
    position: absolute;
    position-anchor: --a;
    width: 100%;
    height: 100%;
  }
</style>
<div id="multicol">
  <div style="height:50px;"></div>
  <div id="cb">
    <div id="anchor"></div>
    <div class="anchored" style="position-area:bottom right; border:solid blue;"></div>
    <div class="anchored" style="position-area:center; border:solid hotpink;"></div>
  </div>
</div>

Should be rendered like this:

Image

Observe how position:area places the element nicely within its (lightgray) containing block, even if the containing block is fragmented.

Not like this (current Chrome):

Image

Thoughts, @tabatkins ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions