Quantcast
Channel: Active questions tagged flexbox - Stack Overflow
Viewing all articles
Browse latest Browse all 1675

How to restrict Slick slider dragging to a center zone only (disable drag from left/right edges)?

$
0
0

I'm using the Slick carousel library to display reviews loaded dynamically from a review.json file. The setup works well, including autoplay and infinite scroll.

However, I want to restrict dragging (mouse or touch) so that users can only start dragging the slider from the center 50% area of the .review-scroll-wrapper (where the grab cursor is visually shown). Dragging from the left and right edges should be completely disabled.

CSS complete review section.

/*Reviews/Testimony Section*/.reviews-section {  background-color: #0c1624; /* dark blue background */  color: white;  padding: 120px 20px;  /* text-align: right;  min-height: 250px; */}.reviews-container {  max-width: 1400px;  margin: -200px auto 0 auto; /* top -20px, horizontal auto, bottom 0 */}.review-title {  font-size: 45px;  font-weight: bold;  margin-bottom: 15px;  text-align: center;  font-family: 'Orbitron', sans-serif;}.review-title-gold {  color: #Efc900; /* bright gold */}.review-scroll-wrapper {  position: relative;  overflow: hidden;  cursor: grab;  overflow-x: auto;  scroll-behavior: smooth;  scrollbar-width: none;      /* Firefox */  -ms-overflow-style: none;   /* IE/Edge */  mask-image: linear-gradient(to right, transparent 0%, black 10%, black 90%, transparent 100%);  -webkit-mask-image: linear-gradient(to right, transparent 0%, black 10%, black 90%, transparent 100%);    /* For Chrome, Safari */&::-webkit-scrollbar {    display: none;  }}/* .review-scroll-wrapper:active {  cursor: grabbing;} *//* .card-holder {  display: flex;  gap: 30px;  width: max-content;  padding: 10px;} *//* Force Slick to respect your gap + card size */.slick-track {  display: flex !important;  gap: 30px !important;  padding: 10px !important;  margin-left: 0 !important; /* prevent centering */}.slick-slide {  height: auto !important;  display: flex !important;  justify-content: center; /* optional */}/* Optional: if Slick wrapper centers */#scrollCards.slick-slider {  text-align: left !important;}/* Optional: Hide flicker while Slick loads */#scrollCards {  visibility: visible;  opacity: 1;}.review-scroll-wrapper::before,.review-scroll-wrapper::after {  content: "";  position: absolute;  top: 0;  width: 60px;  height: 100%;  z-index: 2;  pointer-events: none;}.review-scroll-wrapper::before {  left: 0;  background: linear-gradient(to right, #0c1624, transparent);}.review-scroll-wrapper::after {  right: 0;  background: linear-gradient(to left, #0c1624, transparent);}.review-drag-zone {  position: absolute;  top: 0;  left: 25%;  width: 50%;  height: 100%;  z-index: 20;  cursor: grab;  pointer-events: auto;}.review-drag-zone:active {  cursor: grabbing;}.review-scroll-wrapper .slick-track {  cursor: default !important;}.review-card {  flex: 0 0 auto;               /* Prevent shrinking, enforce fixed width */  width: 320px;  background-color: #0d191f;  border: 1px solid #Efc900;  border-radius: 20px;  padding: 20px;  box-sizing: border-box;  display: flex;  flex-direction: column;  margin-top: 40px;  color: white;}/* Main layout: pic, text, and icon */.review-header {  display: flex;  align-items: flex-start;  position: relative;}/* Profile pic */.linkedin-pic {  flex-shrink: 0;}.pic-prof {  width: 50px;  height: 50px;  border-radius: 50%;}/* Name + role beside image */.review-info {  margin-left: 15px;}/* LinkedIn icon on top right */.linkpic-url {  position: absolute;  top: 0;  right: 0;}.linkedin-icon {  width: 50px;  height: 50px;}/* Name */.review-name {  font-size: 18px;  font-weight: bold;  margin: 0;  font-family: 'Times New Roman', sans-serif;}/* Role */.review-role {  font-size: 12px;  font-weight: bold;  margin-top: 5px;  color: #Efc900;  font-family: 'Times New Roman', sans-serif;}/* Quote */.review-text {  font-size: 16px;  margin-top: 25px;  color: #bbb;  font-family: 'Times New Roman', serif;}

JS

<script>fetch('review.json')  .then(res => res.json())  .then(data => {    const track = document.getElementById('scrollCards');    track.innerHTML = '';    data.forEach(review => {      const card = document.createElement('div');      card.className = 'review-card';      card.innerHTML = `<div class="review-header"><div class="linkedin-pic"><img src="${review.image}" alt="${review.name}" class="pic-prof" /></div><div class="review-info"><h2 class="review-name">${review.name}</h2><h2 class="review-role">${review.role}</h2></div><div class="linkpic-url"><a href="${review.linkedin}" target="_blank" rel="noopener noreferrer"><img src="https://static.vecteezy.com/system/resources/previews/018/930/480/non_2x/linkedin-logo-linkedin-icon-transparent-free-png.png" alt="LinkedIn" class="linkedin-icon"/></a></div></div><h2 class="review-text">${review.text}</h2>      `;      const cardWrapper = document.createElement('div'); // <== Important!      cardWrapper.appendChild(card);      track.appendChild(cardWrapper);    });    // ✅ Initialize Slick    $('#scrollCards').slick({      infinite: true,      slidesToShow: 1,      variableWidth: true,      slidesToScroll: 1,      autoplay: true,      autoplaySpeed: 5000,      speed: 1000,      arrows: false,      dots: false,      draggable: true,      pauseOnHover: false,      swipeToSlide: true,      touchThreshold: 20,      // 👇 resume autoplay after manual swipe      responsive: [], // leave empty if not needed      }).on('afterChange', function() {        $(this).slick('slickPlay');      });    })  .catch(err => console.error('Review load failed:', err));</script><script>document.addEventListener('DOMContentLoaded', () => {  const wrapper = document.querySelector('.review-scroll-wrapper');  const dragZone = document.querySelector('.review-drag-zone');  // Wait until Slick is initialized  const interval = setInterval(() => {    const slickTrack = document.querySelector('#scrollCards .slick-track');    if (!slickTrack) return;    clearInterval(interval); // ✅ Once track exists, proceed    // Always block dragging by default    slickTrack.addEventListener('mousedown', (e) => {      const bounds = dragZone.getBoundingClientRect();      const inside =        e.clientX >= bounds.left &&        e.clientX <= bounds.right &&        e.clientY >= bounds.top &&        e.clientY <= bounds.bottom;      if (!inside) {        e.stopImmediatePropagation();        e.preventDefault();      }    });    // Mobile drag block    slickTrack.addEventListener('touchstart', (e) => {      const bounds = dragZone.getBoundingClientRect();      const touch = e.touches[0];      const inside =        touch.clientX >= bounds.left &&        touch.clientX <= bounds.right &&        touch.clientY >= bounds.top &&        touch.clientY <= bounds.bottom;      if (!inside) {        e.stopImmediatePropagation();        e.preventDefault();      }    });  }, 50);});</script>

HTML

<!--At the TOP Before body--><script src="https://code.jquery.com/jquery-3.6.0.min.js"></script><script src="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js"></script><section class="reviews-section"><div class="reviews-container"><h2 class="review-title">      Review of <span class="review-title-gold">our clients</span></h2><div class="review-scroll-wrapper"><!-- This is where Slick injects & scrolls --><div class="review-drag-zone"></div><div class="card-holder" id="scrollCards"></div><!-- This goes *on top* as a transparent overlay for drag limitation --></div></div></section>

JSON

[  {"name": "Yoshi Tatsu","role": "Founder of YoshiT","image": "images/Yoshi.png","linkedin": "https://www.linkedin.com/in/reviewerlink/","text": "Very responsive and easy to work with. Got things done fast."  },  {"name": "Isabella Moreno","role": "Marketing Lead at CoinLoop","image": "images/Isabella Moreno.png","linkedin": "https://www.linkedin.com/in/reviewerlink1/","text": "Professional and consistent. Would recommend."  },  {"name": "Liam Chen","role": "CTO at BitNova","image": "images/Liam Chen.png","linkedin": "https://www.linkedin.com/in/reviewerlink2/","text": "Solid work. Helped us keep the community active and clean."  },  {"name": "Ava Schmidt","role": "Community Manager at ChainSpark","image": "images/Ava Schmidt.png","linkedin": "https://www.linkedin.com/in/reviewerlink3/","text": "Fast, reliable, and detail-oriented."  },  {"name": "Lucas Moreira","role": "Operations Lead at MetaEdge","image": "images/Lucas Moreira.png","linkedin": "https://www.linkedin.com/in/reviewerlink4/","text": "Communication was smooth. Always on point."  },  {"name": "Sophia Nguyen","role": "Community Strategist at Web3Shift","image": "images/Sophia Nguyen.png","linkedin": "https://www.linkedin.com/in/reviewerlink5/","text": "Delivered exactly what we needed, no fluff."  }]

Current code example shows the cursor at correct area, however I cannot drag from the middle and in this example also blocks it from the left and right side..

I'm unable to make it work, whatever I tried I never managed to drag work only on center area (where grab cursor is seen), sometimes I was able to drag only from the left and right side but never the center... Is this possible with slider or do I have to look for different library? This library was recommended to me by a friend.

Core CSS<- (this should be related to the problem)

.review-drag-zone {  position: absolute;  top: 0;  left: 25%;  width: 50%;  height: 100%;  z-index: 20;  cursor: grab;  pointer-events: auto;}.review-drag-zone:active {  cursor: grabbing;}.review-scroll-wrapper .slick-track {  cursor: default !important;}

Viewing all articles
Browse latest Browse all 1675

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>