Custom arrow Swiper Slider + Next.js + Sass

Solution 1:

Changing the basic arrows styles is pretty simple - take a look at the following codesandbox: https://codesandbox.io/s/stoic-shaw-q35wq?file=/src/styles.scss

.swiper-button-prev, .swiper-button-next {
  top: 45%;
  width: 40px;
  height: 40px;
  background: #fff;
  border: 1px solid gray;
  border-radius: 50%;
  color: blue;
  font-weight: 700;
  outline: 0;
  transition: background-color .2s ease, color .2s ease;
  
  &::after {
      font-size: 16px;
  }
}

.swiper-button-prev {
  &:after {
      position: relative;
      left: -1px;
  }
}

.swiper-button-next {
  &:after {
      position: relative;
      left: 1px;
  }
}

.swiper-button-prev, .swiper-container-rtl .swiper-button-next {
  left: 10px;
  right: auto;
}

.swiper-button-next, .swiper-container-rtl .swiper-button-prev {
  right: 10px;
  left: auto;
}

.swiper-button-prev.swiper-button-disabled, .swiper-button-next.swiper-button-disabled {
  opacity: 0;
  cursor: auto;
  pointer-events: none;
}

Moving the arrows outside, however, is a bit more tricky. In the example above I've used a little CSS tricks (negative margin and corresponding padding) and some overflows to get it working but it might not be enough for your use case.

You would have to create your own next/previous elements:

import React from "react";
import { Navigation, Pagination, Scrollbar, A11y, Controller } from "swiper";
import { Swiper, SwiperSlide } from "swiper/react";

// Import Swiper styles
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
import "swiper/css/scrollbar";

import "./styles.scss";

const image = "https://source.unsplash.com/featured/300x201";

export default function App() {
  const images = new Array(6).fill({ url: image });

  const [swiper, setSwiper] = React.useState();
  const prevRef = React.useRef();
  const nextRef = React.useRef();

  React.useEffect(() => {
    if (swiper) {
      console.log("Swiper instance:", swiper);
      swiper.params.navigation.prevEl = prevRef.current;
      swiper.params.navigation.nextEl = nextRef.current;
      swiper.navigation.init();
      swiper.navigation.update();
    }
  }, [swiper]);

  return (
    <div className="App">
      <div className="carousel-container">
        <div className="swiper-button" ref={prevRef}>
          prev
        </div>
        <Swiper
          modules={[Navigation, Pagination, Scrollbar, A11y, Controller]}
          className="external-buttons"
          spaceBetween={24}
          slidesPerView={1}
          navigation={{
            prevEl: prevRef?.current,
            nextEl: nextRef?.current
          }}
          updateOnWindowResize
          observer
          observeParents
          initialSlide={2}
          onSwiper={setSwiper}
        >
          {images.map((image, index) => (
            <SwiperSlide key={index}>
              <img
                height="200"
                width="300"
                alt="img"
                className="image"
                src={image.url}
              />
            </SwiperSlide>
          ))}
        </Swiper>
        <div className="swiper-button" ref={nextRef}>
          next
        </div>
      </div>
    </div>
  );
}

Complete example - https://codesandbox.io/s/prod-darkness-o483y?file=/src/App.js

Important - the examples are using Swiper v7