Slick Carousel Responsive slidesToShow Recipe
Tags: css, javascript, parcel
Published: 2019-09-13 13:13:50

Designs typically require more than the out of the box demos provide, which is understandable. The [slick](https://kenwheeler.github.io/slick/) carousel demos will get you most of the way there and provide examples for various settings. This post is an example of how to dynamically update the slick `slidesToShow` value as the viewport is resized, [demo](https://jimfrenette.com/demo/slides-to-show/).

### Getting Started

In this tutorial, we're using the Parcel web application bundler to compile all of source code and load it in a development web server. All of our markup, JavaScript and CSS will be created in a subdirectory named src, short for source. In the project root, create the `src` folder. Then, create an `html` file in the `src` folder with the following HTML. This markup contains 4 slide content containers for the carousel. The content container include FPO images and a heading.

##### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Responsive slidesToShow | Slick Carousel Demo</title>
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
    <main>
        <div class="carousel">
            <div>
                <div class="slide-content">
                    <h3>First Slide</h3>
                    <img src="https://via.placeholder.com/260x200/9932CC/FFFFFF" />
                </div>
            </div>
            <div>
                <div class="slide-content">
                    <h3>Second Slide</h3>
                    <img src="https://via.placeholder.com/260x200/7FFFD4/000000" />
                </div>
            </div>
            <div>
                <div class="slide-content">
                    <h3>Third Slide</h3>
                    <img src="https://via.placeholder.com/260x200/87CEFA/000000" />
                </div>
            </div>
            <div>
                <div class="slide-content">
                    <h3>Fourth Slide</h3>
                    <img src="https://via.placeholder.com/260x200/F4A460/000000" />
                </div>
            </div>
        </div>
    </main>
    <script src="index.js"></script>
</body>
</html>
```
    
> Using [Emmet](https://emmet.io/), which is [built into VS Code](https://code.visualstudio.com/docs/editor/emmet "Emmet in Visual Studio Code"), you can create the `index.html` content by entering an exclamation mark on the first line then select the tab key.

### Slick Carousel

Since we're using [npm](https://www.npmjs.com/) to install the slick carousel and it's dependencies, in the project root, run `npm init` with the `-y` flag to generate an empty project with the default settings.

```
npm init -y
```

Install slick carousel.

```
npm install slick-carousel
```

Slick carousel depends on jQuery, so let's install it.
```
npm install jquery
```

Create a `src/index.css` file in the project as follows. Note that we're importing the slick stylesheets from slick in the `node_modules` folder where it was installed by npm. When we run our build later on, these imported stylesheets will be compiled along with the `index.css` below into a single stylesheet to reduce http requests made by the web application.

##### index.css

```css
/* node_modules */
@import "../../node_modules/slick-carousel/slick/slick.css";
@import "../../node_modules/slick-carousel/slick/slick-theme.css";

body {
  margin: 0;
}

main {
  max-width: 1440px;
  margin: auto;
  padding: 10px;
  background: #cfcfcf;
}

.carousel {
  margin-right: -10px;
}

.slide-content {
  display: inline-block;
  background: #fff;
  padding: 15px;
  text-align: center;
}

@media screen and (min-width: 980px) {
  main {
    padding: 50px;
  }

  .carousel {
    max-width: 980px;
    margin: auto;
  }
}
``` 

Here is our JavaScript code. Add this to a `src/index.js` file.

##### index.js

```javascript
import $ from 'jquery'
import 'slick-carousel'

(function () {

  var slidesToShow = 1.1,
      slideWidth = 290,
      slideSpacing = 30;

  var $el = $('.carousel');

  init();

  function init() {
    $el.on('init', (event, slick, currentSlide) => carouselInit(event, slick));

    $el.slick({
      arrows: false,
      dots: true,
      infinite: false,
      slidesToScroll: 1,
      slidesToShow: slidesToShow,
      mobileFirst: true,
      responsive: [{
        breakpoint: 980,
        settings: {
          arrows: true,
          slidesToShow: 3
        }
      }]
    });

    $el.css('padding-left', slideSpacing / 2 + 'px');

    var resizeTimeout;
    $(window).on('resize', () => {
      clearTimeout(resizeTimeout);
      resizeTimeout = setTimeout(setSlidesToShow(), 500);
    })
  };

  function carouselInit(event, slick) {
    // https://github.com/kenwheeler/slick/issues/1802
    setTimeout(() => setSlidesToShow(), 0);
  };

  function setSlidesToShow() {
    if ($(window).width() >= 980) {
      return;
    }

    var num1, num2,
        slickListWidth = $el.find('.slick-list').width(),

    num1 = slickListWidth / slideWidth;
    num2 = Math.floor(num1) * slideSpacing;
    num1 = (slickListWidth - num2) / slideWidth;
    num1 = Math.floor(num1 * 100) / 100;

    console.log('slickListWidth', slickListWidth);
    console.log('slideWidth', slideWidth);
    console.log('slidesToShow', num1);

    $el.slick('slickSetOption', 'slidesToShow', num1);

    // refresh to apply slick-slide classes, dots etc. as needed
    $el.slick('resize');

    slidesToShow = num1;
  };

})();
```

In the JavaScript, we're importing the slick library and jquery. Then we're wrapping everything else in an [IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE) (Immediately Invoked Function Expression). 

Then we're declaring some slide defaults for the `slidesToShow` calculation that will run when slick is initialized and again when the browser window is resized. e.g.,

```
var slidesToShow = 1.1,
    slideWidth = 290,
    slideSpacing = 30;
```

The `$el` variable is set with a jQuery selector for the HTML element slick carousel will bind to. e.g.,

```
var $el = $('.carousel');
```

The slick `responsive` option has a breakpoint setting of 980 with a constant `slidesToShow` setting that can be used when the browser window is at or greater than this width. In order for this responsive setting to remain constant, the 980 width value is checked in the `setSlidesToShow` function before it continues. e.g.,

```
if ($(window).width() >= 980) {
  return;
}
```

Now we're ready to build the web app. Install [Parcel](https://parceljs.org/) to do this. e.g.,

```
npm install parcel-bundler -D
```

>   If you're planning on using Parcel to bundle other projects, you might want to install it as a global module instead using `npm install -g parcel-bundler`.


#### [npm-run-script](https://docs.npmjs.com/cli/run-script)

These npm script commands in the `package.json` file are what we will use to run the parcel commands.

The first script command to add, we'll name `dev:slidestoshow`. This launches the parcel dev server, watches for file changes and rebuilds as needed. 

The second script command to add, is named `build:slidestoshow`. This minifies the files for production. Note the `--public-url` option, this sets the asset paths as relative during the build.

##### package.json

```javascript
"scripts": {
  "dev:slidestoshow": "parcel ./src/slides-to-show/slides-to-show.html",
  "build:slidestoshow": "parcel build ./src/slides-to-show/slides-to-show.html --public-url ./",
  "test": "echo \"Error: no test specified\" && exit 1"
},
``` 

One more thing to install is [parcel-plugin-clean-dist](https://www.npmjs.com/package/parcel-plugin-clean-dist). This will remove all the previous files when rebuilding for production.

#### Running the commands

Development
```
npm run dev:slidestoshow
```

If all went as expected, the terminal output will include a URL to the development server. e.g., Server running at <a href="http://localhost:1234" rel="nofollow">http://localhost:1234</a>.

Any code changes you make while running in this mode will be rebuilt and rendered on the server.

Production
```
npm run build:slidestoshow
```

#### Download the Code

All of the source code for this tutorial is available on GitHub as part of my [uiCookbook](https://github.com/jimfrenette/uiCookbook) repo.

<h5><i class="icon-github"></i> <a href="https://github.com/jimfrenette/uiCookbook/tree/master/slick">Source Code</a></h5>

Originally published at [jimfrenette.com/2019/04/slick-carousel-responsive-slides-to-show](https://jimfrenette.com/2019/04/slick-carousel-responsive-slides-to-show/)