css - How to slow down inertia/momentum scrolling on mobile - html

I am working on a scrollable card gallery of sorts.
For this I am using a CSS grid structure.
Something along the line of:
<div class="cs-wrapper">
<div class="cs-container">
<div id="card-1" class="cs-card-container">
<div class="cs-card">
</div>
</div>
<div id="card-2" class="cs-card-container">
<div class="cs-card">
</div>
</div>
...
</div>
</div>
Using the css
.cs-content {
height:100vh;
position: relative;
display: grid;
grid-template-columns: var(--cs-container-grid-gap) 1fr var(--cs-container-grid-gap);
grid-gap: var(--container-grid-gap);
z-index:10;
}
.cs-container {
display: grid;
position: relative;
grid-gap: 0vw;
grid-template-columns:repeat(auto-fill, 100vw);
grid-auto-flow: column;
grid-auto-columns: calc( 100% / var(--cs-cards-per-screen));
grid-template-rows: 1fr;
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
overflow-scrolling: touch;
overflow-x: scroll;
scroll-snap-type: x mandatory;
}
.cs-container > div {
height: 100%;
width: 100%;
position: relative;
margin:0;
overflow: auto;
scroll-snap-align: start;
}
.cs-card-container {
height: 100%;
width: 100%;
position: relative;
margin:0;
overflow: auto;
}
Now the code works as intended, the cards are positioned right and the scroll works.
However the inertia/momentum scrolling on mobile tends to scroll a bit to fast, when scrolling on mobile you have to swipe very sensibly to get to the next card and not skip 1 or 2 cards (you have to be able to swipe trough multipe cards if you'd wish to, so a stop on each card isn't an option).
Now I am looking for a way to slow down the scroll speed so it becomes usable
I'd prefer a CSS only solution if possible. Things I have tried:
Playing around with
.cs-container {
perspective: 1px;
transform-style: preserve-3d;
}
.cs-container > div {
transform: translateZ(-1px) scale(2);
margin-top:-10px;
margin-left:-10px;
top:-10px;
}
this did seem to slow the scroll down a bit, however the scroll acted unpredictable and as the divs are now in the background and scroll half as fast. as soon as cs-container has scrolled to the end only half the cards have been scrolled through (also the scroll snapp is now off by half a card)
Javascript
I tried a couple javascript solutions I found, but all of them relied on the scrolling being done with the mousewheel, so for mobile this didn't work

Did not run the code myself, but it sounds like you are looking for the property called:
{scroll-snap-stop: always}

You can use {scroll-behavior: smooth;} to the element for a smoother scroll.
Remember : When this property is specified on the root element, it applies to the viewport instead. This property specified on the body element will not propagate to the viewport.

There is a property: -webkit-overflow-scrolling: auto.
The value auto should disable momentum-based scrolling. This means that the content stops scrolling immediately when you remove your finger from the touchscreen.
Note: Unfortunately, this property is currently supported by only a few browsers. Instead you could also use the overflow:hidden propery on the .cs-wrapper element, and to get back the normal scrolling behavior, you can position a <div> absolutely inside of the element to get scrolling back with overflow:auto. I think this is the best option using only css!

Related

How to create a scrollable container that doesn't clip its contents?

I'm currently trying to create a horizontal card row for my website. The cards have a little transition where they lightly rotate and raise on hover, like so:
I want to make the row scrollable on the horizontal axis to make it responsive, but after setting overflow-x: auto; on the container, I noticed that the cards now get clipped, making the hover effect look pretty bad.
I've tried setting overflow-y: visible; on the container but it has no effect. Is there any way I can keep my cards from clipping but still leave the container scrollable?? Thanks in advance for your help.
You should wrap the elements in 2 divs. The first and inner will have a width(for horizontal scroll) that is greater than the viewport. And the second and outer div, will have a width, that is exactly the same as the viewport. The second div will then have the property overflow-x: scroll; overflow-y: hidden and it should work.
Example:
body {
width: 100vw;
height: 100vh;
}
outer-wrapper {
width: 100vw;
height: max-content;
overflow-x: scroll;
overflow-y: hidden;
}
inner-wrapper {
width: 150vw;
height: 100px;
display: flex;
}
cards {
// what ever properties you want
}

Scroll Snap Full Screen Always Scrolls 2 Sections

The problem is shown here:
https://codepen.io/team/css-tricks/pen/yLLqqgP
This is the important part:
html {
scroll-snap-type: y mandatory;
}
section {
height: 100vh;
scroll-snap-align: start;
}
When setting height of section > 120, or similar this issue can get fixed, but this is a hack.
When I start scrolling, with a scroll wheel, then it always scrolls two sections, which makes the whole logic unusable.
I am using Chrome: 86.0.4240.183.
This codepen example is from: https://css-tricks.com/practical-css-scroll-snapping/ which is a very well known ressource for css examples.
This is a known bug in Chrome unfortunately, caused by using either html or a container with a background-color property for the scroll container. It only affects scroll wheels and not trackpads or touch scrolling on mobile. See this thread for a demonstration of the problem.
The simplest solution is to just use a nested container to hold the scroll, although, bizarrely, you may notice that the scroll-snap now has a small delay on it. This is the best that can be done with the current implementation:
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
html {
overflow: hidden;
}
.container {
height: 100vh;
width: 100%;
overflow: auto;
scroll-snap-type: y mandatory;
}
h1 {
width: 100%;
height: 100vh;
scroll-snap-align: start;
border: 2px solid black;
display: flex;
justify-content: center;
align-items: center;
}
<div class="container">
<h1>1</h1>
<h1>2</h1>
<h1>3</h1>
<h1>4</h1>
</div>
The problem is unfortunately compounded once you realise that 100vh is also non-static (read: extremely janky) on some mobile browsers due to the implementation of retracting UI, potentially leading to unstyled gaps as the html layer shows through before the container fills up the remaining space. I've spent hours wrestling with this issue this year and have yet to come up with a totally satisfactory solution, settling for media queries to reset back to html in most cases and targeting any edge cases with JS.
Here's one possible media query you could add for that:
#media (hover: none) and (pointer: coarse) {
html {
overflow: auto;
scroll-snap-type: y mandatory;
}
.container {
height: auto;
display: contents;
scroll-snap-type: unset;
}
}

How to not make CSS modal get cut off in page?

I have a modal implemented in CSS and it is getting cut off at the bottom of the page:
I've tried the following style attributes:
style = "max-height: 100%; overflow-y: scroll; margin: auto"
But I am unable to make the modal fit in the page, on mobile or desktop. How can I fix this?
Update:
Tried:
style = "max-height: 95vh; max-width: 95vw; overflow-y: auto;"
This gave some room at the bottom, but I still want the modal to fit in the page:
Edit 2:
I've updated my modal to:
class="modal" style="overflow-y: auto; max-height: 100vh; padding: 30px 0px 50px 0px; box-sizing: border-box; height: 90vh; z-index: 1000"
and my modal content to:
class="modal-content" style="height: 80vh; max-height: 600px; position: relative; display: flex; flex-direction: column; width: 95vw; max-width: 600px; border-radius: 4px; overflow: auto; box-sizing: border-box"
This seems to solve the problem I was having that caused the bottom button to get cut off; however, now, the header doesn't look right. It is pushed down. What can I do to fix this?:
CSS has the unit vh (viewport height) for this.
max-height: 95vh; /* 95% of the viewport's height */
This works on any device, mobile or desktop, with a supporting browser. Even Internet Explorer 9 supports it.
Regarding the overflow, I recommend you overflow-y as auto, not scroll. The difference is that scroll will always result in a scrollbar, even if not needed.
Remember to also limit the width of the modal. Long playlist names might, especially on mobile devices, lead to unwanted layout results otherwise.
For width, the corresponding unit is vw (viewport width).

Chrome (windows) does not hide scrollbar

I have this scrollable div, which (on my Mac in Chrome) hides the scrollbar when I don't scroll. On windows 8 however, it doesn't work in Chrome and Firefox.
Ie doesn't support this too, but I've enabled it using the following CSS:
-ms-overflow-style: -ms-autohiding-scrollbar;
Is there any way to enable this behaviour for Chrome and Firefox
Here is a jsfiddle
maybe you can use something like that?
body {
margin:0;
padding:0;
overflow-y: hidden;
}
body:hover {
overflow-y: scroll;
}
http://jsfiddle.net/4RSbp/165/
Scrollbar is hiding on your Mac because this is a system preference (System Preferences > General > Show scroll bars). And unfortunatelly there is no version of -ms-overflow-style for Firefox or Chrome.
For anyone comming here, if you want to hide scrollbars in a cross-browser cross-system way and keeping the scrollability enabled without visual glitching of mouse over rendering; hiding them behind the limits of your container is a good approach. (Beware, this will be long)
Let's say you have a scrollable container and you want to hide the vertical scrollbar (even the thin transparent one that moderns systems shows). its ID is #scrollable:
<html>
[...]
<div id="scrollable">Some Y large content</div>
[...]
</html>
To achieve what we want, #scrollable must be contained by a node exclusively for it (a div would work, in this example #scrollable-cover) and we must know #scrollable layout width and height. Lets say it'll be an area of 800px x 900px. So we got:
<html>
[...]
<div id="scrollable-cover">
<div id="scrollable">Some Y large content</div>
</div>
[...]
</html>
And its CSS:
#scrollable-cover {
width: 800px;
height: 900px;
overflow: hidden
}
#scrollable {
width: 820px;
height: 100%;
overflow: scroll;
}
With that, #scrollable will be stretched to the height of its inmediate parent (#scrollable-cover) and its large content will render it like an scrollable box, but, since its width is 20px bigger than its parent, which has an 'overflow: hidden' property, the scrollbar will not be shown, because it renders on the 20px hidden at the right of #scrollable.
This lead us to an inconvenient, the content of #scrollable could also be rendering in that hidden 20px width area; to avoid that, there is two methods. One is to wrapper all the content of #scrollable in a #scrollable-wrapper with 800px width and auto height:
<html>
[...]
<style>
#scrollable-cover {
width: 800px;
height: 900px;
overflow: hidden
}
#scrollable {
width: 820px;
height: 100%;
overflow: scroll;
}
#scrollable-wrapper {
width: 800px;
height: auto;
}
</style>
[...]
<div id="scrollable-cover">
<div id="scrollable">
<div id="scrollable-wrapper">Some Y large content</div>
</div>
</div>
[...]
</html>
This way all content will be rendered in a 800px width layout inside our scrollable box. But, if you dont want to add another element, you can solve this with the Second CSS only option, using box-sizing an a 20px padding at the right:
#scrollable-cover {
width: 800px;
height: 900px;
overflow: hidden
}
#scrollable {
width: 820px;
height: 100%;
overflow: scroll;
padding-right: 20px
box-sizing: border-box;
}
This way, anything rendered inside #scrollable will avoid the 20px hidden area at the right, and 'box-sizing: border-box' will tell the browser to include the 20px of the padding in the total 820px width of #scrollable (otherwise, it'll grow to a computed total of 840px). Check box-sizing compatibility here: http://caniuse.com/#search=box-sizing
And of course, this example could also work with horizontal scrolling, just increasing the height of #scrollable 20px above the height of it's inmediate parent. That's the clue ;)
For anyone who got here not because of system preferences, but because scroll bars in general are visible in on Windows Systems in Chrome:
Do not save your css like that:
overflow: scroll;
but rather
overflow: auto;
This way it will only show on Windows Chrome Browser if necessary.
found here: Hide useless scrollbars that show up on Windows only

how to enable scrolling rather than squashing divs together

on my website it is a div based layout when the window is reszied everything is pushed together. Such as images overlap or are moved below each other and divs also overlap each other.
How can I get it to scroll when the content of the div is greater than the window size, similar to facebook if you resize the window it prevents anything overlappting and just makes the user scroll?
body
{
background-color: #B0B0B0;
color: #ffffff;
margin-top: 0px;
margin: 0px;
}
#header
{
width: 100%;
height: 100px;
margin: 0px;
padding: 0px;
}
#content
{
width: 80%;
height: 800px;
margin-top: 50px;
margin-left: auto;
margin-right: auto;
padding: 30px;
}
<div id="header">
[Header]
</div>
<div id="content">
[Content]
<img src="image1.png" /><img src="image2.png"/><img src="image3.png" />
</div>
The html is like that but obviously with more content
Hope I haven't made this too confusing, thanks.
Just add overflow:auto; to your div.
You can also use the following if you only want x or y scrolling
overflow-x:auto;
or
overflow-y:auto;
use the overflow:scroll; to enable scrolling in the DIVs
You must add white-space:nowrap; to your body tag.
I believe you may want overflow: auto;
Here's a comparison between auto and scroll.
add the style
overflow: scroll;
to #content
This answer is pretty late, however I stumbled across this question, as I was having issues on one of my pages, where I have this Page with 30 odd inputs of various types, that are split between two tables. I was unable to scroll to see about 10 or so inputs at the bottom of the page, and could not even scroll left to right when adjusting the browsers width.
What solved my issue was:
html, body {
overflow: visible;
}
This activated my X and Y scroll bar.
I had an issue with my footer not adjusting when scrolling, it instead would just stay fixed where it was situated before scrolling. this was due to my master CSS having the footer's position set as absolute. Simple fix, just creating a new style element in the page and added
footer {
position: fixed;
min-width: 100%;
}
I hope this helps anyone looking for a solution.
As stated by user3726345 , the best option to use is the
html,body {
overflow: visible;
}
using
overflow: auto;
dosnt give the best output. then you can further adjust your footer codes to your taste.