Skip to content

[css-align-3][css-position-3] How should safe alignment work for OOF elements when positioned statically? #11934

Open

Description

@alisonmaher

According to css-align, when the overflow alignment mode is safe, "If the size of the alignment subject overflows the alignment container, the alignment subject is instead aligned as if the alignment mode were start."

According to css-position, OOFs are "resolved into a static position by aligning the box into its static-position rectangle, an alignment container derived from the formatting context the box would have participated in if it were position: static (independent of its actual containing block)."

Based on these two statements, this would imply that if an OOF is statically positioned, and is aligned with the safe keyword, we'd position it at the start of the alignment container (i.e. the originating parent container) if the OOF overflows that alignment container.

However, css-align also notes that for abspos elements, the overflow alignment behavior is based on "the default overflow rect" which is "the bounding rectangle of the alignment subject’s inset-modified containing block and its original containing block."

It is not clear to me if this also applies to statically positioned OOFs or not, but if it does, then this would imply that for statically positioned OOFs, we'd look at the default overflow rect when determining safe overflow.

Ignoring this, there is also another issue in assuming that the originating alignment container is used for safe in the case of OOF alignment and overflow, specifically in relation to the OOF available space.

According to css-position, an OOFs "inset-modified containing block is calculated, defining its available space."

If it is true that when an OOF is statically positioned, and is aligned with the safe keyword, we'd position it at the start of the alignment container (i.e. the originating parent container) if the OOF overflows that alignment container, then this would mean that when the item hits the overflow condition, its IMCB (and its available space) would change to match the definition for 'self-start'.

The problem with this is that it would shift the available space midway through, causing a shift in the layout of the item, which breaks the continuity principle. Is this what we want?

An alternative approach is: if an OOF is statically positioned, and is aligned with the safe keyword, we'd position it at the start of the IMCB if the OOF overflows the IMCB. This would prevent the shift in available space, and would likely still be a reasonable result for authors. It would however mean that it wouldn't match the result of an OOF that was start-aligned, but perhaps that is ok?

CC @bfgeek @tabatkins @fantasai

Activity

  1. yisibl commented on Dec 17, 2025

    @yisibl
    Contributor

    I've noticed that if the parent element doesn't have position: relative set, Blink behaves differently from other browsers. Is this expected?

    Image
    data:text/html;charset=UTF-8,<!DOCTYPE html>
    <style>
      .box {
        font: 16px sans-serif;
        border: 1px solid red;
        margin: 100px;
        width: 300px;
        display: flex;
        /*position: relative;*/
    }
      .test {
        background-color: lightblue;
        position: absolute;
        height: 50px;
        border: 1px solid;
        white-space: nowrap;
        width: 200px;
      }
    </style>
    <div class="box">
      <div class="test" style="align-self: safe center;">align-self: safe center</div>
    </div>
    
    <div class="box">
      <div class="test" style="align-self: unsafe center;">align-self: unsafe center</div>
    </div>
  2. alisonmaher commented on Jan 5, 2026

    @alisonmaher
    CollaboratorAuthor

    @yisibl yeah, I believe this is tied to this issue specifically, and we are both taking different approaches. In blink we are taking the IMCB approach mentioned at the end. It looks like maybe Firefox is using the "static position rectangle". And because removing position: relative changes the IMCB, but not the "static position rectangle", that is why we see this difference in Chromium, which may be a slightly weird side effect of that approach, but it does avoid potential layout shifts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions