w3c / csswg-drafts

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

Setting the primary scrolling direction for a scroll container #10060

Open Zhang-Junzhi opened 5 months ago

Zhang-Junzhi commented 5 months ago

Currently, almost all UAs assume the vertical direction is the first-class scrolling direction, so that UAs set the default action of a pure wheel event to scrolling the content vertically, while setting the default action of a wheel event with an additional key(typically Shift Key) to scrolling the content horizontally.

That's a reasonable assumption for a page in horizontal writing mode. A page in vertical writing mode, however, is another story, which is much more likely to overflow horizontally.

If we can set an element's primary scrolling direction, then an UA knows that it can set the default action of the pure wheel event to scrolling the content horizontally, while setting the default action of a wheel event with an additional key to scrolling the content vertically.

Also, there are two vertical writing modes: vertical-rl and vertical-lr. It is worth suggesting UAs to logically "convert" scrolling direction.

Zhang-Junzhi commented 5 months ago

Just as a personal opinion:

I personally prefer the concept of overflow, instead of scroll for CSS, for example, I would prefer a property named primary-overflow-direction over primary-scroll-direction:

html {
    writing-mode: vertical-rl;
    primary-overflow-direction: horizontal;
}

Because overflow is a more "style-oriented" name, although I started the topic using the concept of scroll, for the purpose of intuitively describing the issue.

A primary overflow direction is only suggestive information, it only tells an UA which direction is expected to be scrolled only by the user (or at least to be scrolled far more frequently than the other direction). The UA then takes advantage of the knowledge, and improves UX as far as possible, for example, by "converting" the default actions of wheel events for a mouse with one single directional wheel.

Zhang-Junzhi commented 5 months ago

Further argument: Why is this feature necessary for CSS? What's the problem if a JavaScript developer programmatically implements such a feature?

  1. Performance issue. Although JavaScript developers are absolutely able to change the default action of a wheel event for vertical-writing pages, but they have to set the wheel event's passive option to false, in order to be able to call preventDefault to prevent the default action, and then write their own action code. Unfortunately, turning off passive mode results in a very big performance loss.

  2. Ugly coupling. Also, this couples style with event handling, making code hacky.

  3. Uncertain consequence. Things become even worse if you consider the default action of a wheel event is implementation-specific, and may vary from UA to UA. By blindly preventing the default action of a wheel event, the developer is doing something at risk of messing things up.

fantasai commented 5 months ago

I think UAs should be doing this automatically, based on the principal writing mode. So I guess there's a few questions:

Zhang-Junzhi commented 5 months ago

I think UAs should be doing this automatically, based on the principal writing mode.

It's absolutely reasonable to do this automatically based on the principal writing mode. However, as an alternate solution, I would also like to further introduce just my two cents on adding a new property:

While what this issue mainly aims to handle is about vertical writing mode, there might also be cases where it's desirable for pages even when it's principal writing mode is horizontal. For example, a horizontal-tb page can use the property if it contains a bunch of extremely wide cityscape pictures:

<div style="primary-overflow-direction: horizontal; overflow: auto">
    <!--a bunch of extrememly wide cityscape pictures-->
    <picture ...>...</picture>
    <picture ...>...</picture>
    <picture ...>...</picture>
    ...
</div>
* Are there bugs filed against implementations for this?

Yes, there're at least bugs filed for this kind of issues, as far as I know, on bugzilla.mozilla.org:

Years ago, the issue was mentioned by David Baron, and then I implemented autodir feature for Firefox.

later on, the Firefox Desktop team also utilises the autodir feature to improve UX.

Unfortunately, the big disadvantage of autodir is that it's not a CSS thing, so it's unaware of any element's style. Turning autodir on by default would mean pages all over the world that contain any horizontally scrollable elements could be affected. So Firefox had to turn autodir off by default.

Things are much better if we solve this issue with CSS: the issue that autodir couldnot resolve can be resolved perfectly by CSS: Because with CSS, we can selectively affect pages or elements according to it's style(Either automatically based on the principal writing mode, as you said, or manually set using a new property, as I said).

fantasai commented 5 months ago

Turning autodir on by default would mean pages all over the world that contain any horizontally scrollable elements could be affected.

That seems... expected?

So Firefox had to turn autodir off by default.

Can you explain why?

SebastianZ commented 5 months ago

Turning autodir on by default would mean pages all over the world that contain any horizontally scrollable elements could be affected.

That seems... expected?

Not necessarily. Imagine an article with a horizontal image gallery. If the reader is only interested in the article text, it would be surprising/annoying for them if while scrolling down the scroll direction suddenly changed within the image gallery.

Sebastian

Zhang-Junzhi commented 5 months ago

Turning autodir on by default would mean pages all over the world that contain any horizontally scrollable elements could be affected.

That seems... expected?

So Firefox had to turn autodir off by default.

Can you explain why?

@SebastianZ gave a good example why autodir has to be turned off by default: Because autodir is unware of CSS style, so it will blindly apply to ANY elements if they are horizontally scrollable.

On the contrary, with CSS, we can selectively affect pages or elements where the developer is pretty sure the user will be eager to scroll horizontally(e.g. a page with vertical principal writing mode, or a bunch of extremely wide cityscape pictures on a city fan website the user will definitely be interested in). This is where a CSS solution will go beyond autodir.

fantasai commented 5 months ago

Because autodir is unware of CSS style, so it will blindly apply to ANY elements if they are horizontally scrollable.

I don't understand. Wasn't the behavior taking into consideration both overflow and writing-mode? These are both CSS properties.

Not necessarily. Imagine an article with a horizontal image gallery. If the reader is only interested in the article text, it would be surprising/annoying for them if while scrolling down the scroll direction suddenly changed within the image gallery.

Suppose the gallery is vertical instead of horizontal. Why should that be different? Either the user wants to scroll through the image gallery or they don't. Laying out the gallery horizontally vs vertically shouldn't make a difference to whether scroll events are sent to the gallery or the main page.

Zhang-Junzhi commented 5 months ago

I don't understand. Wasn't the behavior taking into consideration both overflow and writing-mode? These are both CSS properties.

Sorry for being unclear. When I said "CSS unaware", I meant we hadn't introduced any CSS private property to do autodir, so autodir has nothing to do with CSS's extra assistance. Let me be more specific: autodir does "use" writing-mode and overflow indirectly(without the concept of CSS), in some way, in some condition. But that's not the key point. The key point is: No selectiveness. We cannot selectively turn on autodir for some elements in the document, while turning off autodir for some other elements in the same document. Because we do not have such a CSS property that selectively does it.

Suppose the gallery is vertical instead of horizontal. Why should that be different? Either the user wants to scroll through the image gallery or they don't. Laying out the gallery horizontally vs vertically shouldn't make a difference to whether scroll events are sent to the gallery or the main page.

It does matter based on whether autodir is enabled.

<article class="very-tall"> <!--overflows vertically-->
    ...
    <div style="overflow:auto" class="very-wide"><img ...><img ...>...</div> <!--overflows horizontally-->
    ...
</article>

If autodir is disabled, a user can scroll the <article> from top to down, using plain wheel scroll(plain means no Shift), without the possibility of accidentally falling into the gallery. Because plain wheel scroll will not be changed by disabled autodir, so, the gallery is "essentially an unscrollable element" from the perspective of plain wheel scroll.

If autodir is enabled, then there's possibility of falling into the gallery.

Zhang-Junzhi commented 5 months ago

Let me summarize my personal key solution for this topic in possibly a shortest sentence:

All we need is selectiveness.

Example 1:

<style>
div
{
    overflow: auto;
}
.i-am-pretty-sure-users-will-be-interested
{
    primary-overflow-direction: horzizontal;
}
</style>

<article class="very-tall">
    ...
    <div class="very-wide i-am-not-sure-users-will-be-interested">...</div>
    ...
</article>

<article class="very-tall">
    ...
    <div class="very-wide i-am-pretty-sure-users-will-be-interested">...</div>
    ...
</article>

Example 2:

<!--According to to normal reasoning-->
<html style="writing-mode: vertical-rl; primary-overflow-direction: horizontal;">
    ...
</html>

Example 3:

<!--For some reason, the scroll direction users are more interested in may still be vertical.
For example, this is an old page using "writing-mode" for layout due to historical reasons.
Because it doesn't have use primary-overflow-direction, so we don't break compatibility.-->
<html style="writing-mode: vertical-rl;">
    ...
</html>
Zhang-Junzhi commented 5 months ago

BTW, just one more thing: A name just came to my mind: more-interesting-overflow-direction, which I think reflects the intention of the property better than my previously proposed name primary-overflow-direction.

But more-interesting-overflow-direction is awfully long due to my English proficiency. I believe someone can think of a better name.

css-meeting-bot commented 2 months ago

The CSS Working Group just discussed Setting the primary scrolling direction for a scroll container, and agreed to the following:

The full IRC log of that discussion <emeyer> fantasai: There's an issue about vertical-text document means your primary scroll direction is horizontal and that's not hooked to the scroll wheel
<emeyer> …So deves are having to capture elements and code around that
<emeyer> …The obvious thing to me is if your principal writing mode is horizontal, then if you have a 1D scrolling device it should scroll in that direction
<emeyer> …Do others agree? Should we clarify?
<flackr> q+
<emeyer> astearns: Is the person who raised it asking for a switch?
<emeyer> fantasai: Yes, but I think it would be better to change the default and then we can add a switch if one is needed
<astearns> ack flackr
<iank_> q+
<emeyer> flackr: I was going to ask if we know the cases where we have a 1-axis device?
<emeyer> …I think it would be bad to change a touchpad where it's easy to scroll both horizontally and vertically
<emeyer> …I'm worried that we'll get into cases where we do this on devices where it doesn't make sense to do this
<astearns> there are mice with 2d scroll wheels, too
<bramus> Plugging in a regular mouse with a scrollwheel on macos has this 1-axis limitation
<emeyer> …Alternate idea: if your primary physical axis is not scrollable, we change it to a logical axis
<emeyer> fantasai: I think that will work in some cases but not others
<emeyer> …I run into sites that scroll both directions, but one direction only a little bit
<emeyer> …It would be awkward if when you resize the window, the scroll wheel starts or stops working
<dbaron> https://bugzilla.mozilla.org/show_bug.cgi?id=1358017#c0
<astearns> ack dbaron
<TabAtkins> I think this needs to only apply to 1-d scroll affordances
<emeyer> dbaron: If you dig through the comments, there's a link to a Bugzilla issue that this started with a meeting we had with JP publishers in 2017
<TabAtkins> q+
<emeyer> …They said they were reluctant to publish with vertical text because mouse scroll wheels weren't working as expected
<emeyer> …I agree with Rob that we need to be careful about assuming what an implementation knows
<emeyer> …The fact that you have vertical scroll events doesn't tell you if a user can handle horiztonal scrolls
<emeyer> …We should avoid an implementation that assumes you know that
<emeyer> flackr: I wonder if we should fix this in the OS
<emeyer> fantasai: At some point the browser has to be involved because the OS doesn
<florian> q+
<emeyer> s/doesn/doesn't know the scroll direction/
<florian> q-
<emeyer> flackr: Yeah, if it's a 1D scroll wheel
<fantasai> s/scroll direction/writing mode/
<astearns> ack iank_
<emeyer> iank_: Alison, did Edge have an -ms-scroll property at one point?
<emeyer> alisonmaher: Not familiar, can look into it
<astearns> ack TabAtkins
<emeyer> TabAtkins: This ties into David's points: in terms of events we get, we can tell if something is a scroll wheel, right?
<fantasai> s/can/can't/
<emeyer> …But if you have a 2D scroll wheel, we can't tell that
<emeyer> flackr: I think touchpads get sent at scroll events with distance in each direction
<emeyer> …There is a difference between precise and non-precise scrolls and that's usually where the differentiation happens
<iank_> https://learn.microsoft.com/en-us/previous-versions/hh973361(v=vs.85)
<emeyer> TabAtkins: This does annoy me; if there's a reasonable expectation in the common scroll wheel case, even if we can't quite tell when a wheel is 2D, we should spend config space on this as we do for asking users which way they want their 1D wheels to move
<kizu> q+
<astearns> ack kizu
<emeyer> …With vertical text, if we get imprecise events, we should stick with block direction
<emeyer> kizu: I can imagine a case where we reach the default axis, we want to switch
<emeyer> q+
<emeyer> …With a switch property, you could switch directions
<emeyer> …mid-page
<astearns> ack fantasai
<Zakim> fantasai, you wanted to reply
<emeyer> fantasai: I don't think that would make sense
<emeyer> …Say you load a page with an image slightly too wide, do you expect to scroll over in the image and then scroll down in the whitespace after that?
<emeyer> kizu: [missed[
<kbabbitt> re: -ms-scroll-* events mentioned by iank_ - those were related to scroll snap points / touch overscroll features
<emeyer> fantasai: We know the main axis, but we might not know whether we have a scroll wheel that works in two different axes
<bramus> Sidenote: You can (ab)use scroll-driven animations for the behavior kizu wants: https://scroll-driven-animations.style/demos/horizontal-section/css/
<emeyer> …If you have a 2D wheel, use it, but if you have a 1D wheel, then that's the one that should go in the main direction of the document
<flackr> q+
<astearns> ack emeyer
<iank_> kbabbitt: what about the "-ms-scroll-translation" property?
<fantasai> emeyer: Literally today, I visited this page
<emeyer> https://www.propublica.org/article/microsoft-solarwinds-golden-saml-data-breach-russian-hackers
<khush> q+
<fantasai> emeyer: you get partly down the page and then there's a horizontal bit that scrolls
<TabAtkins> kbabbitt, I think we should standardize that *as well*, separately from this conversation.
<fantasai> emeyer: this is exactly this use case, scrolling down the main axis
<fantasai> emeyer: and it switched directions
<fantasai> emeyer: I had no problem understanding what was happening
<fantasai> emeyer: This is a thing that's done, would be nice ot address via CSS rather than using JS
<TabAtkins> that way `scroll-translation` can be used by a page *on purpose* to do the thing Eric is talking about
<bramus> https://scroll-driven-animations.style/demos/horizontal-section/css/
<fantasai> bramus: do that with scroll-driven animations
<florian> q+
<kbabbitt> iank_, oh I missed that one - would need to dig into it
<fantasai> bramus: it's a hack...
<astearns> ack flackr
<emeyer> flackr: Scrolling the primary axis and then the secondary axis does not give you access to everything
<florian> q-
<emeyer> …This isn't a universal solution
<emeyer> …We do offer a shift key modifier
<emeyer> …We could look at the writing mode of a scroller to change direction for subscrollers, but I'm not a fan of the mode-switching
<TabAtkins> q+
<astearns> ack khush
<bramus> +1
<bramus> q+
<emeyer> khush: Was going to ask if there's any reason this would be l;imited to the root scroller instead of it changing when you're focused on a subscroller
<emeyer> …Using writing mode seems an intuitive solution, but examples show you might want to switch based on writing mode
<emeyer> s/based on/based on things other than/
<fserb> welcome back :)
<emeyer> fantasai: That's what I would want, but can't find where I did
<emeyer> …I started with the writing mode of the principal document, since that seemed to make sense
<astearns> ack TabAtkins
<fserb> pasting the pre-split comments:
<fserb> fantasai: I can't find where I wrote the thing that the viewport should be based on principal writing mode of document, and the scroller should be based on the writing mode of the scroller
<fserb> …If you can only scroll in one axis, then you attach to the scrollable axis
<fserb> done.
<fantasai> s/in one axis/in one axis due to overflow-x vs overflow-y /
<emeyer> TabAtkins: Kevin mentioned some ms- prefixed things about scroll wheel events turn into vertical or horizontal scroll
<emeyer> …We could scope the automatic one to the root document based on the writing mode
<TabAtkins> -ms-scroll-translation
<emeyer> iank_: It would be interesting to know how -ms-scroll-translation actually behaved
<florian> q+
<fantasai> /me q?
<astearns> ack bramus
<emeyer> kbabbitt: Will need to research
<fantasai> s| /me q?||
<emeyer> bramus: I liked what Elika suggested to attach to the scrollable axis
<florian> q-
<emeyer> …Seems like a good idea
<iank_> kbabbitt: specifically would be curious what got plumbed through from the OS to handle that case.
<flackr> q+
<bramus> s/to attach to the/to eventually attach to the
<emeyer> astearns: Are we arriving at yes, we want to see if we can detect scrolling and attach to the main document?
<TabAtkins> (sorry, scribe is not on a mic so i couldn't hear him asking for an interrupt)
<emeyer> dholbert: What if you have two mice and one is 1D and one is 2D?
<emeyer> …And both are connected, and both are giving scroll events?
<emeyer> TabAtkins: I don't think we can tell that even if you're only using one mouse at a time, so we'd have to treat as: the 2D mouse scrolled vertically would give you horizontally
<emeyer> flackr: This is going to me common because every laptop user has a touchpad and many have a mouse attached
<florian> q+
<astearns> ack flackr
<emeyer> TabAtkins: If you're doing something physical, it's terrible to make that change direction
<astearns> ack florian
<emeyer> flackr: Responding to Elika's 1D scroll suggestion, there's a risk of scrolling down a long vertical page, landing on a horizontal scroll without knowing, and preventing further vertical scroll
<bramus> Good remark.
<emeyer> florian: Didn't catch this was concluded, but if we are facing horizontal scroller, presumably it's not really flipping, you scroll as possible
<khush> q+
<emeyer> …What I mean is, the H scrolwheel of a mouse should always get you H scrolling even if you remap it
<astearns> ack khush
<emeyer> khush: Rob has a good point that if you try to do this automatically, you can start mapping scroll behavior by mistake
<emeyer> …IN the ProPublica case linked, the author does want you to do that, and it's why a switch might be a good thing here
<TabAtkins> That's why I was suggesting the default only apply to the root scroller, fwiw
<emeyer> …Letting the author having a say in that is good
<emeyer> flackr: I think flipping a 1D is uncontentious
<astearns> ack dbaron
<emeyer> astearns: For more, we probably need a proeprty
<emeyer> dbaron: Worried we're getting too far into specifying UI instead of web tech
<emeyer> …Or at least, speccing how UAs handle particular input devices
<emeyer> …I'm not sure how much of this discussion is specificable
<emeyer> TabAtkins: We have a lot of stuff about how to handle scrolling on a page, like scroll snapping
<emeyer> …I feel like this is in the same wheelhouse
<emeyer> dbaron: I think distinguishing between precise and wheel scroll might be an interesting idea but I don't think it can go in CSS
<emeyer> fantasai: I think it would need to be more abstract
<astearns> ack fantasai
<emeyer> TabAtkins: Agreed, though with a note describing how to tell devices apart
<flackr> +1
<emeyer> fantasai: +1 to Tab in IRC, it's why I raised this in the first place
<emeyer> …With small blocks, there is a concern
<emeyer> …If the author put a vertical carousel in there, it would be a problem to deal with
<emeyer> …We should explore, but we'll need to add advice to scroll in the document's primary direction
<emeyer> …As to a separate property, if we can avoid making people use it most of the time, that would be better
<emeyer> …Hopefully it wouldn't be necessary most of the time
<emeyer> astearns: Can you summarize a resolution just for the primary writing direction?
<flackr> suggestion? The UA should map known 1D scroll events to the document's writing mode block direction
<fantasai> PROPOSED: A scrolling device with a primary direction should scrol the root scroller in the block flow axis of the principal writing mod.
<fantasai> s/mod/mode/
<fantasai> s/scrol/scroll/
<emeyer> astearns: Any objections?
<fantasai> s/primary direction/primary axis/
<emeyer> khush: Should we add the clarification about precise and imprecise scroll?
<emeyer> flackr: No
<emeyer> fantasai: No, that needs to be left up to implementation
<flackr> having a "primary direction" is intentionally vague about how you tell that
<emeyer> …We can give direction, but need to leave it up to UAs
<emeyer> RESOLVED: A scrolling device with a primary direction should scroll the root scroller in the block flow axis of the principal writing mode
<dbaron> bramus: non-root scrollers still an open issue?
<dbaron> ?: yes
<bramus> s/?: yes/fantasai and astearns: yes