akiran / react-slick

React carousel component
http://react-slick.neostack.com/
MIT License
11.76k stars 2.11k forks source link

Using Client Side Routing completely breaks my carousel CSS #1507

Open clayhan opened 5 years ago

clayhan commented 5 years ago

I'm unfortunately unable to replicate this in Codesandbox because I am using Next.js for SSR and client-side rendering, but hoping someone might have insight into what I'm running into.

So far on one of my pages, on initial page load, everything looks great. However, on another page where the carousel is the exact same component, the prev and next arrows are somehow no longer to the left and right of the carousel, but to the top and bottom. Then when I route back to the page that was originally rendered properly, the nextArrow is rendered entirely off the page.

I'm noticing that on the page where the arrows are are the bottom/top instead of left to right, they lack all this default CSS, it just never makes it to the page:

.slick-next, .slick-prev {
    font-size: 0;
    line-height: 0;
    top: 50%;
    width: 20px;
    height: 20px;
    -webkit-transform: translate(0,-50%);
    -ms-transform: translate(0,-50%);
    transform: translate(0,-50%);
    cursor: pointer;
    color: transparent;
    border: none;
    outline: 0;
    background: 0 0;

Another thing I'm noticing is that I have a CSS file that I use to override the carousel's default CSS. When I client side route, some of my CSS rules are overwritten again while some of remain.

I have attached a gif representing the behavior I'm seeing. Thanks a ton for any insight anyone might have.

ezgif com-optimize

My carousel code:

const SvgWrapper = styled.div`
  border-radius: 50px;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgba(0, 0, 0, 0.7);
  cursor: pointer;
  padding-right: ${props => (props.left ? '2px' : 'none')};
  padding-left: ${props => (props.right ? '2px' : 'none')};

  @media (min-width: 1024px) {
    width: 52px;
    height: 52px;
  }
`;

const StyledFontAwesomeIcon = styled(FontAwesomeIcon)`
  font-size: 23px;
  color: white;
  opacity: 1;
  z-index: 1;
  @media (min-width: 1024px) {
    font-size: 35px;
  }
`;

class VideoCarousel extends Component {
  state = { currentSlide: 0 };

  render() {
    const settings = {
      slidesToShow: 5 + 0.05,
      slidesToScroll: 5,
      infinite: false,
      lazyLoad: true,
      afterChange: current => this.setState(state => ({ currentSlide: current })),
      prevArrow:
        this.state.currentSlide === 0 ? (
          <div />
        ) : (
          <div>
            <SvgWrapper left>
              <StyledFontAwesomeIcon icon={faAngleLeft} />
            </SvgWrapper>
          </div>
        ),
      nextArrow:
        this.state.currentSlide - 1 >= this.props.videos.length - 5 ? null : (
          <div>
            <SvgWrapper right>
              <StyledFontAwesomeIcon icon={faAngleRight} />
            </SvgWrapper>
          </div>
        ),
      responsive: [
        {
          breakpoint: 1440,
          settings: {
            slidesToShow: 4 + 0.05,
            slidesToScroll: 4,
            nextArrow:
              this.state.currentSlide - 1 >= this.props.videos.length - 4 ? null : (
                <div>
                  <SvgWrapper right>
                    <StyledFontAwesomeIcon icon={faAngleRight} />
                  </SvgWrapper>
                </div>
              )
          }
        },
        {
          breakpoint: 1024,
          settings: {
            slidesToShow: 3 + 0.05,
            slidesToScroll: 3,
            nextArrow:
              this.state.currentSlide - 1 >= this.props.videos.length - 3 ? null : (
                <div>
                  <SvgWrapper onClick={null} right>
                    <StyledFontAwesomeIcon icon={faAngleRight} />
                  </SvgWrapper>
                </div>
              )
          }
        }
      ]
    };

    return (
      <div>
        <Slider {...settings}>
          {this.props.videos.map(video => (
            <Link href={`/watch?v=${video.id}`}>
              <a>
                <VideoCard backgroundImageUrl={video.thumbnail.url} title={video.title} />
              </a>
            </Link>
          ))}
        </Slider>
      </div>
    );
  }
}

and my styles.css

.slick-next {
  right: 40px;
}

.slick-next, .slick-prev {
  z-index: 10000;
}

.slick-next:before, .slick-prev:before {
  display: none;
}
ehmadzubair commented 5 years ago

@clayhan I'm facing the same issue. Have you found a fix to this? I think the Slick slider is having a hard time playing along with the React Router.

clayhan commented 5 years ago

@ehmadzubair I ended up ditching react-slick. I did not have a fix for this.

ehmadzubair commented 5 years ago

Surprising. I was using a slick slider (HTML/CSS) which would fail to initialise sliders that were off in nested screens. That seemed to cause the problem. I'm able to use react-slick sans problems now.