w3c / csswg-drafts

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

[css-scroll-snap] Scroll snap areas for fragmented boxes (like in css-multicol) #5911

Open cartr opened 3 years ago

cartr commented 3 years ago

Where does the scroll snap position go when you set scroll-snap-align on a block that's fragmented across multiple columns? (Here is a demo that attempts to do this. The goal was to create behavior similar to an e-book reader application, where text is flowed into columns that the user can swipe between.)

The CSS Scroll Snap Module says (emphasis mine):

Values represent outsets defining the scroll snap area that is used for snapping this box to the snapport. The scroll snap area is determined by taking the transformed border box, finding its rectangular bounding box (axis-aligned in the scroll container’s coordinate space), then adding the specified outsets.

However, the CSS Fragmentation Module appears to suggest that you can't apply transforms to a box, you have to apply transforms to each fragment of the box separately:

Fragmentation interacts with layout, and thus occurs before relative positioning [CSS2], transforms [CSS-TRANSFORMS-1], and any other graphical effects. Such effects are applied per fragment: for example, rotation applied to a fragmented box will calculate a rotation origin for each fragment and independently rotate that fragment around its origin.

My demo actually behaves differently in different browsers. Firefox creates multiple scroll snap positions, one for each fragment. Safari picks a column near the middle and places a single scroll snap position aligned to that column.

So it's not completely clear what's supposed to happen in this situation, and it would be nice if it was specified more clearly.

Personally, I think Firefox's behavior is the best here, mostly because it lets me do the e-book reader thing. I could also see an approach where you draw a bounding box around all the fragments to create a single scroll snap area. Safari's behavior doesn't make much sense to me so I don't think it should be written into the specification.

SebastianZ commented 3 years ago

Just for the record, Chrome's implementation obviously currently has general problems regarding multi-column elements and scroll snapping, see https://bugs.chromium.org/p/chromium/issues/detail?id=1172771.

It generally needs to be clarified how scroll-snap-* properties work for multi-column elements, not just scroll-snap-align but also scroll-padding-* don't seem to be handled as expected by the browsers.

Sebastian

tabatkins commented 3 years ago

So there are two issues here; the one being asked, and the one being alluded to by the e-reader use case mentioned in the OP. The latter is addressed in #6017.

For the question of how to snap to a fragmented element, there are a few options:

  1. draw the bounding box of all the fragments, and snap that area
  2. have each fragment be an independent snap area

The first is roughly Chrome's current behavior, the second is Firefox's.

If we do the second, there's then the question of which fragment to snap to when an element is targeted/scrolled-into-view: 2a. the first fragment is always the initial snap 2b. the first fragment is snapped when "start" aligned, the last is snapped when "end" aligned, the middle (???) fragment when "center" aligned

2b has some complications (which fragment is the "middle"? just count by index? weight by size? if # of fragments is even, do we bias toward start or end?) and can be a little confusing if you're start-snapping in one axis and end-snapping in another (this is already handled by the spec, it's just potentially confusing to authors).

So I propose either 1 or 2a, but don't have a strong opinion between them. There might also be other options we haven't thought of.

css-meeting-bot commented 3 years ago

The CSS Working Group just discussed [css-scroll-snap] Scroll snap areas for fragmented boxes (like in css-multicol).

The full IRC log of that discussion <dael> Topic: [css-scroll-snap] Scroll snap areas for fragmented boxes (like in css-multicol)
<dael> github: https://github.com/w3c/csswg-drafts/issues/5911
<dael> fantasai: Basically this is a question of how do we want to address it. We didn't spec frag boxes. Basically 2 concepts. Draw a bounding box around all frag and snap or each frag is independent snap area
<dael> fantasai: When they line up nicely it works fine. but a box split across multi columns and half is the bottom of a column and half is the top, how do you handle? Snap to the middle might not see well.
<dael> fantasai: I don't have a good answer. Wanted to ask the WG
<dael> florian: For multicol specicially drawing a big box could work. Fragmentation in general it wouldn't. Scroll and paginate could exist in the same device. If that's the case pieces might be on different canvases.
<dael> fantasai: If on sep pages you have to snap within page. No other poss interpretation. Multiple frag on same page, how to handle?
<dael> fantasai: scroll snap does apply to inline boxes. That's a case where snap to bounding box makes sense. For block may be snap to each fragment makes sense
<dael> astearns: Other ideas?
<dael> astearns: Looks like we have 2 behaviors impl and we're not sure either is what we want to spec
<dael> smfr: Examples of pages that show different behavior? Any real world ones? Basically, does it matter?
<dael> fantasai: Yeah. Let's say I have phrases with an ID. terms and definitions. It wraps 2 lines. WHen you click on a link to the definition, where do we snap? If we ask to center it
<dael> florian: In spec we don't turn on snapping for these things. What would be a doc where we would turn on snapping? If we know why it's on might be able to reason what's preferable
<dael> Rossen_: Instead of trying to come up with examples here, I think this needs to go back to GH. I think it's a good prompt to add real world motivating examples
<dael> smfr: My suggestion would be to ask if anyone obj to bounding box solution
<dael> TabAtkins: In particular if FF objects b/c that's a change for them
<dael> fantasai: I will not original person who raised issue was looking for per fragment
<dael> TabAtkins: They wanted to snap to columns
<dael> fantasai: Yes, particular use case can be done in other ways
<dael> TabAtkins: B/c asking for something different we shoudln't worry about satisfying thier case
<dael> fantasai: I think it would be good to get author feedback
<dael> astearns: One way of getting feedback is spec bounding box and ask for examples of how we're getting it wrong
<dael> fantasai: We have both impl so they can compare. We need people to pay attention
<dael> Rossen_: Will bounding box be compat with multicol?
<dael> fantasai: If you ask for center snap position you snap to center of all col the element belongs to. Not sure if that's what you wanted
<dael> florian: Earlier point that for inlines bounding box is good but block it might not makes sense. Multicol is one example. The further apart the pieces can be the less sense it makes for bounding box. Okay to say inline is bounding box, else per fragment?
<dael> jfkthame: Even inline element could run cross fragments in a multicol, couldn't it?
<dael> florian: Yeah. Double fragmented
<dael> iank_: I was going to ask same question fantasai asked, what do webdev expect here
<dael> fantasai: WE should try and reach out to dev community. Maybe jensimmons or rachelandrew
<dael> rachelandrew: If we ask webdev might get confused with the snap to column boxes. Trying to think how to separate
<dael> fantasai: Need a diagram. One of a multicol with a hot pink box or something
<dael> rachelandrew: Happy to have a go at writing blog. need to make sure we're getting feedback for the thing we want
<dael> fantasai: How about you and I work on that
<dael> rachelandrew: Sure
<fantasai> s/pink box/pink box starting near the bottom of the first column/
<dael> astearns: Alright, I'll take the tag off this and we'llg et feedback