Slider activation causing sudden vertical scroll

So, I have this slider where everytime I click the slider-nav to change images, the viewport top automatically aligns with the product-slider-wrapper top. Basically, causes an abrupt vertical scroll to align their tops everytime you scroll between images with a click. The image with the front view of the glasses is what happens after I click one of the slider-nav links. What I've already tried to solve it, but failed:
html {
scroll-behavior: auto;
}
html {
scroll-behavior: auto;
}
:target {
position: relative;
top: 0;
}
:target {
position: relative;
top: 0;
}
The HTML is with the images, since the message was too long and I couldn't post it.
The CSS:
.product-page-item {
display: flex;
gap: 5rem;
padding: 5rem 0 0 0;
}

.product-slider-wrapper {
position: relative;
/* max-width: 48rem; */
border: solid 1px var(--clr-neutral-600);
border-radius: 20px;
z-index: 1;
}

.product-slider {
display: flex;
aspect-ratio: 1 / 1;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
border-radius: 1rem;
-ms-overflow-style: none; /* hide scrollbar IE and Edge */
scrollbar-width: none; /* hide scrollbar Firefox */
}

/* Hide scrollbar for Chrome, Safari and Opera */
.slider::-webkit-scrollbar {
display: none;
}

.product-slider img {
flex: 1 0 100%; /* flex grow, flex shrink, flex basis */
scroll-snap-align: start;
object-fit: cover;
border-radius: 20px;
}

.slider-nav {
display: flex;
column-gap: 1rem;
position: absolute;
bottom: 1.25rem;
left: 50%;
transform: translateX(-50%);
z-index: 1;
}

.slider-nav a {
width: 0.75rem;
height: 0.75rem;
border-radius: 50%;
background-color: var(--clr-neutral-900);
opacity: 0.5;
transition: opacity ease 250ms;
}

.slider-nav a:hover {
opacity: 1;
}
.product-page-item {
display: flex;
gap: 5rem;
padding: 5rem 0 0 0;
}

.product-slider-wrapper {
position: relative;
/* max-width: 48rem; */
border: solid 1px var(--clr-neutral-600);
border-radius: 20px;
z-index: 1;
}

.product-slider {
display: flex;
aspect-ratio: 1 / 1;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
border-radius: 1rem;
-ms-overflow-style: none; /* hide scrollbar IE and Edge */
scrollbar-width: none; /* hide scrollbar Firefox */
}

/* Hide scrollbar for Chrome, Safari and Opera */
.slider::-webkit-scrollbar {
display: none;
}

.product-slider img {
flex: 1 0 100%; /* flex grow, flex shrink, flex basis */
scroll-snap-align: start;
object-fit: cover;
border-radius: 20px;
}

.slider-nav {
display: flex;
column-gap: 1rem;
position: absolute;
bottom: 1.25rem;
left: 50%;
transform: translateX(-50%);
z-index: 1;
}

.slider-nav a {
width: 0.75rem;
height: 0.75rem;
border-radius: 50%;
background-color: var(--clr-neutral-900);
opacity: 0.5;
transition: opacity ease 250ms;
}

.slider-nav a:hover {
opacity: 1;
}
Can someone, please, help me? 🥲
No description
No description
No description
6 Replies
ἔρως
ἔρως7d ago
probably the overflowing element isn't the html document, but something else without seeing the actual website, or a replica of the problem, this is all i can say
Chris Bolson
Chris Bolson6d ago
#target will automatically scroll (or jump) the browser to the top of the target element. You can offset this with scroll-padding-top . As Epic says, without seeing some working code it is difficult to know what is actually happening.
clevermissfox
clevermissfox6d ago
Fairly sure Chris means :target not #target unless there's an ID in the code screenshot I'm not seeing. :target pseudo-class refers to the target element. I always forget when to use scroll margin vs scroll padding , guess it just depends on the use case and whether you'll need it isolated or want a global scroll padding on your scroller. - scroll margin is set on the :target or the scroll items - and scroll padding is set on the html or the scroll container - can assign all sides or just the top eg
.scroll-container {
scroll-padding-block-start: 1em;
}
:target {
scroll-margin-block-start: 1em;
}

.scroll-container {
scroll-padding-block-start: 1em;
}
:target {
scroll-margin-block-start: 1em;
}

Chris Bolson
Chris Bolson6d ago
no, I did mean #target. The code is sliding the images using href #slide-1 and #slide-2 But you are right in that the "targeted" element can be selected using the :target selector, however bear in mind that that will then set the property for all of the "targets" on the page, not just the images in question which might not be what you want. This can of course be refined to only select the images. Just to clarify, by saying "#target" I was really referring to any href with a "#" link (in this case #slide-1 and #slide-2) - sorry for any confusion
clevermissfox
clevermissfox6d ago
Aha , apologies I was reading tje comment in terms of css so was looking for an element with an ID value literally of #target 😆 carry on ! and good point , :target is global for ANY target , but can get more specific to only add scroll-margin on the images in question (.product-slider img:target) or just set scroll-padding on the parent scroller
Rebeca
RebecaOPthis hour
Thank you for the replies! I couldn't quite fix it using only CSS, so I added some JS and it worked. I figured that what was causing the problem was the .slider-nav links, because they were changing the url when I clicked to scroll the images, and it caused the sudden vertical scroll. So I added some JS to stop the url from changing. I don't know if there's some easier way to solve this, but it's working now! HTML and CSS remain the same, but here's the JS I added:
document.addEventListener("DOMContentLoaded", function () {
const slider = document.querySelector(".product-slider");
const navLinks = document.querySelectorAll(".slider-nav a");

navLinks.forEach((navLink, index) => {
navLink.addEventListener("click", function (event) {
event.preventDefault(); // blocks url changes
slider.scrollTo({
left: slider.clientWidth * index,
behavior: "smooth"
});
});
});
});
document.addEventListener("DOMContentLoaded", function () {
const slider = document.querySelector(".product-slider");
const navLinks = document.querySelectorAll(".slider-nav a");

navLinks.forEach((navLink, index) => {
navLink.addEventListener("click", function (event) {
event.preventDefault(); // blocks url changes
slider.scrollTo({
left: slider.clientWidth * index,
behavior: "smooth"
});
});
});
});

Did you find this page helpful?