Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom arrow Swiper Slider + Next.js + Sass

I'm using the slider swiper in a project developed in Next.JS and I'm using Sass to do the styling. But when I'm going to use the swiper classes, as mandated by the documentation, to style the arrows, it doesn't work.

I need the arrows to be outside the component, not overlapping.

CSS

.swiper-button-next,
.swiper-button-prev {
  background: red;
  position: absolute;
  top: 50%;
  width: calc(var(--swiper-navigation-size) / 44 * 27);
  height: var(--swiper-navigation-size);
  margin-top: calc(0px - (var(--swiper-navigation-size) / 2));
  z-index: 10;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--swiper-navigation-color, var(--swiper-theme-color));
}
.swiper-button-next.swiper-button-disabled,
.swiper-button-prev.swiper-button-disabled {
  opacity: 0.35;
  cursor: auto;
  pointer-events: none;
}
.swiper-button-next:after,
.swiper-button-prev:after {
  background: red;
  font-family: swiper-icons;
  font-size: var(--swiper-navigation-size);
  text-transform: none !important;
  letter-spacing: 0;
  text-transform: none;
  font-variant: initial;
  line-height: 1;
}
.swiper-button-prev,
.swiper-container-rtl .swiper-button-next {
  left: 10px;
  right: auto;
}
.swiper-button-prev:after,
.swiper-container-rtl .swiper-button-next:after {
  content: "prev";
  color: #000;
}
.swiper-button-next,
.swiper-container-rtl .swiper-button-prev {
  right: 10px;
  left: auto;
}
.swiper-button-next:after,
.swiper-container-rtl .swiper-button-prev:after {
  content: "next";
}
.swiper-button-next.swiper-button-white,
.swiper-button-prev.swiper-button-white {
  --swiper-navigation-color: #ffffff;
}
.swiper-button-next.swiper-button-black,
.swiper-button-prev.swiper-button-black {
  --swiper-navigation-color: #000000;
}
.swiper-button-lock {
  display: none;
}

I've tried changing the styles, but nothing reflects on the component. If I change styles by browser it works normally.

like image 795
LayTexas Avatar asked Oct 16 '25 11:10

LayTexas


2 Answers

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

like image 115
adrianmanduc Avatar answered Oct 18 '25 01:10

adrianmanduc


Here is the best way to add custom arrows:

import React, { useRef } from "react";
// For Typescript 
// import SwiperCore from "swiper";
import { Swiper, SwiperSlide } from "swiper/react";
import "swiper/css";


const SliderComponent = () => {
const swiperRef = useRef();

// For Typescript!
// const swiperRef = useRef<SwiperCore>();  


const sliderSettings = {
  440: {
    slidesPerView: 1,
    spaceBetween: 30,
  },
  680: {
    slidesPerView: 2,
    spaceBetween: 30,
  },
  1024: {
    slidesPerView: 3,
    spaceBetween: 30,
  },
};

return (
    <div>
      <button onClick={() => swiperRef.current?.slidePrev()}>Prev</button>

      <Swiper
        slidesPerView={3}
        breakpoints={sliderSettings}
        onBeforeInit={(swiper) => {
          swiperRef.current = swiper;
        }}
      >
        <SwiperSlide>
          Slide 1
        </SwiperSlide>
        <SwiperSlide>
          Slide 2
        </SwiperSlide>
        <SwiperSlide>
          Slide 3
        </SwiperSlide>
        <SwiperSlide>
          Slide 4
        </SwiperSlide>
        <SwiperSlide>
          Slide 5
        </SwiperSlide>
      </Swiper>

      <button onClick={() => swiperRef.current?.slideNext()}>Next</button>
    </div>
  );
};

export default SliderComponent;
like image 29
hamza liaqat Avatar answered Oct 18 '25 00:10

hamza liaqat



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!