Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slick Slider - how to keep the active pagination (dot) always centered

I am trying to achieve something which I haven't seen done so far on the web. I want the active pagination dot in the slick slider to always be in the center.

This is the expected result:

Image of dots centered

In other words I would expect the page to load showing the first slide but the pagination dot for the first slide should be centered.

If a user clicks the next slide by swiping then the dot should move the middle again, with the active slide always being centered in the pagination. Any ideas on the best way to achieve this?

Here's an example and code of what i've done so far.

$('.slider').slick({
  infinite: true,
  dots: true,
  arrows: false
});
.slider {
  width: 200px;
}

.slide img {
  display: block;
  width: 100%;
  height: auto;
}

.slick-dots {
  display: flex;
  justify-content: center;
  margin: 0;
  padding: 1rem 0;
  list-style-type: none;
}

.slick-dots li {
  margin: 0 0.25rem;
}

.slick-dots button {
  display: block;
  width: 1rem;
  height: 1rem;
  padding: 0;
  border: none;
  border-radius: 100%;
  background-color: grey;
  text-indent: -9999px;
}

.slick-dots li.slick-active button {
  background-color: blue;
}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha256-3edrmyuQ0w65f8gfBsqowzjJe2iM6n0nKciPUp8y+7E=" crossorigin="anonymous"></script>
<script type="text/javascript" src="//cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/[email protected]/slick/slick.css" />
<div class="slider">
  <div class="slide">
    <img src="http://placehold.it/200x100?text=1" />
  </div>
  <div class="slide">
    <img src="http://placehold.it/200x100?text=2" />
  </div>
  <div class="slide">
    <img src="http://placehold.it/200x100?text=3" />
  </div>
  <div class="slide">
    <img src="http://placehold.it/200x100?text=4" />
  </div>
  <div class="slide">
    <img src="http://placehold.it/200x100?text=5" />
  </div>
</div>
like image 681
zxynz Avatar asked Aug 30 '18 10:08

zxynz


3 Answers

for that you have to add one more slider as per my snippet and the use Slider Syncing functionality to bind both slider.

here is an working example for that

$(document).ready(function() {
  $(".main_slider").slick({
    infinite: true,
    dots: false,
    arrows: false,
    asNavFor: '.slider_dots',
    slidesToShow: 1,
    slidesToScroll: 1,
  });
  $('.slider_dots').slick({
    infinite: true,
    slidesToShow: 3,
    slidesToScroll: 1,
    asNavFor: '.main_slider',
    arrows: false,
    dots: false,
    centerMode: true,
    focusOnSelect: true,
    centerPadding: '20%',
  });
});
.main_slider,
.slider_dots {
  width: 200px;
}

.slide img {
  display: block;
  width: 100%;
  height: auto;
}

.slick-dots {
  display: flex;
  justify-content: center;
  margin: 0;
  padding: 1rem 0;
  list-style-type: none;
}

.slick-dots li {
  margin: 0 0.25rem;
}

.slick-dots button {
  display: block;
  width: 1rem;
  height: 1rem;
  padding: 0;
  border: none;
  border-radius: 100%;
  background-color: grey;
  text-indent: -9999px;
}

.slick-dots li.slick-active button {
  background-color: blue;
}

.slider_dots .slider_navigators {
  height: 20px;
  background-color: #9E9E9E;
  border-radius: 50%;
  margin: 10px;
  transform: scale(0.4);
  outline: none;
  cursor: pointer;
}

.slider_dots .slider_navigators.slick-active {
  transform: scale(0.70);
}

.slider_navigators.slick-active.slick-current {
  transform: scale(1);
  background-color: #00f;
}
<!DOCTYPE html>
<html>

<head>
  <title>Demo Page</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/slick/slick.css" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js"></script>
</head>

<body>
  <div class="main_slider">
    <div class="slide">
      <img src="https://via.placeholder.com/350x150" />
    </div>
    <div class="slide">
      <img src="https://via.placeholder.com/350x150" />
    </div>
    <div class="slide">
      <img src="https://via.placeholder.com/350x150" />
    </div>
    <div class="slide">
      <img src="https://via.placeholder.com/350x150" />
    </div>
    <div class="slide">
      <img src="https://via.placeholder.com/350x150" />
    </div>
    <div class="slide">
      <img src="https://via.placeholder.com/350x150" />
    </div>
    <div class="slide">
      <img src="https://via.placeholder.com/350x150" />
    </div>
    <div class="slide">
      <img src="https://via.placeholder.com/350x150" />
    </div>
    <div class="slide">
      <img src="https://via.placeholder.com/350x150" />
    </div>
    <div class="slide">
      <img src="https://via.placeholder.com/350x150" />
    </div>
  </div>
  <div class="slider_dots">
    <div class="slider_navigators"></div>
    <div class="slider_navigators"></div>
    <div class="slider_navigators"></div>
    <div class="slider_navigators"></div>
    <div class="slider_navigators"></div>
    <div class="slider_navigators"></div>
    <div class="slider_navigators"></div>
    <div class="slider_navigators"></div>
    <div class="slider_navigators"></div>
    <div class="slider_navigators"></div>
  </div>
</body>

</html>

I hope you are getting your solution from my snippet code.

like image 134
KuldipKoradia Avatar answered Sep 20 '22 02:09

KuldipKoradia


.on('beforeChange', function(event, slick, currentSlide, nextSlide){
  //appedn the bullet on center 
});

Something like this

Codepen

like image 38
pixellab Avatar answered Sep 21 '22 02:09

pixellab


Here's an example that uses a bit of jQuery to manipulate the styles of the existing slide dots. Another example of the working code can be found here: https://codepen.io/edlucas/pen/XWJRmbb

The only caveat is that the <li> tags containing the dots must all be the same width for the math to work out. This solution will work with any number of dots in a single line.

const $slideShow = $('.slider');

function offsetDots(slideNum) {
  const $slickDots = $slideShow.find('.slick-dots'),
    numDots = $slickDots.find('li').length,
    dotWidth = $slickDots.find('li:first').outerWidth(true),
    offset = dotWidth * slideNum;
  
  // Offset the dots container to center current slide dot
  $slickDots.css('marginLeft', offset * -1 - Math.ceil(dotWidth / 2));
  
  // Clear existing secondary dot class
  $slickDots.find('li').removeClass('slick-secondary');

  // Add secondary dot class to preceeding slide dot
  if (slideNum > 0) {
    $slickDots.find('li:nth-of-type('+slideNum+')').addClass('slick-secondary');
  }

  // Add secondary dot class to next slide dot
  if (slideNum < numDots - 1) {
    $slickDots.find('li:nth-of-type('+(slideNum + 2)+')').addClass('slick-secondary');
  }
}

$slideShow.on('init', function(event, slick) {
  offsetDots(0);
});

$slideShow.on('beforeChange', function(event, slick, currentSlide, nextSlide) {
  offsetDots(nextSlide);
});

$slideShow.slick({
  infinite: true,
  dots: true,
  arrows: false
});
.demo-wrapper{
  width: 200px;
  position: relative;
}

.slide img {
  display: block;
  width: 100%;
  height: auto;
}

.slick-dots {
  position: absolute;
  left: 50%;
  display: inline-flex;
  margin: 0;
  padding: 1rem 0;
  list-style-type: none;
}

.slick-dots li {
  width: 12px;
  margin: 0 3px;
}

.slick-dots button {
  display: block;
  width: 6px;
  height: 6px;
  padding: 0;
  margin: 0 auto;
  border: none;
  border-radius: 100%;
  background-color: grey;
  text-indent: -9999px;
}

.slick-dots li.slick-active button {
  background-color: blue;
  width: 12px;
  height: 12px;
  margin-top:-4px
}

.slick-dots li.slick-secondary button {
  width: 8px;
  height: 8px;
  margin-top: -1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="//cdn.jsdelivr.net/npm/[email protected]/slick/slick.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/[email protected]/slick/slick.css" />

<div class="demo-wrapper">
<div class="slider">
  <div class="slide">
    <img src="https://loremflickr.com/200/200/lego?random=1" />
  </div>
  <div class="slide">
    <img src="https://loremflickr.com/200/200/lego?random=2" />
  </div>
  <div class="slide">
    <img src="https://loremflickr.com/200/200/lego?random=3" />
  </div>
  <div class="slide">
    <img src="https://loremflickr.com/200/200/lego?random=4" />
  </div>
  <div class="slide">
    <img src="https://loremflickr.com/200/200/lego?random=5" />
  </div>
</div>
</div>
like image 37
Ed Lucas Avatar answered Sep 19 '22 02:09

Ed Lucas