In the last few weeks Google show a carousel for Stack Overflow
result, It's awesome and move smooth but weird for me, there is no JavaScript
DOM
changing and even CSS
that cause to horizontal scroll, I cannot find it out.
Even I read about CSS Horizontal Scroll
but it is so different and it is just for Google Chrome
in other browsers it doesn't exist.
After some searches and experiments I found out this weird carousel is actually a long horizontal division with display: none
scroll bar, but how with grab
and moving mouse pointer, the division scroll moving? is that a native chrome trick? or just use JavaScript
to calculate the motion of horizontal scroll?
Actually, I have found the answer to my question, but I decided to post it here now. Google website developers use many sexy tricks to implement the UI and this carousel is one of them, definitely, this is not DOM
manipulation, it's a simple scrolled division. Because of this, the division moves very smoothly and even with dragging move properly.
A scroll has some native behavior in some devices like Apple devices or other touch devices, even Microsoft new laptops have some features about scrolling by touch. but if we use a few JavaScript
codes to handle dragging it will be nice, see following code:
HINT: You can use your native device horizontal scrolling features like the two-finger horizontal scroll on MacBook trackpad OR using click and drag to move the carousel horizontally
var slider = document.querySelector('.items');
var isDown = false;
var startX;
var scrollLeft;
slider.addEventListener('mousedown', function (e) {
isDown = true;
slider.classList.add('active');
startX = e.pageX - slider.offsetLeft;
scrollLeft = slider.scrollLeft;
});
slider.addEventListener('mouseleave', function () {
isDown = false;
slider.classList.remove('active');
});
slider.addEventListener('mouseup', function () {
isDown = false;
slider.classList.remove('active');
});
slider.addEventListener('mousemove', function (e) {
if (!isDown) return;
e.preventDefault();
var x = e.pageX - slider.offsetLeft;
var walk = (x - startX) * 3; //scroll-fast
slider.scrollLeft = scrollLeft - walk;
});
@import url(https://fonts.googleapis.com/css?family=Rubik);
body,
html {
color: #fff;
text-align: center;
background: #efefef;
font-family: Helvetica, sans-serif;
margin: 0;
}
.grid-container {
background: #efefef;
font-family: 'Rubik', sans-serif;
}
@supports (display: grid) {
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas: "header header header" "title title footer" "main main main";
}
@media screen and (max-width: 500px) {
.grid-container {
grid-template-columns: 1fr;
grid-template-rows: 0.3fr 1fr auto 1fr;
grid-template-areas: "header" "title" "main" "footer";
}
}
.grid-item {
color: #fff;
background: skyblue;
padding: 3.5em 1em;
font-size: 1em;
font-weight: 700;
}
.header {
background-color: #092a37;
grid-area: header;
padding: 1em;
}
.title {
color: #555;
background-color: #f4fbfd;
grid-area: title;
}
.main {
color: #959595;
background-color: white;
grid-area: main;
padding: 0;
overflow-x: scroll;
overflow-y: hidden;
}
.footer {
background-color: #5bbce4;
grid-area: footer;
padding: 0.6em;
}
.items {
position: relative;
width: 100%;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
transition: all 0.2s;
transform: scale(0.98);
will-change: transform;
user-select: none;
cursor: pointer;
}
.items.active {
background: rgba(255, 255, 255, 0.3);
cursor: grabbing;
cursor: -webkit-grabbing;
transform: scale(1);
}
.item {
display: inline-block;
background: skyblue;
min-height: 100px;
min-width: 400px;
margin: 2em 1em;
}
@media screen and (max-width: 500px) {
.item {
min-height: 100px;
min-width: 200px;
}
}
}
a {
display: block;
color: #c9e9f6;
text-decoration: underline;
margin: 1em auto;
}
a:hover {
cursor: pointer;
}
p {
text-align: left;
text-indent: 20px;
font-weight: 100;
}
i {
color: skyblue;
}
<div class="grid-container">
<main class="grid-item main">
<div class="items">
<div class="item item1"></div>
<div class="item item2"></div>
<div class="item item3"></div>
<div class="item item4"></div>
<div class="item item5"></div>
<div class="item item6"></div>
<div class="item item7"></div>
<div class="item item8"></div>
<div class="item item9"></div>
<div class="item item10"></div>
</div>
</main>
</div>
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments