Skip to content

[css-align] Clarify how justify-self affects automatic size of block-level box #12102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Loirooriol opened this issue Apr 18, 2025 · 4 comments
Labels

Comments

@Loirooriol
Copy link
Contributor

I'm quite puzzled by other implementers and even spec editors interpreting the spec in ways that seem weird to me, so let's clarify the behavior.

How does justify-self affect the automatic size of a block-level box?

I think https://drafts.csswg.org/css-align/#justify-self-property is clear:

Values other than stretch cause a width/height of auto to be treated as fit-content.

So the automatic size only stretches with justify-self: stretch (or auto/normal that behave as stretch).

As discussed in #11463, this behavior differs from <center> and align="". But it's consistent with flex items, grid items, and abspos, so I think it's the reasonable thing to do.

It's also how it works in Blink and Servo#36595 (AFAIK the only implementations).

However, @fantasai interpreted the spec as only using fit-content in over-constrained cases.

<!DOCTYPE html>
<div style="width: 200px; border: solid magenta">
  <div style="justify-self: right; border: solid">
    <div style="width: 100px; height: 50px"></div>
  </div>
</div>
<div style="width: 200px; border: solid magenta" align="right">
  <div style="border: solid">
    <div style="width: 100px; height: 50px"></div>
  </div>
</div>
Servo#36595, Blink

How do auto margins affect the above?

<!DOCTYPE html>
<div style="width: 200px; border: solid magenta">
  <div id="a" style="justify-self: right; border: solid">
    <div style="width: 100px; height: 50px"></div>
  </div>
  <div id="b" style="justify-self: right; border: solid; margin: auto">
    <div style="width: 100px; height: 50px"></div>
  </div>
</div>

In this example, both #a and #b should be sized as fit-content as per the above. Then, #b has auto margins, so it should appear centered instead of aligned to the right.

However, presumably because of

Note: auto margins, because they effectively adjust the size of the margin area, take precedence over justify-self.

Blink interprets that auto margins completely nullify justify-self: right, and thus #b stretches as for justify-self: normal.

I think that's very unexpected, my interpretation of the note is that margin: auto will center even with justify-self: right, but that it doesn't prevent justify-self: right from affecting the size.

Servo#36595 Blink
@bfgeek
Copy link

bfgeek commented Apr 18, 2025

I'm fine w/ either behaviour.

@fantasai
Copy link
Collaborator

However, @fantasai interpreted the spec as only using fit-content in over-constrained cases.

No that would be super weird!

My interpretation was that the alignment properties don't affect block-level sizing, so alignment only takes effect in over-constrained cases; in other cases the outer size perfectly fits the container, so there is nothing to align. In other words, justify-self replaces direction for determining alignment, but otherwise layout is as per CSS2.1.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-align] Clarify how `justify-self` affects automatic size of block-level box, and agreed to the following:

  • RESOLVED: Values of `justify-self` other than normal or stretch treat the automatic size as fit-content, just like in flex/grid
  • RESOLVED: auto margins do not prevent justify-self from imposing fit-content
The full IRC log of that discussion <emilio> oriol: two implementations of justify-self on block boxes (blink and servo). We interpreted some things that the spec says in different ways
<emilio> ... some things we agree on fantasai disagreed on
<emilio> ... want to clarify this
<emilio> ... two questions:
<emilio> ... first could be the effect of `justify-self` on the auto size of a block level box
<emilio> ... spec says that values other than stretch makes auto size fit-content
<emilio> ... so it applies to grid/flex items and block level items
<emilio> ... both blink and servo did this
<emilio> ... fantasai was interpreting it as this property doesn't affect block level sizing, only in over-constrained cases
<iank_> +1 to Oriol - it makes it more consistent w/ grid/flex
<emilio> ... I kinda prefer the fit-content behavior unconditional
<emilio> ... allows to explain tables
<emilio> ... could be explained as `justify-self: normal` on keywords is `start` rather than `stretch`
<emilio> ... on the other hand means diverging from `<center>` and html `align` attributes since those don't prevent stretching
<emilio> ... I prefer treating block-level boxes as other boxes
<emilio> ... but if fantasai wants to argue for an exception...
<astearns> ack fantasai
<iank_> q+
<emilio> fantasai: this also plays into the related issue about the effect of these properties when anon boxes are present
<emilio> ... anon boxes always stretch
<emilio> ... so there's an issue there where if you take the position that this affects fit-content you get inconsistent behavior if you have anon boxes
<emilio> ... I initially thought that this was fixing the alignment of stuff given how long block layout has existed
<emilio> ... guess we could go either way
<astearns> ack iank_
<emilio> iank_: IMO this makes the feature useful by default
<emilio> ... so kinda prefer how servo and blink interpret it
<emilio> q+
<astearns> ack emilio
<fantasai> emilio: Don't disagree, but was curious about the anonymous box situation
<fantasai> emilio: justify wouldn't apply to the anonymous box, right?
<fantasai> iank_: Concern for top-level anonymous boxes that are generated
<fantasai> iank_: consider our previous behavior a bug, so changed so that anonymous boxes ignore justify and always stretch, but we can talk about that issue separately
<fantasai> emilio: Makes sense to be consistent with block (???) to not introduce other issues
<fantasai> iank_: What do you mean?
<fantasai> emilio: If it doesn't do weird things if you have an anonymous block inside.
<fantasai> emilio: If that's ok, then making it work by default makes sense.
<fantasai> astearns: Do we have consensus? what's the resolution?
<fantasai> oriol: Values other than normal or stretch treat the automatic size as fit-content, just like in flex/grid
<fantasai> astearns: Does everyone agree?
<fantasai> fantasai: I'm ok with it.
<emilio> fantasai: we should ack that this makes justify-self not work for html centering stuff
<TabAtkins> yeah, we've abandoned doing <center> with this now
<emilio> PROPOSED: Values of `justify-self` other than normal or stretch treat the automatic size as fit-content, just like in flex/grid
<emilio> RESOLVED: Values of `justify-self` other than normal or stretch treat the automatic size as fit-content, just like in flex/grid
<emilio> oriol: there's another thing about how auto margins behave with this
<emilio> ... in servo we have different interpretations
<emilio> ... there's an example in the issue. If you set `justify-self: right` then the size will be `fit-content`, however if then you add auto margins, then these prevent `justify-self` from forcing fit-content
<emilio> ... in servo justify-self still prevents the stretching even with auto margins, and I think that makes more sense
<fantasai> +1
<oriol> https://github.com//issues/12102
<emilio> iank_: yeah basically, do auto margins disable justify-self or just the alignment part of it
<fantasai> If stretching is disabled for zero margins, then it should definitely be disabled for auto margins
<emilio> +1
<emilio> fantasai: this goes back to the first issue, where alignment is applied after margins
<fantasai> which are applied after sizing decisions
<emilio> oriol: right in this case the size of the margin box fills the container
<emilio> ... so you don't see the effect but it's not "not working"
<emilio> fantasai: if the box is larger than the container the auto margins will not absorb that space
<emilio> ... not sure we want the alignment to take effect in that case
<emilio> ... if you have auto margins you were expecting a particular alignment
<emilio> ... or do you just start-align it
<emilio> oriol: I think if you have unsafe alignment then why not
<emilio> ... but yeah, not sure
<emilio> iank_: I think auto margins are safe by default, so I think the defaults are actually the same
<emilio> fantasai: right but in this case the margin can't absorb the negative space
<emilio> iank_: but by default it's safe alignment so the default should be fine?
<emilio> fantasai: not sure it falls out of the definitions
<emilio> iank_: to be clear I'm fine changing blink here
<fantasai> I think CSS2.1 is written in a way that this wouldn't fall out.
<emilio> astearns: does the previous resolution apply here?
<emilio> oriol: probably should be a separate one
<emilio> ... the question that fantasai raised could be for a separate issue. We can resolve for the non-overflowing cases
<emilio> PROPOSED: alignment values different than stretch cause sizing to be fit-content, regardless of auto margins
<fantasai> PROPOSED: auto margins do not prevent justify-self from imposing fit-content
<fantasai> RESOLVED: auto margins do not prevent justify-self from imposing fit-content

aarongable pushed a commit to chromium/chromium that referenced this issue May 14, 2025
This patch changes our behaviour to be in line with:
w3c/csswg-drafts#12102 (comment)

This remove the `has_auto_margins` guards when choosing how an
auto inline-size should resolve.

Bug: 417730391
Change-Id: I06e831e3266f3f4a965b715fce12523ead938015
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6547880
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1460370}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue May 14, 2025
This patch changes our behaviour to be in line with:
w3c/csswg-drafts#12102 (comment)

This remove the `has_auto_margins` guards when choosing how an
auto inline-size should resolve.

Bug: 417730391
Change-Id: I06e831e3266f3f4a965b715fce12523ead938015
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6547880
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1460370}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue May 14, 2025
This patch changes our behaviour to be in line with:
w3c/csswg-drafts#12102 (comment)

This remove the `has_auto_margins` guards when choosing how an
auto inline-size should resolve.

Bug: 417730391
Change-Id: I06e831e3266f3f4a965b715fce12523ead938015
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6547880
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1460370}
@Loirooriol
Copy link
Contributor Author

Loirooriol commented May 16, 2025

@astearns I think you re-added Agenda+ by mistake?

Test coverage:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants