react-slick で矢印ボタンを良い感じに表示する

2021.04.15

吉川@広島です。

スライダー実装で react-slick を使ったのですが、フロントエンドに慣れておらず少々ハマりましたので共有します。

react-slick について

React Slick

react-slick がどのようなものかは、公式ドキュメントトップの動くデモを確認して頂くと話が早いかと思います。

このようなスライダーは要件としてよく出てくるかと思います。react-slick のようなライブラリを使うことで少ない工数で実現することができます。

環境

  • react 17.0.0
  • react-dom 17.0.0
  • react-slick 0.28.1
  • react-carousel 1.8.1
  • typescript 4.0.3

コード (変更前)

import React from 'react'
import Slider, { Settings } from 'react-slick'
import styled from 'styled-components'
import 'slick-carousel/slick/slick.css'
import 'slick-carousel/slick/slick-theme.css'

const Container = styled.div``

const SliderWrapper = styled.div``

export const MyComponent: React.FC = () => {
  const settings: Settings = {
    dots: true,
    infinite: true,
    arrows: true,
    speed: 500,
  }

  return (
    <Container>
      <SliderWrapper>
        <Slider {...settings}>
          <div>
            <h3>1</h3>
          </div>
          <div>
            <h3>2</h3>
          </div>
          <div>
            <h3>3</h3>
          </div>
          <div>
            <h3>4</h3>
          </div>
          <div>
            <h3>5</h3>
          </div>
          <div>
            <h3>6</h3>
          </div>
        </Slider>
      </SliderWrapper>
    </Container>
  )
}

矢印ボタンが見えない

arrows: true を指定することでスライダーの左右に矢印ボタンが出現するはずなのですが、見当たりません。

原因

単にデフォルトでは矢印ボタンが白く、背景と同化しているだけでした。今回のように背景色が白である場合はボタンの色を変更する必要があります。

【解決策 1】 .slick-prev:before, .slick-next:before にスタイルを指定する

Easy way to change arrow color ? Not the background color

こちらの issue が参考になりました。下のように CSS を指定する方法です。

.slick-prev:before,
.slick-next:before {
  color: yellow;
}

【解決策 2】 nextArrow, prevArrow にカスタムコンポーネントを指定する

Custom Arrows

nextArrow と prevArrow パラメータに任意のコンポーネントを渡すことができるようです。

const settings = {
  dots: true,
  infinite: true,
  slidesToShow: 3,
  slidesToScroll: 1,
  nextArrow: <SampleNextArrow />, // 進む矢印にカスタムコンポーネントを指定
  prevArrow: <SamplePrevArrow /> // 戻る矢印にカスタムコンポーネントを指定
};

解決策 1 を採用

今回は 1 の方法を採用しました。

今回は styled-components を使っているので、 SliderWrapper の中に以下の CSS を記述します。

.slick-prev:before,
.slick-next:before {
  color: black; /* 黒色に指定 */
}

矢印ボタンが画面から逸脱する

上の対応で矢印ボタンは黒くなり、視認することができるようになりました。ただ、まだ問題があって、 width: 100% を超えた外側に位置しているようです。

画面左右いっぱいを超えているので、 X 軸のスクロールバーが自動表示されているのがわかるかと思います。

原因

スライダーを画面いっぱいで設置している場合、矢印ボタンはその外側に配置されるのでこのようになってしまうようです。

解決策

矢印ボタンの表示スペースを左右に確保してあげる必要があります。今回は、 width を 100% より少し縮めて、中央寄せするという方針を採りました。

SliderWrapper に次のような CSS を指定します。

width: calc(100% - 50px);

これで 100% から 50px を引いた width にしました。

また、 Container

display: flex;
justify-content: center;

と、 FlexBox を用いた中央寄せを指定しました。

コード (変更後)

完成形のコードが以下です。

import React from 'react'
import Slider, { Settings } from 'react-slick'
import styled from 'styled-components'
import 'slick-carousel/slick/slick.css'
import 'slick-carousel/slick/slick-theme.css'

const Container = styled.div`
  display: flex;
  justify-content: center;
`

const SliderWrapper = styled.div`
  width: calc(100% - 50px);

  .slick-prev:before,
  .slick-next:before {
    color: black;
  }
`

export const MyComponent: React.FC = () => {
  const settings: Settings = {
    dots: true,
    infinite: true,
    arrows: true,
    speed: 500,
  }

  return (
    <Container>
      <SliderWrapper>
        <Slider {...settings}>
          <div>
            <h3>1</h3>
          </div>
          <div>
            <h3>2</h3>
          </div>
          <div>
            <h3>3</h3>
          </div>
          <div>
            <h3>4</h3>
          </div>
          <div>
            <h3>5</h3>
          </div>
          <div>
            <h3>6</h3>
          </div>
        </Slider>
      </SliderWrapper>
    </Container>
  )
}

適切に左右の矢印ボタンが表示されるようになりました。

本文紹介以外の参考資料