I've got a page design that uses CSS keyframes to make a min-height: 100% <section> element containing page content slide in from the right. Once the element has animated to its final position, it is possible to "drag-scroll" the page horizontally by selecting and dragging the text, which I want to avoid.
Both the <html> and <body> elements are set to overflow-x: hidden;, which works for preventing scrollbars but still allows scrolling functionality. I do need users to be able to scroll the <section> element vertically.
I'm assuming the problem is caused by the initial translateX value in the keyframe animation, but I'm not sure how to prevent the horizontal drag scrolling.
Here's a jsfiddle demonstrating the problem.
I appreciate any input.
Perhaps a javascript solution? How is the following:
function bindEvent(e, eventName, callback) {
if(e.addEventListener) // new browsers
e.addEventListener(eventName, callback, false);
else if(e.attachEvent) // IE
e.attachEvent('on'+ eventName, callback);
};
bindEvent(document.body, 'scroll', function(e) {
document.body.scrollLeft = 0;
});
Related
Requirements
Visually remove the y-axis scrollbar from a div element
y-axis must still be scrollable, so overflow-y: hidden will not work
x-axis scrollbar must remain intact so -webkit-scrollbar { display: none; } will not work because it removes the x-axis scrollbar as well.
Solution Constraints
Must work in recent versions of Chrome and Safari (not concerned about any other browsers)
Answer to my own question:
I was actually able to accomplish this by using a combination of CSS and Javascript.
I was able to apply an overflow-y: hidden style to the div with the y-axis scrollbar I wanted to hide, and add a custom event listener to that div.
Disclaimer: This solution does not provide pageUp/pageDown, or arrow keys functionality. You will need additional event listeners to get the scroll to reflect those events.
const div = document.getElementById('elementId');
div.addEventListener('mousewheel', ($event) => {
// prevent the page from scrolling when you scroll on an
// element with a style of overflow-y: hidden
$event.preventDefault();
// Calculate and set the scroll position
div.scrollTop = div.scrollTop - $event.wheelDelta;
});
In Safari 13 release notes it is stated that there is no longer the need to apply the following to an element to enable the bounce scroll effect:
div {
overflow-x: scroll;
-webkit-overflow-scrolling: touch; /* No longer needed */
}
However, I can now no longer disable this effect with the following code:
div {
overflow-x: scroll;
-webkit-overflow-scrolling: auto;
}
I need this for a carousel I am working on. Any idea on how to fix it?
I think you should try to change that using the overflow property that in Safari blocks the bouncing scroll behaviour. To do that in the parent container of your scrolling div you have to set:
overflow: hidden;
and then in your div set something like this:
div {
overflow: auto;
}
Polyfilling this CSS property in Safari is pretty tricky.
For non-scrollable elements, you can prevent scroll chaining by simply turning off touch gestures. You can do that with a CSS property that is supported by Safari: touch-action: none.
But for scrollable elements, JavaScript will be required.
Remember that scroll chaining occurs when you reach the bounds of the element. So we need to ensure that the user is never able to fully scroll to the top or bottom. Doing this the wrong way can cause UX problems, because the user will clearly be fighting against the default inertia scroll.
So here's the trick:
Create an inner element that is at least 3px taller than the size of its scrolling parent, to force the area to get the overscroll behavior.
Immediately set the scroll position to 1px to prevent scroll chaining when scrolling up
With JavaScript, catch when the scroll position is exactly 0 or exactly at the bottom. After a requestAnimationFrame, set the scroll position to 1px from either the top or bottom.
The container will still get the inertia scroll (the user won't have to fight it) but it won't trigger scroll chaining.
Here's the JavaScript function:
this.addEventListener('scroll', async handleScroll() {
await new Promise(resolve => window.requestAnimationFrame(resolve))
const {
scrollTop,
scrollLeft,
scrollHeight,
clientHeight
} = this
const atTop = scrollTop === 0
const beforeTop = 1
const atBottom = scrollTop === scrollHeight - clientHeight
const beforeBottom = scrollHeight - clientHeight - 1
if (atTop) {
this.scrollTo(scrollLeft, beforeTop)
} else if (atBottom) {
this.scrollTo(scrollLeft, beforeBottom)
}
}
source: https://dev.to/mpuckett/the-holy-grail-web-app-shell-with-header-and-footer-for-iphone-549j
css overscroll-behavior is now supported in iOS 16. If you are targeting > iOS 16 devices, to prevent bounce effect when content inside overflowing parent reaches start or end, add following CSS to the div with overflow : scroll
div {
overscroll-behavior: none;
overflow : scroll
}
Tested in iOS 16 and above.
I don't know if i really understand this correct, but here it goes! :)
Can't you just remove that line of code from your file?
You could also try to write -webkit-overflow-scrolling: auto; !important
Hope this helped :
I have a page with much content. When I open it I have a vertical scroll bar.
I have a small div that should stick to the right side and centered (vertically).
And when user scroll it should be in the same position never move just to be there in the center all the time.
And this work in chrome,ff but I have issues with ie8.
Chrome: div stick as it should be vertical center in the viewport of the browser.
IE8: div stick to the right but it use vertical center of the whole content and I need just a viewport. So if content is height=4000px in ie8 it centers it at 2000th pixel so user have to scroll to see it.
What I did wrong here?
position:fixed;
_position:absolute;
top: 50%;
right: 0;
You could do this with javascript. Here's an example, using jQuery, that I would try:
var calculatedTop = $(window).innerHeight() / 2;
$('#YourDiv').css('top', calculatedTop);
Edit: I've expanded this a bit to recalculate the top position when the user scrolls. Hopefully this helps with your IE8 problem.
$(document).ready(function(){
var reposition = function() {
var calculatedTop = $(window).innerHeight() / 2;
calculatedTop += $(document).scrollTop();
$('#YourDiv').css('top', calculatedTop);
}
// call reposition immediately on initial load
reposition();
// attach to scroll event
$(window).on('scroll', function(){
reposition();
});
});
I have a <select> box with many options, and you can scroll through these. When you scroll to the bottom of the options list and continue scrolling, the scrolling "overflows" into the parent window, and scrolls the window down instead. Is there a way to turn this off, i.e. when you scroll to the bottom scrolling down is disabled?
Here is a fiddle. To get the effect I describe, mouse over the multiple select and scroll down (using the trackpad, scroll wheel, etc) to the bottom, then continue scrolling. The entire page will scroll. My desired behavior is for the entire page not to scroll when you reach the bottom of the select options.
The only way to achieve what you want is to use javascript. The logic is pretty simple, on hover, you can add overflow: hidden; to the body, then onblur of the select element, you remove the overflow value.
The code would look something like this (give your select box an id of selectbox):
document.getElementById('selectbox').onmouseenter = function(){
document.body.style.overflow = 'hidden';
};
document.getElementById('selectbox').onmouseout = function(){
document.body.style.overflow = 'auto';
};
demo: http://jsfiddle.net/LRCKn/6/ - you just need to get it to apply the css change on the options elements as well.
I have a mobile website that has a main wrapper with three divs inside - all are fixed height which add up to 480px total. The top two divs inside are headers which are pretty short, and the bottom one is where the main content is and has an overflow-y of scroll. I set the html and body to overflow-y:hidden. I want only the main content div to scroll vertically and absolutely nothing else, leaving the headers always visible in full.
When I view it in my desktop browser it works fine. In my iPhone simulator it scrolls correctly if I click and drag within that content div, but if I click and drag from one of the headers or I swipe with two fingers on my trackpad it scrolls the whole page, not just the content. This results in the top header getting scrolled off the page. I don't have a real iphone to test with, but I am told by my client that the same thing happens on her iphone.
I tried setting the height of the main wrapper to something very short (300px) so in theory there shouldn't be any need to scroll the page at all regardless of the overflow setting, but it still scrolls. I also tried visiting this very short page and even there in the simulator it scrolls a little. I also tried setting my headers to position:fixed but no luck.
How can I get the page to stop scrolling away from the headers?
You could bind a "touchmove" event to the two other divs, and use prevent default.
<div id="main-wrapper">
<div id="header"></div>
<div id="content"></div>
<div id="footer"></div>
</div>
The use jQuery and
jQuery(function($) {
$("#header").on(‘touchmove’, function(e) { e.preventDefault() });
$("#footer").on(‘touchmove’, function(e) { e.preventDefault() });
}
This will prevent the browser from doing it’s default behaviour.