- From: Florian Rivoal <florian@rivoal.net>
- Date: Tue, 18 Oct 2016 17:19:08 +0900
- To: www-style list <www-style@w3.org>
Just for the record, I believe that neither this proposal of mine that I am responding to nor the one from Tab it was attempting to replace are needed anymore. As the latest incarnation of CSS Scroll Snap covers the use cases. - Florian > On Jun 30, 2015, at 06:05, Florian Rivoal <florian@rivoal.net> wrote: > > Hi Tab, > > I've been looking at this proposal of yours > discussed in https://tabatkins.github.io/specs/css-sticky-scrollbars/ > > I think it is overall a good idea addressing valid use cases, but I have some > disagreements about the design, so I've been thinking of how to tweak it to be > more to my liking. Also I have some use-cases that are not explicitely > addressed by your proposal which should be covered as well. > > If you just want my proposal, jump all the way to the bottom of this mail, to > SUMMARY. Otherwise keep on reading for the rationale building up to that > proposal. > > == FULL STORY == > > First, I am not sure that anchoring at a distance from the edge is what we actualy > need. I absolutely see that in in the chat example, if you're in the middle of > the scroller, you want to stay there no matter how much content gets added to > the end. But if you scroll to 1em of the end, with a scroll-anchor distance of > 2em, do you want to stay forever at 1em from the end? You might fail to notice > and forever miss one line as new messages get added. It seems to me it would be > more friendly to snap to the end, and anchor there. Maybe both are useful and we > can have a switch, but if we only get one, I think it should be the one that gets > you to the edge, not the one that keeps you near it. > > Also if you're not within the scroll-anchor distance from the edge, and the > content grows, it would be useful to be able to say from which edge of the > scroller you maintain a constant distance. In the classical chat example, or > similar situations where content gets added to the bottom, you want to > maintain the offset from the top. But when new content comes at the top, > as it does for example in twitter, you want the other way around. > > This, together with the "go-to-the-edge-if-you-are-close" behavior mean that > specifying the behavior both on the start and end edge are useful. Under your > proposal only one side (start or end) per axis can have an anchor zone. > > With names to be bikesheded, that gives me the following properties instead of > overflow-anchor. > > scroll-offset-anchor: [ start | end ]{1,2} > scroll-edge-behavior: [ inert | [ glue | magnet ] <length>? ]#{1,4} > or maybe > scroll-edge-behavior: inert | [ glue | magnet ] <length>{0,4} > if the previous one is overkill > > scroll-offset-anchor tells you if you maintaint the distance from the start or > end edge of the scroller when it grows and you're somewhere in the middle. If > you have 1 value, it applies in the inline and block directions, and if you > have 2, the first is block and the second is inline. > > scroll-edge-behavior is similar to your overflow-anchor, and tells you what > happens if you get within the scroll-anchoring distance of an edge. ''inert'' > get you what we have now without any special property, ''glue'' what you > specified, and ''magnet'' scrolls you all the way in. The optional length > works the same as in your spec to set the scroll anchoring distance. If you > set 1 value, it applies to all 4 edges, and 2 to 4 values work the usual way: > top-bottom left-right, top left-right bottom, top right bottom left. > > Another consideration is that if instead of manual scrolling (scrollbar, > mousewheel, touchscreen...), what is trigering the scrolling is moving the > text insersion caret inside a editable text field, it's a bit more tricky. > Let's say your scroll-anchoring distance is equivalent to 3 lines' height. At > any point in the editable field other than the last 3 lines, if you move the > caret down one line and that line was the last visible line, your scroller > moves by 1 line. If you move to caret to the 3rd-to-last line and we're in > glue mode, nothing special happens, since caret movements explicitly change > the scroll position. In magnet mode though, we jump all the way to the edge, > which may be jarring. What we could do instead is always mainting a > scroll-anchoring distance worth of space between the caret and the visible > edge of the scroller. That way, when you're within the last 3 lines, the > result is the same and you're scrolled all the way, but this happens without > discontinuity in the amount of scrolling you get when you move the caret by > one line. > > It also seems that this "keep a bit of context around the caret" effect can > also be quite useful even if we're not anchoring at the edge, so maybe it > should be a separate property. This is not an essential part of the proposal, > but it seems better to me with it. > > scroll-context: auto | <length>{1,4} > > auto gets the value from the scroll-anchoring distance (maybe only in magnet > mode?), the other values let you set it up explicitely. > > Besides caret based scrolling, this could also apply to scrolling triggered by > focusing elements. If you focus (by pressing the tab key, programatically...) > a button or something that is in the scroller, but out of view, the scroll > offset is adjusted to make it visible. So far so good. But if you have for > example a 15px box shadow around your buttons that you would like to be > visible when focusing them, you could set "scroll-context: 15px" to make sure > the whole thing is in view. Which makes me think that maybe scroll-context > should also apply to focusable children of the scroller, to let you > override element by element the values set on the scroller itself. > > == Demos == > Here are a few JS-bins to play around with. They illustrates situations other > than the chat or twitter examples when these properties would help. > > * Demo 1 > http://output.jsbin.com/xovuzil/ > > Problems with a scroller with padding that contains an editable thing, and an > overlay over the scroller meant to fit in the padding when you're scrolled all > the way down. > > Would be made better with either "scroll-context: 1em" directly, or getting it > through "scroll-edge-behavior: magnet 1em". > > * Demo 2 > http://output.jsbin.com/mabemi/ > > Similar to demo 1, except the padding overlay is in the scroller instead of > over it. > > Would also be made better with either scroll-context or > scroll-edge-behavior:magnet, potentially with different values on different > edges. (scroll-edge-behavior: magnet 1em, magnet 1em, magnet 2em). > > In these 2 examples, glue mode (or equivalently, the overflow-anchor behavior) > wouldn't help: if you have scrolled all the way down, and type text to grow the > content, the caret movements will set the scroll position, overriding the glue > effect. While the caret would be kept in the visible area of the scroller, > it would not account for the overlays, which would move out of view in demo 2, > or obscure the content in demo 1. > > * Demo 3 > http://output.jsbin.com/fusedo/ > > This one is arguably less disfunctional than the first 2, but may suffers > from hidden content if you navigate the content of the scroller by tabing > around instead of scrolling around, depending on exactly how the UA choses to > bring the focused element into view. (On this example, webkit/blink do well > even without the property, but Firefox and IE do not). > > This also would benefit from using either properties, in the same way the > preceding 2 examples did. > > In all 3 demos, if you don't expect the content to be programatically grown, > using either property gets you the same thing, but if you do, using > scroll-edge-behavior is likely preferable. > > == SUMMARY == > Replace overflow-anchor by scroll-edge-behavior, and add scroll-offset-anchor > and scroll-context. > > scroll-edge-behavior: [ inert | [ glue | magnet ] <length>? ]#{1,4} > or > scroll-edge-behavior: inert | [ glue | magnet ] <length>{0,4} > Initial: inert > Applies to: scrollable elements > Definition: sets up scroll-anchor areas, and the behavior in them: stay where > you are, or scroll to the edge and stay there. > > scroll-offset-anchor: [ start | end ]{1,2} > Initial: start > Applies to: scrollable elements > Definition: From which edge of the scroller should the distance be maintained > the scroller grows if we're not in a scroll-anchor area. > > scroll-context: auto | <length>{1,4} > Initial: auto > Applies to: Scrollable elements and focusable descendants of scrollable > elements > Definition: When the scroll position is moved by caret movements or by > focusing elements, how much room should be kept between this > active element and the visible edges of the scroller. auto > computes to the scroll-anchor distance of magnet-mode edges. > > > - Florian > >
Received on Tuesday, 18 October 2016 08:19:36 UTC