I have a webpage that normally snaps to predominant direction of scroll when it starts, the default behavior web browsers have: if the div is scrollable in both directions, the scroll direction is locked to the first axis that the user moved their fingers more, and unlocked if the user also moves their fingers in the other axis more than some threshold amount.
This works great and natural for almost everything though I have some canvas-like (for clarity: NOT HTML canvas, I'm talking about regular divs here) div that I want to disable this behavior as for navigating inside that particular view, it's counter-intuitive.
How can I disable axis locking for a particular element?
Locking of scroll axis is not a part of any of the current the Web APIs https://developer.mozilla.org/en-US/docs/Web/API so it is a property of the user agent (browser or browser+OS). This means that there is likely no solution, and if there is one it will probably only work for a specific browser.
Related
So I've been running into this annoying problem and I don't seem to be able to fix it by myself. I'm currently working on an experimental App written Angular (11.2).
The page itself should be divided into several screen filling sections which users scroll through as if it were specific tiles. Therefor, scroll snapping is a must.
However I'm simply not capable of hiding the mobile browser address bar. This is due to the fact that, in order to get the snapping effect, the page only consists of one single element that is scaled fitting the current viewport. Also manually hiding the browser address bar using the widely used window.scrollTo(0,1) hack does not work since there is no real scrolling to be achieved.
Thus my question
Can I somehow hide the browsers address bar while still being able to keep the required layout required for scroll snapping?
You could use the app.manifest file to set your web-app to fullscreen. Dont know exactly if just works with installed pwas, bur you could give it a try.
This is the guidance I'm looking at: https://www.w3.org/WAI/WCAG21/Understanding/reflow.html
For example, in the image below, the highlighted red container scrolls horizontally, but the rest of the page is responsive.
The w3 guidance says 2-d scrolling should be avoided, but I didn't know if that specifically meant the page itself should not scroll horizontally.
I believe that 1.4.10 Reflow is intended to address webpages where the entire page requires vertical and horizontal scrolling to be readable on mobile devices. If yours only requires horizontal scrolling in one small area, then you should be fine.
This may be helpful:
1.4.10 Reflow (AA)
Intent:
Having to scroll in two dimensions to view content on a page makes seeing and reading the content difficult. If a user has to scroll in order to see a full line of text, it becomes very difficult to then follow to the next line.
https://dequeuniversity.com/resources/wcag2.1/1.4.10-reflow
It's also worth noting a couple of things with a design like this:
The items in this section need to be keyboard accessible, as per 2.1.1. Keyboard.
The user should be able to scale the text to 200% without the layout breaking, as per 1.4.4. Resize Text.
When a keyboard user tabs through the links, the focus ring should be visible, as per 2.4.7 Focus Visible.
I'm trying to position an element directly above a mobile keyboard. ie: position absolute/fixed to bottom of page, but pushed up by the keyboard (or pushed up equivalent height of the keyboard).
Usually this is the opposite behavior of what's desired, and there's to be a lot of people fighting to keep bottom elements in place. I feel like I remember fighting those same battle before...
But now that I want it to move, it's not. (of course!)
My focus is iOS Safari for now, but would prefer cross browser.
It seems older versions of iOS changed window.innerHeight when the keyboard opened, for better or worse. But that's no longer the case. Which may explain why I'm not seeing what I expected to see...
I've been playing around with variously positioned parent elements with no luck.
Is this even possible? Or is the keyboard now completely detached from the viewport?
It is not possible. The keyboard appears to be its own entity away, or as you said, detached from the viewport.
Although you can't fix the element to the keyboard exactly, might I suggest that you may be able to use JavaScript and add a class that raises the fixed element the same height as the keyboard.
The keyboard sizes can be found here:
What is the height of iPhone's onscreen keyboard?
It's possible with VisualViewport API now to listen for the viewport change and read it values. In practice, it's not sending events immediately so the experience might be laggy.
Is there any way to control the speed or in other word, the viscosity of scrolling by the user in a scrollable element in a mobile browser?
I'm focusing on android browser.
No, scroll speed is controlled by the browser (and usually directly by the settings on the computer/device). I think your code wouldn't effect that.
In regards to a work around...
There are ways you could try to fake a different scroll speed by
moving your own content instead of the page, however, it's a bad
idea in terms of usability.
If the interest is that users have to scroll multiple times to get
to content further down the page, I would also suggest anchor points
with a smooth scroll option built into it. That way the control
to jump to that content faster is left to the user.
And lastly, if you're concerned about users leaving your content too
quickly and missing important information, it may be a better idea
to better style your content to visually catch their attention
before they begin scrolling away from it.
I hope this information helps you moving forward.
I've an application with a scrollable element that contains a list of items.
I'd like to optimize the rendering for jank free scrolling, with some tricks that are described in http://aerotwist.com/blog/on-translate3d-and-layer-creation-hacks/ for exemple
Just would like to know: where should I force the browser to create layers? Am I supposed to create a rendering layer around each of my list items?
I also would like to know why the browser isn't able to do this on his own, because when an element is scrollable, it makes sens to me that we will move the content of this element up and down without changing the rendering of the inner content right? So why doesn't the browser creates a layer for the inner content of any scrollable element?
By the way, is this layer creation hack consistent across browsers?
Edit:
I've noted that it is now possible to indicate to the browser that some changes will happen.
I could use for exemple: will-change: scroll-position; according to this article
However, I still don't understand why the browser needs this, because if we set overflow-y: auto;
or overflow-y: scroll;, it seems obvious that the scroll position is expected to change.
If you are scrolling list of elements that are 'static' (they don't change their relative position, size, opacity etc. while you scroll) there isn't much that you can do to improve the scrolling performance. That's because your scrollable content is already promoted to a separate layer. You can easily test it yourself:
open this demo (it doesn't use translate3d nor will-change),
enable 'Show composited layer borders' in the DevTools
and observe the result.
Orange border around the scrollable content indicates that it is on a separate layer.
If you are experiencing janky scrolling then try to narrow your issue down (e.g. using Timeline in the DevTools). translateZ(0) is not a silver bullet for all performance problems.