Don't allow horizontal scroll when scrolling vertically (and vice versa) - javascript

I have a list, with the overflow-x and overflow-y set to auto. In addition, I've set up momentum scroll, so the touch scrolling works nice in mobile, using webkit-overflow-scrolling: true.
The issue, however, is that I cannot figure out how to disable the horizontal scroll when scrolling vertically. It leads to really bad user experience, as the swiping towards the top left or top right will cause the table to scroll diagonally. When the user is scrolling vertically, I absolutely do NOT want any scrolling horizontally until the user has stopped scrolling vertically.
I've tried the following:
JS:
offsetX: number;
offsetY: number;
isScrollingHorizontally = false;
isScrollingVertically = false;
//Detect the scrolling events
ngOnInit() {
this.scrollListener = this.renderer.listen(
this.taskRows.nativeElement,
'scroll',
evt => {
this.didScroll();
}
);
fromEvent(this.taskRows.nativeElement, 'scroll')
.pipe(
debounceTime(100),
takeUntil(this.destroy$)
)
.subscribe(() => {
this.endScroll();
});
}
didScroll() {
if ((this.taskRows.nativeElement.scrollLeft != this.offsetX) && (!this.isScrollingHorizontally)){
console.log("Scrolling horizontally")
this.isScrollingHorizontally = true;
this.isScrollingVertically = false;
this.changeDetectorRef.markForCheck();
}else if ((this.taskRows.nativeElement.scrollTop != this.offsetY) && (!this.isScrollingVertically)) {
console.log("Scrolling Vertically")
this.isScrollingHorizontally = false;
this.isScrollingVertically = true;
this.changeDetectorRef.markForCheck();
}
}
endScroll() {
console.log("Ended scroll")
this.isScrollingVertically = false;
this.isScrollingHorizontally = false;
this.changeDetectorRef.markForCheck();
}
HTML:
<div
class="cu-dashboard-table__scroll"
[class.cu-dashboard-table__scroll_disable-x]="isScrollingVertically"
[class.cu-dashboard-table__scroll_disable-y]="isScrollingHorizontally"
>
CSS:
&__scroll {
display: flex;
width: 100%;
height: 100%;
overflow-y: auto;
overflow-x: auto;
will-change: transform;
-webkit-overflow-scrolling: touch;
&_disable-x {
overflow-x: hidden;
}
&_disable-y {
overflow-y: hidden;
}
}
But the everytime I set overflow-x or overflow-y to hidden when its been scrolled, scrolling will glitch and jump back to the top. I've also noticed that webkit-overflow-scrolling: true is the reason why this occurs, when I remove it, the behavior seems to stop, but I absolutely need this for momentum scrolling in mobile devices.
How do I disable horizontal scroll when scrolling vertically?

It's generally a bad practice for your design to need multiaxis scrolling on mobile, unless maybe you're showing big tables of data. That being said, why do you want to prevent it? If a user wants to scroll diagonally, that doesn't seem like the end of the world to me. Some browsers, like Chrome on OSX, already do what you're describing by default.
If you must have single-axis scrolling, a possible solution might be to keep track of the scroll position yourself via touchstart and touchmove events. If you set your drag threshold lower than the browser's, you may be able to do your css stuff before it starts scrolling, avoiding the perceived glitch. Also, even if it does still glitch, you have the touch start and the touch's current location. From these, if you record your div's starting scroll position, you can manually scroll the div to the correct place to counteract it jumping to the top if you have to. A possible algorithm might look like this:
// Touchstart handler
if (scrollState === ScrollState.Default) {
// Record position and id of touch
touchStart = touch.location
touchStartId = touch.id.
scrollState = ScrollState.Touching
// If you have to manually scroll the div, first store its starting scroll position:
containerTop = $('.myContainer').scrollTop();
containerLeft = $('.myContainer').scrollLeft();
}
// Touchmove handler - If the user has dragged beyond a distance threshold,
// do the css classes swap.
if (touch.id === touchStartId && distance(touchStart, touch.location > threshold) {
scrollState = ScrollState.Scrolling;
swapCssClasses();
// If you have to manually scroll the div to prevent jump:
$('.myContainer').scrollTop(containerTop + (touch.location.y - touchStart.y));
// Do the same for horizontal scroll.
}
// Then, listen for debounced scroll events, like you're already doing,
// to reset your state back to default.
Second idea: in your scroll handler, instead of changing the css classes, set the scroll position of the div directly for the axis you want locked. IE, if you're scrolling horizontally, always set the scrollTop to its starting value. This might also cancel scrolling, not sure. You'd have to try it to see if it works.

Try this
HTML
<div
class="cu-dashboard-table__scroll-vertical"
>
<div
class="cu-dashboard-table__scroll-horizontal"
>
<!-- Scroll content here -->
</div>
</div>
CSS
&__scroll {
&-horizontal {
overflow-x: auto;
width: 100%;
-webkit-overflow-scrolling: touch;
}
&-vertical {
overflow-y: auto;
height: 100%;
-webkit-overflow-scrolling: touch;
}
}
Instead of using one div for scrolling, why dont you use two? Have one for X and one for Y

Need to use three containers.
In the first container I enable vertical scrolling and disallow horizontal.
In the second, vice versa, I enable horizontal scrolling and disallow vertical.
Be sure to use overflow-x: hidden; and overflow-y: hidden;, otherwise child containers may go beyond the current container.
Also need to use min-width: 100%; min-height: 100%;.
For the third container we need to use display: inline-block; and then the internal content will stretch this container and the corresponding scroll bars will appear on the two parent blocks.
HTML
<div class="scroll-y">
<div class="scroll-x">
<div class="content-container">
<!-- scrollable content here -->
</div>
</div>
</div>
CSS
.scroll-y {
position: absolute;
overflow-x: hidden;
overflow-y: auto;
width: 100%;
height: 100%;
min-width: 100%;
min-height: 100%;
}
.scroll-x {
overflow-y: hidden;
overflow-x: auto;
width: auto;
min-width: 100%;
min-height: 100%;
}
.content-container {
min-width: 100%;
min-height: 100%;
display: inline-block;
}
You can test it here in Safari on iPhone.
Good luck!! 😉

There are numerous ways to try to solve this. Some good ideas are offered here.
However, as others have alluded, relying on (or trying to avoid) multi-dimensional scrolling is a bad UX smell - indicative of the UX being a problem. I don't think this is a legitimate dev issue. It would be better to take a step back and reevaluate what you're trying to accomplish. One of the issues might be that in an effort to make the UI more usable, you'll be confusing users. The usability described here would likely cause confusion.
Why can't I scroll horizontally?
Why when I stop scrolling vertically, only then can I scroll horizontally?
These are some questions that may be asked (inaudible).
If you're trying to allow for additional information of the vertical data list to be browsable only when the user has selected the row, it would likely be much better to simply have a flat list by default only scrollable vertically, and only toggle the vertical information when the "row" has been selected/activated. Collapsing the details would get you back to the flat vertical list.
If you're having to jump through hoops to solve such a fringe technical challenge, it's a good indication that the user experience has not been designed well to begin with.

this looks like fun ;)
I won't argue about if it's reasonable.
I tried it with RxJS:
ngAfterViewInit() {
const table = document.getElementById("table");
const touchstart$ = fromEvent(table, "touchstart");
const touchmove$ = fromEvent(table, "touchmove");
const touchend$ = fromEvent(table, "touchend");
touchstart$
.pipe(
switchMapTo(
touchmove$.pipe(
// tap(console.log),
map((e: TouchEvent) => ({
x: e.touches[0].clientX,
y: e.touches[0].clientY
})),
bufferCount(4),
map(calculateDirection),
tap(direction => this.setScrollingStyles(direction)),
takeUntil(touchend$)
)
)
)
.subscribe();
}
We buffer every 4th touchemove event and then make some highly sophisticated calculation with the coordinates of the four events (map(calculateDirection)) which outputs RIGHT, LEFT, UP or DOWN and based on that I try to disable vertical or horicontal scrolling. On my android phone in chrome it kind of works ;)
I'v created a little playground, which could be enhanced, rewritten, whatsoever ...
Cheers Chris

Related

How to detect scroll direction when content changes height on scroll

It's quite straightforward to detect the scroll direction when scrolling page with static size. But if one of the elements is a sticky header and changes the height while scrolling it keeps changes pageYOffset and enters into infinite loop jumping up and down.
Example sandbox where if you scroll to the point were it starts shrinking it starts jumping.
Some possible solution I've came up with was to add a spacer which would compensate when the sticky navigation gets smaller. But that requires doing it in the actual component. Wondering if there is a way to do it with js only in the useScrollDirection hook.
One of the other things I've tried was to use document.documentElement.scrollHeight and check for the size change, that didn't help as well.
Just a suggestion. I think you are underutilizing position: sticky. You don't need an event listener to achieve the behavior you want. You can do this entirely with CSS and let the browser handle everything for you.
.app {
font-family: sans-serif;
text-align: center;
height: 300vh;
}
.nav {
position: sticky;
top: -120px;
height: 150px;
background: aquamarine
}
.nav_item {
position: sticky;
top: 0px;
margin: 0;
}
<div class="app">
<h1>Hello CodeSandbox</h1>
<nav class="nav">
<p class="nav_item">Hello</p>
</nav>
<h2>Start editing to see some magic happen!</h2>
</div>
I encountered the same problem and a co-worker recommended me to listen to the wheel event. So I implemented the following react hook:
const useLastMouseWheelDirection = () => {
const [lastMouseWheelDirection, setLastMouseWheelDirection] = useState(
undefined
)
useEffect(() => {
const handler = (event) => {
setLastMouseWheelDirection(event.deltaY >= 0 ? 'down' : 'up')
}
window.addEventListener('wheel', handler)
return () => window.removeEventListener('wheel', handler)
}, [])
return lastMouseWheelDirection
}
This solution has some serious limitations:
Obviously touch events are ignored
Clicking and dragging the scroll bar will not fire the event
Also a side effect to the desired behavior would be that it wouldn't take into consideration if the element is even overflowing or not, although the hook could be extended to catch this case.
Further more the MDN Web Docs state:
Note: Don't confuse the wheel event with the scroll event. The default action of a wheel event is implementation-specific, and doesn't necessarily dispatch a scroll event. Even when it does, the delta* values in the wheel event don't necessarily reflect the content's scrolling direction. Therefore, do not rely on the wheel event's delta* properties to get the scrolling direction. Instead, detect value changes of scrollLeft and scrollTop of the target in the scroll event.
So please take this answer with a grain of salt.

Resize content when drawer is open in MDL

I'm building a website based on MDL. What I'm trying to achieve is that the drawer doesn't open over the content, but open next to it. I managed to disable the obfuscator and modify the top value.
However, the way I was going to do this is anytime the drawer opens the content area would get a 250px wide left margin (the drawer is 250px wide) and resize its width so that width: calc(100% - 250px). This works just fine, but I don't know if this is the best way to do it, and even if it is, I don't know how to track the state of the drawer.
Here's how the material.js handles the change:
MaterialLayout.prototype.screenSizeHandler_ = function () {
if (this.screenSizeMediaQuery_.matches) {
this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN);
} else {
this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN);
// Collapse drawer (if any) when moving to a large screen size.
if (this.drawer_) {
this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
}
}
};
This is beyond my skills to figure out what is actually going on. I tried tracking it down with Chrome, but it was too complicated.
Is there a trivial way to do this? If not, how do I edit the script?
Cheers!
The .mdl-layout__drawer receives a .is-visible class when it is open/visible.
This small CSS-Rule worked for me:
.mdl-layout__drawer.is-visible ~ .mdl-layout__content {
padding-left: 250px;
}
With this you also don't need to fix the width of the content-area, as you are not using margin but padding. Note that by default the material.css also disables scrolling when the drawer is visible, so you also need to add the overflow-property to the rule:
.mdl-layout__drawer.is-visible ~ .mdl-layout__content {
overflow: auto !important;
padding-left: 250px;
}

How to prevent swipe after an element has been repositioned by a transition

I've created a hidden sidebar navigation menu which, when made visible - moves the site-wrap (main content of the page) to the right to expose the menu:
.nav-trigger:checked + label, .nav-trigger:checked ~ .site-wrap {
left: 16.5em;
}
This all works as I would hope, but the problem is one that arises on mobile, when the user begins trying to swipe around the page. If you touch the left edge of the site wrap and drag it to the left, it scrolls the page in that direction - as if it was dragging the site wrap back across the navigation element behind it.
I have tried adding two variations of overflow hidden to body, but this has no effect:
body{
background: #bodyColor;
color: #headerColor;
font-family: #openSans;
font-size: 16px;
overflow-x: hidden;
overflow: hidden;
}
I did add the following jquery which prevented touch gestures entirely:
var touchDisabled = false;
$("#nav-trigger").click(function(){
if( touchDisabled == false ){
$(document).bind('touchmove', function(e) {
e.preventDefault();
});
touchDisabled = true;
}else{
$(document).unbind('touchmove');
touchDisabled = false;
}
});
but this is not the ideal situation as I'd like to retain vertical scroll if possible, and prevent horizontal scroll/swipe/drag/whatever-you-want-to-call-it.
Part of the reason I'm struggling to solve this is because I'm not entirely sure what to search for, it doesn't seem to be a scroll in the traditional sense, more dragging the div around the page.
The link to demonstrate the problem is:
http://streeten-new.streeten.co.uk/
(obviously only recreatable on mobile). I hope this helps to illustrate the problem as it's not the easiest of things for me to explain in words.
* 12/08 update *
Still having this problem unfortunately.
The problem also manifests itself in both the site-wrap and the .navigation scrolling at the same time as you swipe up on mobile. I would like to be able to tell site-wrap to just stay in place and don't move an inch, no matter how you swipe, and just allow vertical scroll/swipe in the navigation menu.
I've made it so that when you open the menu, overflow: hidden is being added to body and overflow: auto is being added to the navigation. This works perfectly on desktop! When you scroll, only the nav moves and the body is completely frozen. But on mobile it seems to have absolutely no effect.
$("#hamburger").click(toggleMenu);
var menuOpen = false;
function toggleMenu(){
$(".site-wrap, header").toggleClass("slideRight");
$(".navCover").toggleClass("slideRight");
$("#logo").toggleClass("slideLeft");
$("body, #fouc").toggleClass("preventScroll");
$(".navigation").toggleClass("allowScroll");
window.setTimeout(function(){
$("header button").toggleClass("slideLeft");
}, 250);
if (menuOpen == true){
menuOpen = false;
}else{
menuOpen = true;
}
}
.preventScroll{
overflow: hidden;
}
.allowScroll{
overflow: auto;
}
Any help much appreciated.
I have now (mostly) resolved this. I think the edit I made is another issue which I will raise separately.
For the benefit of others who may read this, in order to prevent the site-wrap container from being "swipeable" for want of a better word - whereby it was possible to drag it around the screen in every direction after it had been repositioned on opening the navigation menu - I had to use overflow: hidden
I had initially tried this, but where I went wrong was applying it to the body, which according to this thread doesn't work on mobile:
Overflow-x:hidden doesn't prevent content from overflowing in mobile browsers
I added another div within body, containing all my content and applied overflow: hidden to both body and this new div (belt and braces), which then resolved the issue.
Now when the site-wrap has been shifted to the right after clicking the hamburger icon, it is impossible to drag/swipe it around the screen on mobile.

Dispatch mouse wheel event on another DOM element

I have a web page with scrollable div on it.
On top of scrollable div I have absolutely positioned div that overlaps half of scrollable div.
When I put mouse cursor over scrollable div I can scroll it with mouse wheel. But when I move cursor over overlapping div then mouse wheel stops scroll that div (and this is correct behavior because absolute positioned div is not inside scrollable div).
Question: how to pass or dispatch scroll event received by absolute positioned div to this underlying scrollable div to make this absolute positioned div 'transparent' for mouse wheel events.
I could get it work in Chrome, but not in IE and Firefox. How to rewrite this code to get it work in IE and Firefox?
if ($.browser.webkit) {
$(".overlap-container").bind("mousewheel", function (e) {
var origEvent = e.originalEvent;
var evt = document.createEvent("WheelEvent");
evt.initWebKitWheelEvent(
origEvent.wheelDeltaX,
origEvent.wheelDeltaY,
window,
0,
0,
0,
0,
origEvent.ctrlKey,
origEvent.altKey,
origEvent.shiftKey,
origEvent.metaKey);
$(".scroll-container").get(0).dispatchEvent(evt);
});
}
See example here:
http://jsfiddle.net/HAc4K/5
EDITED: This issue originally is from jqGrid - frozen columns don't react mouse wheel scrolling.
In Chrome and Firefox awesome CSS property is supported: pointer-events:none
Looks like a known issue with jQuery: OriginalEvent not supported in IE
The short answer: you use wrong parameters of initWheelEvent in the demo in case of usage Internet Explorer. The method should have 16 parameters described in the documentation. Yo use currently only 11 parameters the same which have initWebKitWheelEvent, but the meaning of all parameters of initWheelEvent is absolutely another. You have to fix the parameters of initWheelEvent.
Use RetargetMouseScroll(overlap container, scroll container).
I realize this isn't exactly what you're looking for, but at least in Chrome, IE7+, and Firefox 3.5+ this does what you ask - scroll the underlying div when the div overlaying it receives scroll events:
http://jsfiddle.net/b9chris/yM3qs/
It's doing so simply because the overlapping div is a child of the div it overlaps - no jquery passing on any mousewheel events (although it is listening to scroll to ensure the overlapping div stays where it needs to be).
Implementing that kind of workaround in jqGrid might require upending a fair bit of code there, however.
HTML:
<div id=under>
(content goes here)
<div id=over></div>
</div>
CSS:
#under {
position: absolute;
left: 0; top: 0;
width: 220px; height: 200px;
overflow-y: scroll;
}
#over {
position: absolute;
left: 1px; top: 100px;
width: 200px; height: 100px;
z-index: 2;
}
JS:
(function() {
$('#under').on('scroll', function() {
$('#over').css('top', $(this).scrollTop() + 100);
});
})();
Here's the 2019 solution for overlapped container to get wheel event:
document.querySelector('.overlap').on('wheel', (e) => {
const overlap = e.target
overlap.style.pointerEvents = 'none'
setTimeout(() => {overlap.style.pointerEvents = 'auto'}, 0)
})
This way the overlapped element gets wheel event from the overlapping element called .overlap.

How can I disable a browser or element scrollbar, but still allow scrolling with wheel or arrow keys?

I want to hide any scrollbars from my div elements and my whole body, but still let the user scroll with the mouse wheel or arrow keys. How can this be achieved with raw JavaScript or jQuery? Any ideas?
Like the previous answers, you would use overflow:hidden to disable the scrollbars on the body/div.
Then you'd bind the mousewheel event to a function that would change the scrollTop of the div to emulate scrolling.
For arrow keys, you would bind the keydown event to recognize an arrow key, and then change scrollTop and scrollLeft of the div as appropriate to emulate scrolling.
(Note: you use keydown instead of keypress since IE doesn't recognize keypress for arrow keys.)
Edit: I couldn't get FF/Chrome to recognize keydown on a div, but it works in IE8. Depending on what you needed this for, you can set a keydown listener on the document to scroll the div. (Check out the keyCode reference as an example.)
For example, scrolling with the mouse wheel (using jQuery and a mousewheel plugin):
<div id="example" style="width:300px;height:200px;overflow:hidden">
insert enough text to overflow div here
</div>
<script>
$("#example").bind("mousewheel",function(ev, delta) {
var scrollTop = $(this).scrollTop();
$(this).scrollTop(scrollTop-Math.round(delta));
});
</script>
(This is a quick mockup, you'd have to adjust the numbers since for me, this scrolls a bit slowly.)
keyCode reference
mousewheel plugin
keydown, keypress # quirksmode
Update 12/19/2012:
The updated location of the mousewheel plugin is at: https://github.com/brandonaaron/jquery-mousewheel
What about a purely CSS solution?
Solution 1 (cross browser but more hacky)
#div {
position: fixed;
right: -20px;
left: 20px;
background-color: black;
color: white;
height: 5em;
overflow-y: scroll;
overflow-x: hidden;
}
<html>
<body>
<div id="div">
Scrolling div with hidden scrollbars!<br/>
On overflow, this div will scroll with the mousewheel but scrollbars won't be visible.<br/>
Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>
</div>
</body>
</html>
Solution 2 (uses experimental features, may not support some browsers)
Just add the nobars class to any element you want to hide the scrollbars on.
.nobars {
/* Firefox: https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-width */
scrollbar-width: none;
/* IE: https://msdn.microsoft.com/en-us/library/hh771902(v=vs.85).aspx */
-ms-overflow-style: none;
}
.nobars::-webkit-scrollbar {
/* Chrome/Edge/Opera/Safari: https://css-tricks.com/custom-scrollbars-in-webkit/ */
display: none;
}
Solution 3 (cross browser javascript)
Perfect Scrollbar doesn't require jQuery (although it can utilise jQuery if installed) and has a demo available here. The components can be styled with css such as in the following example:
.ps__rail-y {
display: none !important;
}
Here is a complete example including the implementation of Perfect Scrollbar:
<link rel="stylesheet" href="css/perfect-scrollbar.css">
<style>
#container {
position: relative; /* can be absolute or fixed if required */
height: 200px; /* any value will do */
overflow: auto;
}
.ps__rail-y {
display: none !important;
}
</style>
<script src='dist/perfect-scrollbar.min.js'></script>
<div id="container">
Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>Scrollable<br>
</div>
<script>
// on dom ready...
var container = document.getElementById("container");
var ps = new PerfectScrollbar(container);
//ps.update(container);
//ps.destroy(container);
</script>
You dont have to use jquery or js to make this. Its more performant with simple webkit.
Just add the code below to your css file.
::-webkit-scrollbar {
display: none;
}
Caution !
This will disable all the scrollbar so be sure to put it in a specific class or id if you just want one to be hidden.
I much prefer SamGoody's answer provided to a duplicate of this question. It leaves native scrolling effects intact, instead of trying to manually re-implement for a few particular input devices:
A better solution is to set the target div to overflow:scroll, and wrap it inside a second element that is 8px narrower, who's overflow:hidden.
See the original comment for a fleshed-out example. You may want to use JavaScript to determine the actual size of scrollbars rather than assuming they are always 8px wide as his example does.
To get this working for me, I used this CSS:
html { overflow-y: hidden; }
But I had problems using $(this).scrollTop(), so I bound to my #id, but adjusted the scrollTop of window. Also, my smooth scrolling mouse would fire lots of 1 or -1 deltas, so I multiplied that by 20.
$("#example").bind("mousewheel", function (ev, delta) {
var scrollTop = $(window).scrollTop();
$(window).scrollTop(scrollTop - Math.round(delta * 20));
});
As Baldráni said above
::-webkit-scrollbar { display: none; }
Or you can do
::-webkit-scrollbar{ width: 0px; }
(posted for other people that stumble on this from google search!)
Well, perhaps not the most intuitive in my opinion, but I can imagine you being able to make it a decent experience, give this a try.
overflow:hidden;
make sure the parent object has a height and width, and displays as block

Categories