As already asked here, i need to add dropdown into the table element which has scroll to x-direction (horizontal scroll) and in the last column there is one three dot icon where I need to add dropdown element. But dropdown menu always clips inside the table which is not good user experience.
As per the, Bootstrap doc, there is option named boundary
but I am not getting how this boundary option works or even don;t know whether it entirely works or not and how.
If i remove relative position from dropdown parent which is with class dropdown
and also remove from all the ancestors which is not static then I am getting correct behavior. I don;t feel it's the correct way to remove position relative only for getting this dropdown-menu out of container.
Is this the only solution or the boundary
makes sense? I am not getting how popperconfig
works and how should I use boundary
aka data-bs-boundary
?
In earlier version of bootstrap, with some code tweak, I used to get entire dropdown all the way at the end of the body element but not sure with this.
So here there are multiple things to consider when dropdown actually clips under the overflow parent/one of the ancestor parents(grand, great-grand and so on...)
When applying fixed position to dropdown menu is just enough to get it working and if there are no other parents that might create stacking context where fixed position might be constrained, then you can simply get it on the top of everything using standard bootstrap popperConfig strategy option and no need to take it out of current position. Here it will apply position to fixed
instead of absolute
when dropdown is opened.
let myDropdown = new bootstrap.Dropdown(element, {
popperConfig: function (defaultBsPopperConfig) {
const newPopperConfig = { strategy: "fixed"}
//merge default configuration from bootstrap to our own configuration and return merged config
return Object.assign(defaultBsPopperConfig, newPopperConfig);
}
})
but when it is even not enough, we need to do following.
Considering that there are multiple dropdowns with id's like myPopperDropdown-1, 2 etc.. which all are clipped under overflow hidden on one of the parent/s, we can do something like this.
$("[id*='myPopperDropdown-']").each(function(el,index) {
var parent, dropdownMenu, left, top;
$(this).on('show.bs.dropdown',function(){
parent = $(this).parent();
dropdownMenu = $(this).find('.dropdown-menu');
left = dropdownMenu.offset().left - $(window).scrollLeft();
top = dropdownMenu.offset().top - $(window).scrollLeft();
$('body').append(dropdownMenu.css({
position:'fixed',
left: left,
top: top
}).detach());
})
$(this).on('hidden.bs.dropdown',function(){
$(this).append(dropdownMenu.css({
position:'absolute', left:false, top:false
}).detach());
})
})
body {margin: 10px !important}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="card">
<div class="card-body bg-light overflow-hidden">
<div class="bs-dropdown-1">
<div class="dropdown" id="myPopperDropdown-1">
<a class="btn btn-primary dropdown-toggle" role="button" href="javascript:void(0)" aria-expanded="false" data-bs-toggle="dropdown">Dropdown-1</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
</div>
</div>
<div class="card-body bg-light overflow-hidden mt-3">
<div class="bs-dropdown-2">
<div class="dropdown" id="myPopperDropdown-2">
<a class="btn btn-primary dropdown-toggle" role="button" href="javascript:void(0)" aria-expanded="false" data-bs-toggle="dropdown">Dropdown-2</a>
<ul class="dropdown-menu" style="position: absolute;">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul></div>
</div>
</div>
</div>
As of now not found any other better solution than this and even changing in popperConfig
also not working due to restrictions applied even on fixed positioning.
Original answer was at Bootstrap dropdown clipped by overflow:hidden container, how to change the container?. which is somewhat modified here.