Reputation: 1999
I have a large vertically scrolling element and inside that, I have a smaller horizontally scrolling element. (See the snippet)
body {
height: 100vh;
overflow: hidden;
}
.large {
height: 100%;
font-size: 32px;
overflow-y: scroll;
}
.tall {
height: 120%;
}
.small {
width: 100%;
overflow-x: scroll;
white-space: no-wrap;
}
.wide {
width: 120%;
}
<body>
<div class="large">
This is large content vertical content
<br><hr><br>
<div class="small">
<div class="wide">This is smaller horizontal content</div>
</div>
<div class="tall"></div>
</div>
</body>
When you hover it, the large vertical scrolls vertically fine, but I'd like it when you hover the horizontal content, for it to scroll automatically, so the user does not have to manually drag the scroll bar to scroll. Any way to do this with HTML, CSS or JavaScript?
I'd like for the horizontal scroll to be controlled by the scroll wheel, not at a consistent rate, if possible.
Upvotes: 3
Views: 3671
Reputation: 2832
If you want to do this in plain JavaScript, adjust the scrollLeft gradually across an interval while your mouse is in .small
. I also added a reset function when you leave .small
because I thought it made for a better user experience.
var scrollInterval = null;
function scrollElement(ele) {
scrollInterval = setInterval(function() {
ele.scrollLeft += 1;
}, 1);
}
function reset(ele) {
clearInterval(scrollInterval);
ele.scrollLeft = 0;
}
body {
height: 100vh;
overflow: hidden;
}
.large {
height: 100%;
font-size: 32px;
overflow-y: scroll;
}
.tall {
height: 120%;
}
.small {
width: 100%;
overflow-x: scroll;
white-space: no-wrap;
}
.wide {
width: 120%;
}
<div class="large">
This is large content vertical content
<br>
<hr><br>
<div class="small" onmouseenter="scrollElement(this);" onmouseleave="reset(this);">
<div class="wide">This is smaller horizontal content</div>
</div>
<div class="tall"></div>
</div>
If you'd rather the scroll be controlled by the mouse wheel instead of automatic, you can do that like this:
function scrollHorizontally(e) {
e = window.event || e;
var delta = e.wheelDelta || -e.detail;
document.getElementsByClassName('small')[0].scrollLeft -= delta; // Multiplied by 40
e.preventDefault();
}
function bindHorizontalMouseWheel(ele) {
if (ele.addEventListener) {
// IE9, Chrome, Safari, Opera
ele.addEventListener("mousewheel", scrollHorizontally, false);
// Firefox
ele.addEventListener("DOMMouseScroll", scrollHorizontally, false);
} else {
// IE 6/7/8
ele.attachEvent("onmousewheel", scrollHorizontally);
}
}
window.addEventListener('load', function() {
bindHorizontalMouseWheel(document.getElementsByClassName('small')[0]);
});
body {
height: 100vh;
overflow: hidden;
}
.large {
height: 100%;
font-size: 32px;
overflow-y: scroll;
}
.tall {
height: 120%;
}
.small {
width: 100%;
overflow-x: scroll;
white-space: no-wrap;
}
.wide {
width: 120%;
}
<div class="large">
This is large content vertical content
<br>
<hr><br>
<div class="small">
<div class="wide">This is smaller horizontal content</div>
</div>
<div class="tall"></div>
</div>
Credit to this post for some of this code.
Upvotes: 3
Reputation: 431
CSS only solution. I've included both CSS3 animation and transition versions. Use whatever you like.
body {
height: 100vh;
overflow: hidden;
}
.large {
height: 100%;
font-size: 32px;
overflow-y: scroll;
}
.tall {
height: 120%;
}
.small {
width: 100%;
height: 1.5em;
line-height: 1.5;
position: relative;
}
.wide {
white-space: nowrap;
font-size: 1em;
position: absolute;
top: 0;
}
.wide1:hover {
animation: 3s autoscroll linear;
animation-fill-mode: forwards;
}
@keyframes autoscroll {
from {
left: 0;
transform: translateX(0);
}
to {
transform: translateX(-100%);
left: 100%;
}
}
.wide2 {
left: 0;
transform: translateX(0);
transition: all 3s ease;
}
.wide2:hover {
transform: translateX(-100%);
left: 100%;
}
<body>
<div class="large">
This is large content vertical content
<br><hr><br>
<div class="small">
<div class="wide wide1">This is smaller horizontal content This is smaller horizontal content This is smaller horizontal content</div>
</div>
<div class="small">
<div class="wide wide2">This is smaller horizontal content This is smaller horizontal content This is smaller horizontal content</div>
</div>
<div class="tall"></div>
</div>
</body>
Upvotes: 1