How to append the bootstrap 5 dropdown menu to a specific element. when the dropdown element is inside an element with overflow: hidden

Viewed 1060

I am use Bootstrap 5 dropdown menu inside owl-carousel. but dropdown is being cut off because has outer div overflow:hidden in owl-carousel.

enter image description here

Complete snippet here: jsfiddle

So, I have try to position a dropdown relatively to body, not parent with boundary option from Bootstrap Docs,

Bootstrap docs says that can only be done via javascript (not via data attributes),
so I have try below javascript methods code. but no luck.

var dropdownElementList = [].slice.call(document.querySelectorAll('.dropdown-toggle'))
    var dropdownList = dropdownElementList.map(function (dropdownToggleEl) {
      return new bootstrap.Dropdown(dropdownToggleEl, {
        boundary: document.querySelector('#main-wrapper')
      })
    })

Any suggestions with proper solution for where I'm going wrong would be greatly appreciated.

Our HTML Code:

<div id="main-wrapper">
<div class="owl-carousel owl-theme">
  <div class="item">
    <div class="d-flex align-items-center">
      <h4>Shilipp Sotocnik</h4>
      
      <div class="dropdown dropdown-lg d-inline-block ms-auto"> 
      <a href="#" role="button" id="dropdownMenu1" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-ellipsis-h"></i></a>
        <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenu1">
          <li><a class="dropdown-item" href="#">Link 1</a></li>
          <li><a class="dropdown-item" href="#">Link 2</a></li>
          <li><a class="dropdown-item" href="#">Link 3</a></li>
          <li><a class="dropdown-item" href="#">Link 4</a></li>
        </ul>
      </div>
      
    </div>
  </div>
</div>
</div>
5 Answers

To avoid changing the properties of the carousel blocks, adding extra layout blocks, and playing with the overflow property, we can move the dropdown menu outside of the carousel.

  1. the .each() method goes through all the carousels on the page;
  2. the .on() method with a selector attachs a delegated event handler for events from the item clones that can be created by the Owl Carousel at a later time;
  3. the show.bs.dropdown event fires immediately when the show method is called;
  4. the getInstance method returns the dropdown instance associated to a DOM element;
  5. the .insertAfter() method inserts element after the target.

In our case the dropdown menus will be moved, not copied:

If an element selected this way is inserted into a single location elsewhere in the DOM, it will be moved after the target (not cloned) and a new set consisting of the inserted element is returned

And I think we do not need to return them to their original place after closing. If this is still needed, then this can be done by analogy with the hidden.bs.dropdown event.

https://jsfiddle.net/glebkema/s0yua1w7/

$(function() {

  $('.owl-carousel')
    .each(function() {
      let carousel = $(this);
      carousel.on('show.bs.dropdown', '[data-bs-toggle=dropdown]', function() {
        // universal solution
        let dropdown = bootstrap.Dropdown.getInstance(this);
        $(dropdown._menu).insertAfter(carousel);

                // alternative for this particular layout
        // $(this).next('.dropdown-menu').insertAfter(carousel);
      });
    })
    .owlCarousel({
      loop:true,
      margin:15,
      nav:true,
    });

});
<div class="py-5 mx-4">

  <h2>First Owl Carousel</h2>

  <div class="owl-carousel owl-theme">
    <div class="item card">
      <div class="d-flex align-items-center p-3">
        <h5>Shilipp Sotocnik 1</h5>
        <div class="dropdown dropdown-lg d-inline-block ms-auto"> 
          <a href="#" role="button" id="dropdownMenu1" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-ellipsis-h"></i></a>
          <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenu1">
            <li><a class="dropdown-item" href="#">Link 1</a></li>
            <li><a class="dropdown-item" href="#">Link 2</a></li>
            <li><a class="dropdown-item" href="#">Link 3</a></li>
            <li><a class="dropdown-item" href="#">Link 4</a></li>
            <li><a class="dropdown-item" href="#">Link 5</a></li>
            <li><a class="dropdown-item" href="#">Link 6</a></li>
          </ul>
        </div>
      </div>
      <p class="px-3">
        Lorem ipsum dummy
      </p>    
    </div>

    <div class="item card">
      <div class="d-flex align-items-center p-3">
        <h5>Shilipp Sotocnik 2</h5>
        <div class="dropdown dropdown-lg d-inline-block ms-auto"> 
          <a href="#" role="button" id="dropdownMenu2" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-ellipsis-h"></i></a>
          <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenu2">
            <li><a class="dropdown-item" href="#">Link 1</a></li>
            <li><a class="dropdown-item" href="#">Link 2</a></li>
            <li><a class="dropdown-item" href="#">Link 3</a></li>
            <li><a class="dropdown-item" href="#">Link 4</a></li>
            <li><a class="dropdown-item" href="#">Link 5</a></li>
            <li><a class="dropdown-item" href="#">Link 6</a></li>
            <li><a class="dropdown-item" href="#">Link 7</a></li>
            <li><a class="dropdown-item" href="#">Link 8</a></li>
          </ul>
        </div>
      </div>
      <p class="px-3">
        Lorem ipsum dummy
      </p>    
    </div>

    <div class="item card">
      <div class="d-flex align-items-center p-3">
        <h5>Shilipp Sotocnik 3</h5>
        <div class="dropdown dropdown-lg d-inline-block ms-auto"> 
          <a href="#" role="button" id="dropdownMenu3" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-ellipsis-h"></i></a>
          <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenu3">
            <li><a class="dropdown-item" href="#">Link 1</a></li>
            <li><a class="dropdown-item" href="#">Link 2</a></li>
            <li><a class="dropdown-item" href="#">Link 3</a></li>
            <li><a class="dropdown-item" href="#">Link 4</a></li>
            <li><a class="dropdown-item" href="#">Link 5</a></li>
            <li><a class="dropdown-item" href="#">Link 6</a></li>
            <li><a class="dropdown-item" href="#">Link 7</a></li>
            <li><a class="dropdown-item" href="#">Link 8</a></li>
            <li><a class="dropdown-item" href="#">Link 9</a></li>
            <li><a class="dropdown-item" href="#">Link 10</a></li>
          </ul>
        </div>
      </div>
      <p class="px-3">
        Lorem ipsum dummy
      </p>    
    </div>

    <div class="item card">
      <div class="d-flex align-items-center p-3">
        <h5>Shilipp Sotocnik 4</h5>
        <div class="dropdown dropdown-lg d-inline-block ms-auto"> 
          <a href="#" role="button" id="dropdownMenu4" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-ellipsis-h"></i></a>
          <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenu4">
            <li><a class="dropdown-item" href="#">Link 1</a></li>
            <li><a class="dropdown-item" href="#">Link 2</a></li>
            <li><a class="dropdown-item" href="#">Link 3</a></li>
            <li><a class="dropdown-item" href="#">Link 4</a></li>
            <li><a class="dropdown-item" href="#">Link 5</a></li>
            <li><a class="dropdown-item" href="#">Link 6</a></li>
            <li><a class="dropdown-item" href="#">Link 7</a></li>
            <li><a class="dropdown-item" href="#">Link 8</a></li>
            <li><a class="dropdown-item" href="#">Link 9</a></li>
            <li><a class="dropdown-item" href="#">Link 10</a></li>
            <li><a class="dropdown-item" href="#">Link 11</a></li>
            <li><a class="dropdown-item" href="#">Link 12</a></li>
          </ul>
        </div>
      </div>
      <p class="px-3">
        Lorem ipsum dummy
      </p>    
    </div>
  </div>

  <h2>Second Owl Carousel</h2>

  <div class="owl-carousel owl-theme">
    <div class="item card">
      <div class="d-flex align-items-center p-3">
        <h5>Shilipp Sotocnik 1</h5>
        <div class="dropdown dropdown-lg d-inline-block ms-auto"> 
          <a href="#" role="button" id="dropdownMenu21" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-ellipsis-h"></i></a>
          <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenu21">
            <li><a class="dropdown-item" href="#">Link 1</a></li>
            <li><a class="dropdown-item" href="#">Link 2</a></li>
            <li><a class="dropdown-item" href="#">Link 3</a></li>
            <li><a class="dropdown-item" href="#">Link 4</a></li>
            <li><a class="dropdown-item" href="#">Link 5</a></li>
            <li><a class="dropdown-item" href="#">Link 6</a></li>
          </ul>
        </div>
      </div>
      <p class="px-3">
        Lorem ipsum dummy
      </p>    
    </div>

    <div class="item card">
      <div class="d-flex align-items-center p-3">
        <h5>Shilipp Sotocnik 2</h5>
        <div class="dropdown dropdown-lg d-inline-block ms-auto"> 
          <a href="#" role="button" id="dropdownMenu22" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-ellipsis-h"></i></a>
          <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenu22">
            <li><a class="dropdown-item" href="#">Link 1</a></li>
            <li><a class="dropdown-item" href="#">Link 2</a></li>
            <li><a class="dropdown-item" href="#">Link 3</a></li>
            <li><a class="dropdown-item" href="#">Link 4</a></li>
            <li><a class="dropdown-item" href="#">Link 5</a></li>
            <li><a class="dropdown-item" href="#">Link 6</a></li>
            <li><a class="dropdown-item" href="#">Link 7</a></li>
            <li><a class="dropdown-item" href="#">Link 8</a></li>
          </ul>
        </div>
      </div>
      <p class="px-3">
        Lorem ipsum dummy
      </p>    
    </div>

    <div class="item card">
      <div class="d-flex align-items-center p-3">
        <h5>Shilipp Sotocnik 3</h5>
        <div class="dropdown dropdown-lg d-inline-block ms-auto"> 
          <a href="#" role="button" id="dropdownMenu23" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-ellipsis-h"></i></a>
          <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenu23">
            <li><a class="dropdown-item" href="#">Link 1</a></li>
            <li><a class="dropdown-item" href="#">Link 2</a></li>
            <li><a class="dropdown-item" href="#">Link 3</a></li>
            <li><a class="dropdown-item" href="#">Link 4</a></li>
            <li><a class="dropdown-item" href="#">Link 5</a></li>
            <li><a class="dropdown-item" href="#">Link 6</a></li>
            <li><a class="dropdown-item" href="#">Link 7</a></li>
            <li><a class="dropdown-item" href="#">Link 8</a></li>
            <li><a class="dropdown-item" href="#">Link 9</a></li>
            <li><a class="dropdown-item" href="#">Link 10</a></li>
          </ul>
        </div>
      </div>
      <p class="px-3">
        Lorem ipsum dummy
      </p>    
    </div>

    <div class="item card">
      <div class="d-flex align-items-center p-3">
        <h5>Shilipp Sotocnik 4</h5>
        <div class="dropdown dropdown-lg d-inline-block ms-auto"> 
          <a href="#" role="button" id="dropdownMenu24" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i class="fas fa-ellipsis-h"></i></a>
          <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="dropdownMenu24">
            <li><a class="dropdown-item" href="#">Link 1</a></li>
            <li><a class="dropdown-item" href="#">Link 2</a></li>
            <li><a class="dropdown-item" href="#">Link 3</a></li>
            <li><a class="dropdown-item" href="#">Link 4</a></li>
            <li><a class="dropdown-item" href="#">Link 5</a></li>
            <li><a class="dropdown-item" href="#">Link 6</a></li>
            <li><a class="dropdown-item" href="#">Link 7</a></li>
            <li><a class="dropdown-item" href="#">Link 8</a></li>
            <li><a class="dropdown-item" href="#">Link 9</a></li>
            <li><a class="dropdown-item" href="#">Link 10</a></li>
            <li><a class="dropdown-item" href="#">Link 11</a></li>
            <li><a class="dropdown-item" href="#">Link 12</a></li>
          </ul>
        </div>
      </div>
      <p class="px-3">
        Lorem ipsum dummy
      </p>    
    </div>
  </div>

  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sunt doloribus ipsa at culpa fugit nesciunt nulla rem inventore eum perspiciatis assumenda ipsam aut architecto unde laboriosam totam fuga in, dolore.</p>
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.carousel.min.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.theme.default.min.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">

Use jQuery to listen events on dropdown to toggle overflow class at element
<div class="owl-stage-outer">.

$('a[data-bs-toggle="dropdown"]').on('show.bs.dropdown', function () {
    $(".owl-stage-outer").addClass("overflow_none");
})

$('a[data-bs-toggle="dropdown"]').on('hide.bs.dropdown', function () {
    $(".owl-stage-outer").removeClass("overflow_none");
})
.overflow_none  {
  overflow: unset !important;
}

Have you tried this in css?

.owl-stage-outer {
  overflow: visible !important;  
}

Does the overflow hidden property really need to be there?

Alternatively, if you are using one class with the overflow hidden attribute, you could make an exception to this one div. To do that, give an ID to the specific div you want to target, now add overflow: visible !important; to that div.

this is what actually happens when you activate owl-carousel, see the markup below-

<div class="owl-carousel owl-theme owl-loaded">
    <div class="owl-stage-outer">
        <div class="owl-stage">
            <div class="owl-item">...</div>
            <div class="owl-item">...</div>
            <div class="owl-item">...</div>
        </div>
    </div>
</div>

I'm not gonna talk about dots or nav, those aren't relevant here. I want to bring your attention to the class named- owl-stage-outer. this is the class that contains the CSS of overflow: hidden;. These 2 classes- owl-stage-outer & owl-stage are generated from owl-carousel.

To prevent this, you can add a Bootstrap class .overflow-visible with owl-stage-outer. Since the owl-stage-outer class is not hard-code markup, there is an option in owl-carousel doc to customize this class. See the picture below, it's from the doc page- enter image description here

Now, another issue could appear, since you added .overflow-visible class with owl-stage-outer, the items that should be outside of the view, some of them will be visible now. To prevent that you will need to change a little bit of markup and add one line of CSS.

In this example, you have px-4 Bootstrap class in your main-wrapper id, change the px-4 to mx-4 and add the CSS of overflow-x: hidden; to #main-wrapper

And that's it, this could help you fix the issue. Here is the live fixed version of what I'm trying to say, good luck.

Update

Since our current example is having a scrollbar when dropdown menu is triggered, I have made some changes in CSS only-

body {overflow-x: hidden;}

#main-wrapper .owl-item {
    visibility: hidden;
    opacity: 0;
}

#main-wrapper .owl-item.active {
    visibility: visible;
    opacity: 1;
}

Here is the live example.

Related