3
votes

I used react-slick and made a carousel using Slider component. The code is bellow,

const carousel = (props) => {
    return (
        <div style={{ height: '50%', marginTop: '20px' }}>
            <Slider {...settings}>
                <div className={text__bar}>
                    <div >
                        <font>Lorum Ipsum 1</font>
                    </div>
                    <div className={slide1} />
                </div>
                <div className={text__bar}>
                    <div>
                        <font>Lorum Ipsum 2</font>
                    </div>
                    <div className={slide1} />
                </div>
                <div className={text__bar}>
                    <div>
                        <font>Lorum Ipsum 3</font>
                    </div>
                    <div className={slide1} />
                </div>
            </Slider>
            <div className={purple__bar}></div>
        </div>
    );
};

And the settings object,

const settings = {
    dots: true,
    infinite: true,
    speed: 500,
    slidesToShow: 1,
    slidesToScroll: 1,
    autoplay: true,
    autoplaySpeed: 5000,
    className: SlickMain,
    dotsClass: button__bar,
    arrows: false,
};

I have added some extra CSS to style my carousel dots (buttons) to look like bellow,

dotbar

When examined by the developer tools the button related to the currently shown slide gets a CSS class injected named 'slick-active'

injected-class

What I need to do is change the background color of the button corresponding to the slide, to black relapsing the current color purple.

What I did was,

.button__bar li.slick-active button {
    opacity: .75;
    color: #000
}

But it won't work. What am I missing?

.button__bar is the dotsClass I have given to dots in settings object.

3
Do you need to style .button__bar li.slick-active instead of .button__bar li.slick-active button? Unless the button actually exists inside li.Morpheus
button is inside lisajithneyo
Looking at examples the button style is applied using :before pseudo class, have you tried that? .button__bar li.slick-active button:before { opacity: .75; color: #000 }Morpheus
Yes and there's no need to apply before.sajithneyo
Do you want to use dotsClass: 'button__bar' instead of using button__bar object here?hankchiutw

3 Answers

6
votes

This is happening because I'm using CSS-Modules to load my CSS file. In the following code example, you can clearly see what's happening.

https://codesandbox.io/s/1z2lnox5rq?fontsize=14

So as a solution what I did was adding bellow methods to settings object.

const settings = {
  dots: true,
  infinite: true,
  speed: 1000,
  slidesToShow: 1,
  slidesToScroll: 1,
  autoplay: true,
  autoplaySpeed: 3000,
  className: slickMain,
  dotsClass: button__bar,
  arrows: false,
  beforeChange: (prev, next) => {
    this.setState({ currentSlide: next });
  },
  // afterChange: (index) => this.setState({ currentSlide: index }),
  appendDots: dots => {
    return (
      <div>
        <ul>
          {dots.map((item, index) => {
            return (
              <li key={index}>{item.props.children}</li>
            );
          })}
        </ul>
      </div>
    )
  },
  customPaging: index => {
    return (
      <button style={index === this.state.currentSlide ? testSettings : null}>
        {index + 1}
      </button>
    )
  }
};

To solve my problem, I used beforeChange to acquire the next slide index and saved it in the state. Then using appendDots a div with a ul, li is injected to the dot-bar section which. Inside the li, a button passed as a child prop using customPaging method. When the current slide equals the index of the customPaging, which is in the state, then a class is injected with a background color.

const testSettings = {
    backgroundColor: 'rgba(255, 255, 255, 0.8)',
    outline: '0'
}
2
votes

In case someone is using material ui here is how it could work

const settings: Settings = {
  dots: true,
  infinite: true,
  speed: 500,
  slidesToShow: 1,
  slidesToScroll: 1,
  dotsClass: `slick-dots ${classes.dots}`,
};
// your classes created with material ui
makeStyles((theme: Theme) => ({
// may not be the best way but it works
  dots: {
    bottom: 0,
    "& li.slick-active button::before": {
      color: theme.palette.primary.main,
    },
    "& li": {
      "& button::before": {
      fontSize: theme.typography.pxToRem(14),
      color: "#fff",
      opacity: 0.5,
    },
  }
}))

Here is a codesandbox link https://codesandbox.io/s/bold-snow-h9rwq?file=/src/App.tsx

Please note, that I haven't checked it with importing slick css i.e.

// Import css files
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";

but used cdn instead

1
votes

I have made this work just with CSS Modules with the use of :global()

in your specific case adding li.slick-active --> :global(li.slick-active)

.button__bar :global(li.slick-active) button {
  opacity: .75;
  color: #000
}

Here a codebox forked from yours