0

I have a slider using swiperjs and I'd like to add dropdown menu to swiper-slide. By default, all swiper containers are relative position so I changed them all to static position but the dropdown-menu cant escape to the root container (relative position).

Here is the demo in jsfiddle: https://jsfiddle.net/7uas82rz/20/

HTML

<div class="freedom my-5">
  <div class="swiper-container myswiper">
    <div class="swiper-wrapper">
      <div class="swiper-slide">
        <div class="dropdown">
          <a href="#" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            <span>SLIDE 1</span>
          </a>
          <ul class="dropdown-menu">
            <li><a class="dropdown-item" href="#">Menu 1</a></li>
            <li><a class="dropdown-item" href="#">Menu 2</a></li>
          </ul>
        </div>
      </div>
      <div class="swiper-slide">
        <span>SLIDE 2</span>
      </div>
    </div>
    <div class="swiper-button-next"></div>
    <div class="swiper-button-prev"></div>
  </div>
</div>  

CSS

.freedom{
  position:relative;
}
.swiper-container, .swiper-wrapper, .swiper-slide{
  position:static !important;
}
.swiper-container > .swiper-wrapper > .swiper-slide{
  width:200px;
}

Javascript

const swiper = new Swiper(".myswiper",{
  speed:1000,
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
  slidesPerView: 'auto',
  initialSlide:0,
  loop:true,
  loopedSlides:20,
  visibilityFullFit: true,
  autoResize: false,
  spaceBetween: 0,
});
MTLC
  • 53
  • 3
  • 7
  • That's because `overflow: hidden` is set on the parent element `.swiper-container`: that will effectively hide overflowing content (which includes your dropdown menu). However, it might not be a good idea to remove this style, because it may affect the appearance of the slider. – Terry Aug 04 '21 at 09:48
  • @Terry yes, I've notice that but I did some search here and solution is to set child as absolute position to escape. Sadly, it doesn't work for my case. – MTLC Aug 04 '21 at 09:55
  • Unfortunately you can't do this with css - you can't have x hidden and y visible (see https://stackoverflow.com/questions/6421966/css-overflow-x-visible-and-overflow-y-hidden-causing-scrollbar-issue) - you would need to move your dropdown outside of the overflow div for it to show – Pete Aug 04 '21 at 10:08

2 Answers2

0

You can force overflowing content to be visible on the .swiper-container element:

.swiper-container {
  overflow: visible !important;
}

However, there is a chance that this override may interfere with the styling/visuals of the plugin.

See proof-of-concept example:

const swiper = new Swiper(".myswiper",{
  speed:1000,
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
  slidesPerView: 'auto',
  initialSlide:0,
  loop:true,
  loopedSlides:10,
  visibilityFullFit: true,
  autoResize: false,
  spaceBetween: 0,
});
.swiper-container > .swiper-wrapper > .swiper-slide{
  width:200px;
}

.swiper-container {
  overflow: visible !important;
}
<!DOCTYPE html>
<head>
  <script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css" />
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
  <div class="swiper-container myswiper">
    <div class="swiper-wrapper">
      <div class="swiper-slide">
        <div class="dropdown">
          <a href="#" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            <span>SLIDE 1</span>
          </a>
          <ul class="dropdown-menu">
            <li><a class="dropdown-item" href="#">Menu 1</a></li>
            <li><a class="dropdown-item" href="#">Menu 2</a></li>
          </ul>
        </div>
      </div>
      <div class="swiper-slide">
        <span>SLIDE 2</span>
      </div>
    </div>
    <div class="swiper-button-next"></div>
    <div class="swiper-button-prev"></div>
  </div>
</body>
Terry
  • 63,248
  • 15
  • 96
  • 118
0

UPDATE: I've found a trick to resolve the problem without altering overflow or html flow. The key is I need to change swiper-container's height whenever I hover a slide which contains dropdown-menu and switch back to original height when moving the cursor out of the slide. To do that, I need to set swiper-container pointer-events: none and dropdown pointer-events: auto. and then set a height for swiper-container when hovering.

Working code: https://jsfiddle.net/4nw05vyh/

const swiper = new Swiper(".myswiper",{
  speed:1000,
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
  slidesPerView: 'auto',
  initialSlide:0,
  loop:true,
  loopedSlides:3,
  visibilityFullFit: true,
  autoResize: false,
  spaceBetween: 0,
});
:root{
  --swiper-navigation-size:20px !important;
}
.slider-section{
  top:50px;
  position:relative;
  width:400px;
  height:50px;
  margin:auto;
}
.swiper-container{
  width:90%;
  height:100%;
  pointer-events:none;
  background-color:lightgray;
}
.swiper-container:hover{
  height:300px;
}
.dropdown{
  pointer-events:auto;
}
.swiper-container > .swiper-wrapper > .swiper-slide{
  width:100px;
  margin-left:30px;
  margin-top:10px;
}
<!DOCTYPE html>
<head>
  <script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css" />
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
  <div class="slider-section">
    <div class="swiper-container myswiper">
      <div class="swiper-wrapper">
        <div class="swiper-slide">
          <div class="dropdown">
            <a href="#" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
              <span>SLIDE 1</span>
            </a>
            <ul class="dropdown-menu">
              <li><a class="dropdown-item" href="#">Menu 1</a></li>
              <li><a class="dropdown-item" href="#">Menu 2</a></li>
            </ul>
          </div>
        </div>
        <div class="swiper-slide">
          <span>SLIDE 2</span>
        </div>
      </div>      
    </div>
    <div class="swiper-button-next"></div>
    <div class="swiper-button-prev"></div>
  </div>
</body>
MTLC
  • 53
  • 3
  • 7