Search code examples
cssreactjsnext.jsreact-slick

Setting styles for react-slick


I am using react-slick (https://react-slick.neostack.com/) to make an easy slider component of my blogs. Now, I want to simply set position: relative and z-index: 50 to the div with class slack-current (which is generated by the Slider component), but can not find any way to do this. I am using NextJS with the following component:

function Carousel({ blogs }) {
  const [imageIndex, setImageIndex] = useState(0);

  const transformDate = (date) => {
    return date.substring(0, 10);
  };

  const NextArrow = ({ onClick }) => {
    return (
      <div className={`${styles.arrow} ${styles.next}`} onClick={onClick}>
        <FaArrowRight />
      </div>
    );
  };

  const PrevArrow = ({ onClick }) => {
    return (
      <div className={`${styles.arrow} ${styles.prev}`} onClick={onClick}>
        <FaArrowLeft />
      </div>
    );
  };

  const settings = {
    dots: false,
    infinite: true,
    speed: 500,
    slidesToShow: 3,
    slidesToScroll: 1,
    centerMode: true,
    nextArrow: <NextArrow />,
    prevArrow: <PrevArrow />,
    beforeChange: (current, next) => setImageIndex(next),
  };

  return (
    <div className={styles.carouselContainer}>
      <Slider {...settings} className={styles.slider}>
        {blogs.map((blog, idx) => (
          <div key={idx} className={styles.slide}>
            <div
              className={
                idx === imageIndex
                  ? `${styles.innerSlide} ${styles.activeSlide}`
                  : `${styles.innerSlide} ${styles.passiveSlide}`
              }
            >
              <p>{transformDate(blog.created_on)}</p>
              <h3>{blog.title}</h3>
              <p>{blog.subtitle}</p>
              <button
                className={
                  idx === imageIndex
                    ? `${styles.button} ${styles.activeButton}`
                    : styles.button
                }
              >
                <Link href={"/blog/" + blog.id}>READ MORE</Link>
              </button>
            </div>
          </div>
        ))}
      </Slider>
    </div>
  );
}

export default Carousel;

So since I set className ={styles.slider} on the Slider component, I thought I could solve it this way in CSS:

.slider .slick-current {
  position: relative !important;
  z-index: 50 !important;
}

However, this shows up nowhere and thus has no effect. I also tried to do this with a JavaScript queryselector, but this does not work either. Would anybody know how to do this seemingly simple thing?


Solution

  • I got it working with JavaScript, although it's not an elegant solution. The following will add position:relative and z-index:50 to the element with CSS class slick-current, and will remove it from the other active slides (since the slick current class changes slides when another slides becomes the current slide) using useEffect:

    function Carousel({ blogs }) {
      const [imageIndex, setImageIndex] = useState(0);
    
      const transformDate = (date) => {
        return date.substring(0, 10);
      };
    
      const NextArrow = ({ onClick }) => {
        return (
          <div className={`${styles.arrow} ${styles.next}`} onClick={onClick}>
            <FaArrowRight />
          </div>
        );
      };
    
      const PrevArrow = ({ onClick }) => {
        return (
          <div className={`${styles.arrow} ${styles.prev}`} onClick={onClick}>
            <FaArrowLeft />
          </div>
        );
      };
    
      useEffect(() => {
        document.querySelectorAll(".slick-active").forEach((el) => {
          el.style.setProperty("position", "static", "important");
        });
    
        document
          .querySelectorAll(".slick-current")
          .style.setProperty("position", "relative", "important");
        document
          .querySelectorAll(".slick-current")
          .style.setProperty("z-index", "50", "important");
      }, [imageIndex]);
    
      const settings = {
        dots: false,
        infinite: true,
        speed: 500,
        slidesToShow: 3,
        slidesToScroll: 1,
        centerMode: true,
        nextArrow: <NextArrow />,
        prevArrow: <PrevArrow />,
        beforeChange: (current, next) => setImageIndex(next),
      };
    
      return (
        <div className={styles.carouselContainer}>
          <Slider {...settings}>
            {blogs.map((blog, idx) => (
              <div key={idx}>
                <div
                  className={
                    idx === imageIndex
                      ? `${styles.innerSlide} ${styles.activeSlide}`
                      : `${styles.innerSlide} ${styles.passiveSlide}`
                  }
                >
                  <p>{transformDate(blog.created_on)}</p>
                  <h3>{blog.title}</h3>
                  <p>{blog.subtitle}</p>
                  <button
                    className={
                      idx === imageIndex
                        ? `${styles.button} ${styles.activeButton}`
                        : styles.button
                    }
                  >
                    <Link href={"/blog/" + blog.id}>READ MORE</Link>
                  </button>
                </div>
              </div>
            ))}
          </Slider>
        </div>
      );
    }
    
    export default Carousel;
    

    Better solutions are still welcome!