Skip to content
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

[css-align-3] What is supposed to happen to abspos in an end-aligned scroll container? #4957

Closed
tabatkins opened this issue Apr 16, 2020 · 11 comments

Comments

@tabatkins
Copy link
Member

Consider this scenario:

<container style="display:block; height:100px; overflow:auto; position:relative;">
  <child style="height:200px;"></child>
  <abspos style="position:absolute; left:0; top:0; height:500px;"></abspos>
</container>

Layout's well-defined so far. Scrollable overflow area is 500px tall, initial scroll position is 0, etc.

Now set "align-content: end;" on the container.

The rules in the spec say that, since the container is a scroll container, you do not move the alignment subject at all. Instead, you adjust the initial scroll position of the scroll container such that the alignment subject is aligned relative to the scrollport the same that it would be aligned relative to the container if it weren't scrollable. The container is thus scrolled 100px down, so the bottom of the child is aligned with the bottom of the scrollport.

In other words, if you toggle 'overflow' on and off, the content should sit perfectly still, while remaining fully accessible in the scrollable case (that is, never getting shifted into the unscrollable area).

And this goal is achieved! For the in-flow content, at least. It does not work for the abspos. Because the abspos is positioned relative to the scrollable overflow area, it jumps as you toggle overflow on and off, and the container is either scrolled or not. This violates the original design goal.

I only see one possible fix: Abspos descendants are shifted by content alignment, so they maintain the same positioning relative to the alignment subject. (Increasing the scrollable overflow area, but I think never pushing anything into the unscrollable zone.)

Alternately, we can just ignore it, and accept that the original design goal only applies to in-flow content, and the relative positioning of in-flow and abspos content can change depending on 'overflow'.

Thoughts?

@tabatkins tabatkins added the css-align-3 Current Work label Apr 16, 2020
@MatsPalmgren
Copy link

<container style="display:block; height:100px; overflow:auto; position:relative;">

Did you mean display:grid perhaps?

<child style="height:200px;"></child>

Otherwise, <child> is an inline and height does not apply.

@tabatkins
Copy link
Member Author

I meant display:block, but pretend these are all blocks. ^_^

@fantasai
Copy link
Collaborator

fantasai commented May 7, 2020

Testcase to try to demonstrate what we're talking about: http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=8069

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-align-3] What is supposed to happen to abspos in an end-aligned scroll container? #4957.

The full IRC log of that discussion <dael> Topic: [css-align-3] What is supposed to happen to abspos in an end-aligned scroll container? #4957
<fantasai> github: https://github.com//issues/4957
<dael> github: https://github.com//issues/4957
<dael> TabAtkins: While fantasai and I doing position re-write we found incompat
<dael> TabAtkins: 2 ways to resolve
<dael> TabAtkins: When you do align-content: end it aligns end of content box with end of container box. If container is scrollable don't want to do that. Instead adjust scroll position for same visual effect.
<dael> TabAtkins: If you flip overflow from auto to visible you should have content looking the same.
<fantasai> https://www.w3.org/TR/2020/WD-css-align-3-20200421/#overflow-scroll-position
<fantasai> whiteboard: https://www.w3.org/TR/2020/WD-css-align-3-20200421/images/scroll-align-padding.jpg
<dael> TabAtkins: However abspos position themselves in a way that doens't work well. If you say top:0 it's positioned against top edge of scrollable area. If you set align:content end to start at bottom of scroll abspos is out of view. If you turn overflow back to visible abspos is now attached to top and in view.
<fantasai> ^ is what happens with in-flow content
<dael> TabAtkins: Two ways to deal.
<fantasai> Now we're talking about interaction with abspos
<dael> TabAtkins: 1) say that's fine and overflow is slightly different positioning model. I think I prefer this
<dael> TabAtkins: 2) We do adjust how abspos is positioned when it's non-start so abspos containing block is moved in the scroll container to allow to sit in same spot
<dael> TabAtkins: Requires some ffixup but not too complicated. Another thing in there. Not sure authors expect. When they say abspos they expect top
<dael> Rossen_: Inner border box edge?
<dael> TabAtkins: Scollable area edge when scrollable.
<dael> Rossen_: top and left logical establish origin and you don't go past htat
<dael> TabAtkins: Yes
<dael> fantasai: One key point is the origin of the scrollable overflow area is not nec the initial scroll position. Initial scroll position can depend on alignment. Sep. concepts
<dael> Rossen_: I'm unclear in your def when they expect it to be aligned to top important to define what top means. If we allow abspos elements to redefine scrollable area as they extend past hte origin in the negative before the start than your statement is circular
<dael> TabAtkins: We're saying the opposite
<myles> q+
<dbaron> I think I understand the question here, and I don't yet have an opinion on which behavior seems better -- and given that I think it's preferable to go with the simpler one as Tab suggested. But it's possible thinking about it more would make me have a different intuition for what "should" happen.
<dael> TabAtkins: In the thread there's 100pxhigh scroll cotnainer and abspos with top:0 inset. 200px of content. If you set align content end scroll container starts at bottom.
<dael> TabAtkins: Right now abspos still connected to top of area so it's not visible. Attached to 0 position.
<dael> TabAtkins: That means difference in render for visible and scrollable overflow. We try and avoid that with normal content.
<dael> TabAtkins: Is that okay? For abspos position to jump depending on if visible or scrollable?
<dael> TabAtkins: That vs where authors expect abspos to be. Does it push down to always be visible?
<dael> iank_: Concerned if this flipped on overflow status because webdev will change that to disable scroll for example. A bit concerning.
<dael> TabAtkins: Not sure which you argue for in that case
<dael> Rossen_: My excectation is the behavior would be closer to how we handle static inflow layout. Favor stable rather than jumping with the overflow toggle
<dael> TabAtkins: You prefer we redefine abspos position to rely on alignment. So top:0 withing align:end would be visible within the original scroll position
<dael> iank_: No, the other one.
<dael> TabAtkins: It maintains stable position relative tos tatic content but visually jumps based on if you flip overflow on/off
<dael> iank_: Yes. IT's not jumping, just that the initial scroll position is set differently.
<fantasai> testcase
<fantasai> http://software.hixie.ch/utilities/js/live-dom-viewer/?%3C!DOCTYPE%20html%3E%0A%3Cstyle%3E%0Abody%20%3E%20div%20%7Bdisplay%3A%20flex%3B%20float%3A%20left%3B%20border%3A%20solid%3B%20width%3A%2050px%3B%20height%3A%2050px%3B%20margin%3A%20100px%3B%20position%3A%20relative%3B%7D%0A%3C%2Fstyle%3E%0A%3Cdiv%20style%3D%22overflow%3A%20auto%22%3E%0A%20%20%3Cdiv%20style%3D%22border%3A%20solid%20aqua%3B%20width%3A%201
<fantasai> 00px%3B%20height%3A%20100px%3B%20flex%3A%20none%3B%22%3E%3C%2Fdiv%3E%0A%20%20%3Cdiv%20style%3D%22border%3A%20double%20blue%3B%20width%3A%20100px%3B%20height%3A%20100px%3B%20position%3A%20absolute%3B%20left%3A%200%3B%20top%3A%200%3B%22%3E%3C%2Fdiv%3E%0A%3C%2Fdiv%3E%0A%3Cdiv%20style%3D%22flex-flow%3A%20row-reverse%20wrap-reverse%3B%20%22%3E%0A%20%20%3Cdiv%20style%3D%22border%3A%20solid%20aqua%3B%20width%3A%201
<fantasai> 00px%3B%20height%3A%20100px%3B%20flex%3A%20none%3B%22%3E%3C%2Fdiv%3E%0A%20%20%3Cdiv%20style%3D%22border%3A%20double%20blue%3B%20width%3A%20100px%3B%20height%3A%20100px%3B%20position%3A%20absolute%3B%20left%3A%200%3B%20top%3A%200%3B%22%3E%3C%2Fdiv%3E%0A%3C%2Fdiv%3E%0A%3Cdiv%20style%3D%22flex-flow%3A%20row-reverse%20wrap-reverse%3B%20overflow%3A%20auto%3B%22%3E%0A%20%20%3Cdiv%20style%3D%22border%3A%20solid%20a
<fantasai> qua%3B%20width%3A%20100px%3B%20height%3A%20100px%3B%20flex%3A%20none%3B%22%3E%3C%2Fdiv%3E%0A%20%20%3Cdiv%20style%3D%22border%3A%20double%20blue%3B%20width%3A%20100px%3B%20height%3A%20100px%3B%20position%3A%20absolute%3B%20left%3A%200%3B%20top%3A%200%3B%22%3E%3C%2Fdiv%3E%0A%3C%2Fdiv%3E%0A
<dael> TabAtkins: It's jumping visually. align-content:end and you have the abspost top:0 Either top of container or top of scrollable area. align-content:end top of the scrollable is above
<fantasai> testcase - http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=8068
<dael> fantasai: I made a test case if you want to load the testcase and see
<dael> TabAtkins: Glad the answer wasn't obvious
<dael> fantasai: [shares testacase]
<dael> fantasai: blue double border is abspos and aqua box in inflow. FIrst example is typical flexbox where both origin and scroll are top
<dael> fantasai: In second example it's not a scroll container. First example is same if it's scroll or not bc we're in start start
<dael> fantasai: Second shows overflowness
<dael> fantasai: I made a 4th
<dael> fantasai: First is abspos and an item and you can see they align.
<dael> fantasai: Second is overflow auto. In otherwords we clip. Layout is same
<dael> fantasai: Third we have the flex flow changed to be reversed in both axises so it overflows to top and the left. abspos doesn't care about flex flow, stays to top left of block
<dael> iank_: There's something slightly different in [missed]
<dael> fantasai: This is about expectations
<dael> fantasai: Rendering for first 3 is correct
<dael> iank_: No virtical scroll in 2nd?
<dael> fantasai: This is jsut layout and position. THere's lots of bugs about scrollers. Let's not pay attention to them.
<dael> fantasai: I can switch to overflow hidden
<dael> fantasai: 4th example is same code as 3rd but we applied hidden or auto. Ends up clipping around the behavior
<dael> fantasai: Question for TabAtkins is is this what we should see or something different? Important to see aqua box is top and left in 3. We defined alignment to allow people to align to bottom. DOn't want clip so you can't scroll to them. Goal of def is you shoudl be able to scroll to left and top to see content.
<dael> fantasai: Desc in spec to say you do the alignment...instead of alignt to bottom left you keep everything and change initial scroll position
<dael> fantasai: Scroller in 4th should be able to scroll to the left and up. Question we have is for an abspos element depending on how we describe it, do we want to have it layout so that when you're in its initial scroll position it's in its desc position or desc it so when you scroll to origin you get the desc position.
<dael> iank_: Clarification: How you're calc the layout overflow. If you've got a scrollable overflow cotnainer. Calc layout overflow from right to left. Starts on right. But initial position is still 0.
<dael> iank_: With align-content:end are you assuming layout overflow calc starts from bottom or start at top and scroll to bottom?
<dael> fantasai: That's what we're trying to figure out
<fantasai> updated testcase for the minutes: http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=8069
<dael> Rossen_: Mental model when I impl containing box edges desfined by inner border box. That inner border box def origin. You may or may not allow scrolling into the negative for purpose of accommodating alignment. THird case here illustrates using alignment you may create situations where overflow has to allow scroll to negative
<dael> Rossen_: Origin is always well defined and not redefined. Position always in respect to that box.
<dael> Rossen_: That makes both the layouts stable b/c adding or removing scrollbars doesn't change position of abspos elements. Always everyone has expected top/left is in respect to border box
<dael> Rossen_: otherwise a little unstable
<dael> fantasai: 2 renderings we're looking at for last case is what you're seeing in FF where you can scroll to see everything. One poss is you see this initially and scroll i both directions
<dael> Rossen_: That's overflow nto positioning
<drousso> present_
<dael> fantasai: Other is the same rendering as the second case but initial scroll position is to bottom right. See bottom right corner but can scroll to everything.
<myles> q-
<dael> iank_: Maybe different wayt o sdo align-content:end. Maybe in 3rd the aqua box should overlap and then when container is big enough the aqua box sticks
<dael> fantasai: Distinction between safe and unsafe. You can request overflow to always bottom but that's not the default.
<dael> Rossen_: We've been at this for 25 minutes. I think we have 2 choices. We can contain working on the issue or make a resolution here
<dael> fantasai: I'm not sure. I can see that it's a nice invarient to be able to flip overflow on and off and have thing you see the same. I can also see authors surprised if they position top-left and it's not there it's in the middle
<dael> Rossen_: How I'm reading convo is top left is defined by origin established by inner border box of containing block. If it's overflow and has scrollbars in that case there might be additional mech that require scrollers to enable going negative but htat's sep. SHouldn't redefine size for overflow
<dael> TabAtkins: No one has mentioned scrolling negative
<dael> Rossen_: With the aqua box aligned bottom and right, it's overflowing to the negative of the origin of the dark containing block. Do we agree? Overflow is the negative in the inline and block
<dael> TabAtkins: Aqua is inflow box? If that's unscrollable that's blink bug
<dael> Rossen_: Do we agree here aqua overflows in negative?
<dael> TabAtkins: Nothing in spec makes it go negative
<dael> fantasai: I think Rossen_ is talking about negative in respect of top and left of border box of scroll container. You're talking negative of contents which makes it unscrollable
<Rossen_> q?
<dael> fantasai: We all agree aqua box extends out ot left and top of container just like ex 3. Impl not considering that as scrollable and that's a bug.
<dael> iank_: One thing good to clarify is...when blink does reverse we treat similar to a [missed] cotnainer tso overflow starts in top right. :reverse we start from bottom
<Rossen_> q
<dael> iank_: That will influence decision
<dael> dholbert: We intend to be same in FF
<dael> iank_: For row:reverse and column?
<dael> dholbert: Yeah
<dael> iank_: THe question is how do you want align content to work. Start overflow from bottom and right and scroll position in initial or you start top left and scroll position is at end. THat influences this decision
<dael> Rossen_: We're getting into the weeds. I suggest we continue in the issue and bring back for resolution
<dael> Rossen_: 2 clear choices that were well articulated. I'd encourage you to continue discussion there.
<dael> TabAtkins: Last bit. b/c one behavior falls out if we dont' resolve on anything we're in effect choosing one.
<Rossen_> q
<dael> fantasai: Showing this whiteboard that's around concept in spec. Wanted to make sure we didn't mix up scroll to bottom of scrollable vs making etra space you need.

@tabatkins
Copy link
Member Author

Note that one behavior (that abspos continues to resolve its insets against the scrollable area, unmodified by the content-alignment properties) falls out of the spec definitions as-is, so that'll be the de facto choice if we don't make forward progress. If you want the other option, make sure to spend some energy on this. ^_^

@dbaron
Copy link
Member

dbaron commented May 11, 2020

I think some of the question here is about what the underlying model is. There was some prior discussion about this in #1425.

It seems like there are two ways to describe the behavior that the spec describes:

  1. the align-content layout happens as normal, but the scrollbar allows scrolling in the reverse direction from normal. This probably implies that, for the initial scroll position, scrollTop or scrollLeft (as relevant) is 0. I think this model would apply that absolute positioning top: 0 or left: 0 position would be visible at the initial layout position.
  2. For elements with overflow, align-content: end doesn't have its normal effect, but instead, causes the initial scroll position to be at the end rather than the start. This probably implies that for the initial scroll position, scrollTop or scrollLeft (as relevant) is non-zero. I think this model would apply that absolute positioning top: 0 or left: 0 position would not be visible at the initial layout position, but would instead be visible only when the user (or developer) scrolls all the way to the top or left, which is not the initial position.

The spec's current text seems to take the second choice.

I think for the sake of developers who work with this a lot being able to build a reasonable mental model of what's happening, I think it's better to choose the entire model together. So I think the question of what we think should happen for absolute positioning (this issue), the question of what we think scrollTop and scrollLeft should do, and perhaps other questions, should be used to choose which model the spec should use to describe this, and then the answers to those questions should result from the choice of model.

@bfgeek
Copy link

bfgeek commented May 12, 2020

Thanks @dbaron - this was the same point I was trying to make on the call.
cc/ @dholbert

FWIW I think that (1) is likely better as its more consistent with the current platform, and likely more in line with what developers are expecting.

E.g. consider https://www.software.hixie.ch/utilities/js/live-dom-viewer/?saved=8089 in FF.

By my reading of the current spec, in model (2) describes the lime element wouldn't be centered (if the example had align-content: end on it obviously).

(also FWIW it appears that Chrome is trying to fix its scrollLeft scrollTop bugs not being at zero at the moment).

@astearns astearns added this to the VF2F-2021-02-11 APAC milestone Feb 2, 2021
@w3c w3c deleted a comment from css-meeting-bot Feb 12, 2021
@johannesodland
Copy link

I might be late to the discussion here, but I am a little puzzled by this behaviour.

Model 1 – Shifting the coordinate system

Model one implies that the coordinate system of the scrollable overflow area is shifted so that parts of the scrollable overflow area must be addressed with negative coordinates. Using this model an abspos element with top: 0; left 0; would be visible in the initial scroll port, but not without side effects for authors.

How would it be possible to position abspos elements so that they cover the entire overflow area? top: 0; left: 0; right: 0; bottom: 0; would only cover the positive parts of the coordinate system (the initial scroll port).

How is size of abspos elements affected? that is what would top: 0; left: 0; height: 100%; do?

How would it be possible to position abspos elements relative to the top/start with css only without taking content distribution into account? Changing content distribution would change the entire coordinate system, requiring new calculations for positioning abspos elements.

Model 2 – Scrolling to match content distribution
This model scrolls the scroll port so that initially visible content of the scroll container matches the expected alignment. The coordinate system is not shifted, and positioning works as expected relative to the scrollable overflow area.

This implies a hidden functionality to control the initial scroll position of a scroll container. I can see authors using content distribution to get to this functionality, much as we used overflow: hidden to start a new block formatting context.

Maybe this functionality could be exposed? initial-scroll: start | center | end. That way it would also be possible to override the scrolling if that was not intended.

Model 3 – no scrolling
There is also a third model here, that is worth discussing; avoiding magical scrolling.

We're aligning the content of the scrollable overflow area. I would be puzzled if I used the short hand place-content: end; to justify items and ended up with a scrolled container.

@astearns astearns removed the Agenda+ label Mar 10, 2021
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-align-3] What is supposed to happen to abspos in an end-aligned scroll container?.

The full IRC log of that discussion <dael> Topic: [css-align-3] What is supposed to happen to abspos in an end-aligned scroll container?
<dael> github: https://github.com//issues/4957
<dael> iank_: I think we didn't have information previously. Perhaps we forgot to agenda- it
<dael> fantasai: This needs more discussion in GH. It is one of the main open issues against alignment spec. Which model do we want for handling alignment in a scroll container
<dael> astearns: Been 20 days since comment on this issue, maybe b/c waiting on it on the call. Can one of you summarize what's left to do on this issue on GH?
<dael> fantasai: Yeah, TabAtkins and I can
<dael> astearns: We'll discuss more in the issue

@css-meeting-bot
Copy link
Member

css-meeting-bot commented Jan 24, 2024

The CSS Working Group just discussed [css-align] align-content and scroll coordinates.

RESOLVED: alignment on scroll containers results in same layout as non-scrolling containers, and doesn't affect whether initial scroll position is zero-coord, just changes which direction and how far you can scroll

The full IRC log of that discussion <astearns> other issue: https://github.com//issues/4957#issuecomment-627004071
<fantasai> github: s scrolling in the reverse direction from normal. This probably implies that, for the initial scroll
<fantasai> github: https://github.com//issues/9807
<fantasai> gitub: https://github.com//issues/4957#issuecomment-627004071
<fantasai> gitub: https://github.com//issues/4957
<fantasai> github: https://github.com//issues/4957
<Frances> fantasai: We changed the way that we do scroll-coordinate in a reverse flex container with intiial position at 0 as the position of everything and can scroll from there. Implementations don't do it for alignment, need to make content visible if scrolling of the start side of the container for example.
<Rossen_> q?
<Frances> fantasai: Match the implementations. Broader discussion in 4957 two mental models for how they happen. Option 1: lay out as normal. Option 2: layout as position 0. We should go with the first option.
<Frances> Florian: Constrained by compat?
<Frances> fantasai: I don't think so.
<fantasai> s/as position 0/as start alignment, shift scrollable area/
<fantasai> s/as normal/as normal, allow access to scrollable area in opposite direction/
<Frances> Ian: As long as it flips script-origin seems fine with me.
<Frances> Rossen: Any other thoughts or objections?
<Frances> PROPOSAL: alignment in a scroll container follows the same model as reversing in flex box as implemented which is layout for non scrollable containers that allow scrolling in the opposite direction as necessary.
<Frances> Ian: scroll origin concept to choose which point if in negative space is actually negative. It is how implementations today do it.
<iank_> This is the concept we have in the spec currently https://drafts.csswg.org/css-overflow-3/#scroll-origin
<Frances> Rossen: from a fragmentation point of view?
<Frances> Elika: layout point of view
<Frances> fantasai: if no scrollbar,, would not cause any content to shift its position. What happens in the box should not move whether overflow is on or off. In access by scrolling.
<Frances> fantasai: Due to alignment, need to distinguish layout whether different or not.
<Frances> Ian: why not reference scroll origin in resolution? such as how they behave in flex containers.
<Frances> Rossen: Some consensus on the scroll origin.
<Frances> Ian: Resolve on the scroll origin?
<Frances> fantasai: Resolve on behavior and solve implementation later.
<Frances> fantasai: current spec of scroll-position and scroll-overflow are distinct and might not be related.
<fantasai> s/scroll-position/initial scroll positoin/
<fantasai> s/scroll-overflow/scroll origin/
<fantasai> fantasai: and we probably need to fix that
<fantasai> fantasai: so I don't want to rely on that definition
<fantasai> proposal: alignment in scroll containers doesn't affect layout wrt non-scrolling containers, just changes which direction and how far you can scroll
<fantasai> proposal: alignment in scroll containers doesn't affect layout wrt non-scrolling containers or whether initial scroll position is zero-coord, just changes which direction and how far you can scroll
<Frances> Rossen: any objections?
<fantasai> proposal: alignment on scroll containers results in same layout as non-scrolling containers or whether initial scroll position is zero-coord, just changes which direction and how far you can scroll
<fantasai> proposal: alignment on scroll containers results in same layout as non-scrolling containers, and doesn't affect whether initial scroll position is zero-coord, just changes which direction and how far you can scroll
<Frances> resolved: alignment on scroll containers results in same layout as non-scrolling containers, and doesn't affect whether initial scroll position is zero-coord, just changes which direction and how far you can scroll
<fantasai> s/resolved/RESOLVED/

@fantasai
Copy link
Collaborator

Copying over from #9807 :

In https://www.w3.org/TR/css-align-3/#overflow-scroll-position we write:

None of this changes how scroll coordinates are assigned: the origin is still where it would be in a start-aligned container, it just might be initially positioned outside the scrollport.

Wrt scroll coordinates, if we are referring to .scrollTop/.scrollLeft, I noticed when testing flex-flow: row-reverse etc that the initial scroll position corresponds to zero, so I think we should adjust the spec for alignment to be consistent with that: the initial scroll position corresponds to zero, even if that position is scrolled to the writing-mode–relative "end" of the scroller.

fantasai added a commit to fantasai/csswg-drafts that referenced this issue Mar 25, 2024
…extends scrollable area w3c#4957

It does not otherwise affect layout or scrolling mechanics.
fantasai added a commit to fantasai/csswg-drafts that referenced this issue Mar 10, 2025
…extends scrollable area w3c#4957

It does not otherwise affect layout or scrolling mechanics.
fantasai added a commit that referenced this issue Mar 10, 2025
…extends scrollable area #4957

It does not otherwise affect layout or scrolling mechanics.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants