w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.48k stars 659 forks source link

[css-align] *-items properties might need to resolve directions early #7612

Open tabatkins opened 2 years ago

tabatkins commented 2 years ago

Currently, the *-items properties are extremely simple - aside from the legacy keyword doing some magic, their keywords are left completely uninterpreted. The *-self properties then, as their auto behavior, grab the *-items value from their parent element, and interpret them appropriately - resolving logical values against the element's writing mode, etc.

Per @bfgeek, this might not match author expectations, and might end up not being web compatible. Chrome received a bug about this, where an author wrote align-items on a column flexbox (which corresponds to the horizontal axis), and expected it to horizontally align a positioned child. Per spec, this won't work - the positioned child will take the parent's align-items value as its align-self value, but its align-self property operates in its containing block's block axis, which in this case is vertical.

Ian's suggestion is that we do direction resolution on the -items properties, producing a pair of physical positions, and then the -self properties take their auto values from the pair, grabbing from the pair according to their own axis

So in the example above, the column flexbox (with align-items: flex-end and a default justify-items: normal) would produce a horizontal alignment of "right", and a vertical alignment of "normal". Then the positioned child, with both of its -self properties being auto, would take an align-self of "normal" (because its align- axis is vertical) and a justify-self of "end" (the logical direction corresponding to horizontal right).

dholbert commented 2 years ago

Just to clarify the proposal... How does writing-mode play into this (if at all)?

E.g. in your example at the end, would anything need to work out differently if the flex item had an orthogonal writing mode? Or would it still end up choosing the same final physical axis?

dholbert commented 2 years ago

(and relatedly: in practice, does this only change behavior for abspos flex children?)

bfgeek commented 2 years ago

As a concrete example:

<style>
  .containing-block { position: relative; }
  .abspos { position: absolute; align-self: start; justify-self: end; }
</style>

<div class="containing-block">
  <div style="flex; align-items: center;">
    <div class="abspos"></div>
  </div>
  <div style="flex; flex-direction: column; align-items: center;">
    <div class="abspos"></>
  </div>
</div>

Should the two "abspos" go in the same direction? What happens with align-self: initial? What happens with inset:0? Note that containing-block could have a different writing-mode+direction of the static-container.

fantasai commented 2 years ago

The align-self and justify-self properties initialize to auto, which for absolutely-positioned elements does not reference the container`. https://www.w3.org/TR/css-align-3/#valdef-justify-self-auto

We might have a compat problem here that we need to address for flexbox particularly, but the ideal behavior here is that align-items has no effect on abspos descendants.

tabatkins commented 2 years ago

Looking more closely here, it appears that the current behavior of browsers is just to apply the "inheritance" of -self for the purpose of calculating the static position (of abspos flexbox children). I can't get any browser to pay attention to -self properties for the normal alignment of the abspos, so I presume that's not implemented at all yet and we can rely on the current spec explicitly not looking up at *-items when determining its behavior. (See https://jsfiddle.net/dyp9uwea/.)

So this probably just needs (yet another) quirk inserted into the abspos flex children staticpos determination.

bfgeek commented 2 years ago

The align-self and justify-self properties initialize to auto, which for absolutely-positioned elements does not reference the container`. https://www.w3.org/TR/css-align-3/#valdef-justify-self-auto

This isn't clear from the spec to me - can you quote the place where this is mentioned?

We might have a compat problem here that we need to address for flexbox particularly, but the ideal behavior here is that align-items has no effect on abspos descendants.

Hmmm - we have a larger issue here then. Currently align-items for both grid and flex (interoperably across all engines) affect the static position. I believed that we were going to keep the align-items, and justify-items behaviour for grid.

Looking more closely here, it appears that the current behavior of browsers is just to apply the "inheritance" of -self for the purpose of calculating the static position (of abspos flexbox children). I can't get any browser to pay attention to -self properties for the normal alignment of the abspos, so I presume that's not implemented at all yet and we can rely on the current spec explicitly not looking up at *-items when determining its behavior. (See https://jsfiddle.net/dyp9uwea/.)

Right that's what I was looking at implementing - as well as the staticpos rectangle alignment. I suspect we aren't compat constrained in the align-self / justify-self properties (but are compat constrainted with the align-items / justify-items ).

(and relatedly: in practice, does this only change behavior for abspos flex children?)

Abspos flex children in a column flexbox.

tabatkins commented 2 years ago

This isn't clear from the spec to me - can you quote the place where this is mentioned?

The first sentence of the "auto" definition: "Behaves as normal if the box has no parent, or when determining the actual position of an absolutely positioned box."

bfgeek commented 2 years ago

I see thanks.

bfgeek commented 2 years ago

Hmmm - we have a larger issue here then. Currently align-items for both grid and flex (interoperably across all engines) affect the static position. I believed that we were going to keep the align-items, and justify-items behaviour for grid.

E.g. https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=10629

tabatkins commented 2 years ago

Ah, right, our wording actually directly says that by referencing "actual position". We intended that static position would use the normal rules, which means inheriting from the parent's *-items properties. We should make that clearer, tho.

fantasai commented 2 years ago

In full, this seems to be where we're at:

*-self applies to abspos:

*-self: auto on abspos:

staticpos rectangle:

Edits needed:

css-meeting-bot commented 1 year ago

The CSS Working Group just discussed [css-align] *-items properties might need to resolve directions early, and agreed to the following:

The full IRC log of that discussion <dael> Topic: [css-align] *-items properties might need to resolve directions early
<dael> github: https://github.com/w3c/csswg-drafts/issues/7612#issuecomment-1230963091
<dael> fantasai: There was an issue raised against how we interp varios items on abspos
<dael> fantasai: Alignment spec says when you abspos a box with specific offsets alignment prop apply in inset rectangle.
<dael> fantasai: You can stetch, center, left align in inset box.
<dael> fantasai: None is impl yet, but that was the direction
<dael> fantasai: What we were saying is when you abspos the box you're in a formatting context that's not your parent's that you're out of flow from
<dael> fantasai: Spec that align items property of parent don't effect your alignment as an abspos
<dael> fantasai: Problem we ran into is when staticpos there's existing behavior where alignment prop do effect your position
<fantasai> https://github.com/w3c/csswg-drafts/issues/7612#issuecomment-1230963091
<dael> fantasai: Seems like we're at the summary we linked to
<dael> fantasai: If you are abspos and not staticpos the align and justify: self align you in inset box. If you're static they align you in staticpos rectangle
<dael> fantasai: If you're align or justify-self is auto and you're not staticpos you ignore parent. If you are static pos we look at -items of your parent and use alignment based on that
<dael> fantasai: [reads out comment]
<dael> fantasai: That's my understanding of where we're at. Bringing to WG to ask for review and decide if that makes sense
<dael> iank_: One thing good to clarify is what writing mode does align-self:start operate in when insets are set?
<dael> fantasai: I think that's the next issue
<dael> iank_: This is just about static pos rectangle?
<dael> fantasai: That's the focus
<dael> iank_: Prop is static pos rect operates in writing mode direction of parent?
<dael> fantasai: Yeah. I think it would need to for flex stuff follow parent formatting context
<dael> iank_: Okay. So if it's static pos it's within the writing mode of the parent. I think that's probably fine.
<dael> iank_: Side note- do we ahve an open issue for when static pos rectangle is fragmented?
<dael> fantasai: I don't believe we do I think fragment like whatever it's derived from
<dael> iank_: There's complexities I can add to an issue
<dael> astearns: What we're talking about would apply to curent grid and flex children but the rest is waiting on impl for other formatting context?
<dael> iank_: As far as I understand this is broadly status quo for grid and flexbox
<dael> fantasai: I believe so. Might be clarifying for grid but this is for flex
<dael> astearns: As much as I followed it seems good to me
<dael> astearns: Other comments?
<dael> astearns: Shall we resolve on taking the changes in https://github.com/w3c/csswg-drafts/issues/7612#issuecomment-1230963091 ?
<dael> astearns: Objections?
<dael> RESOLVED: Take the changes listed in https://github.com/w3c/csswg-drafts/issues/7612#issuecomment-1230963091
fantasai commented 1 year ago

@bfgeek We believe we've fixed all of this in the specs, let us know if anything seems to still be off?