Force Bootstrap dropdown menu to always display at the bottom and allow it go offscreen
Asked Answered
C

4

34

When there is no room at the bottom of the viewport to fit dropdown menu, it is displayed at the top of its dropdown button. Is it possible alter this behavior and make dropdown always appear at the bottom?

    <div class="dropdown">
  <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Dropdown button
  </button>
  <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
    <a class="dropdown-item" href="#">Action</a>
    <a class="dropdown-item" href="#">Another action</a>
    <a class="dropdown-item" href="#">Something else here</a>
  </div>
</div>
Chiquitachirico answered 11/11, 2017 at 20:57 Comment(0)
B
25

I wanted to tackle this problem with CSS alone.

Bootstrap's dropdown's uses Popper.js for the positioning of the dropdown menu. This makes the task challenging since Popper.js seems to check and evaluate the position of the dropdown when the window is scrolled so I needed to use an !important rule to override Popper.js.

Here's the code I came up with, based on your example.

.dropdown-menu{
    transform: translate3d(5px, 35px, 0px)!important;
}

Example codepen: https://codepen.io/Washable/pen/xPdqVp

This will always force the dropdown to be below the button, even if the button is at the bottom of the screen.

Bromide answered 12/11, 2017 at 12:28 Comment(0)
C
52

For Bootstrap 5 (≥ 5.0)

Completely disable Popper.js dynamic positioning by setting data-bs-display="static" on dropdown-toggle element (button or link).

From Bootstrap 5 Docs > Dropdowns: Options:

By default, we use Popper.js for dynamic positioning. Disable this with static.

.window {
    height: 8em;
    overflow: auto;
    margin: 1em;
    padding: 1em;
    border: 10px solid #DFEAF2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>

<div class="window">
    <div class="dropdown">
        <button data-bs-display="static" class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
            Dropdown dropdown-toggle with data-bs-display="static"
        </button>
        <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
            <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>
            <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>

For Bootstrap 4 (4.1 - 4.6)

Completely disable Popper.js dynamic positioning by setting data-display="static" on dropdown-toggle element (button or link) .

From Bootstrap 4 Docs > Dropdowns: Options:

By default, we use Popper.js for dynamic positioning. Disable this with static.

.window {
  height: 8em;
  overflow: auto;
  margin: 1em;
  padding: 1em;
  border: 10px solid #DFEAF2;
}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<div class="window">
  <div class="dropdown">
    <button data-display="static" class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      Dropdown dropdown-toggle with data-display="static"
    </button>
    <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
      <a class="dropdown-item" href="#">Action</a>
      <a class="dropdown-item" href="#">Another action</a>
      <a class="dropdown-item" href="#">Something else here</a>
      <a class="dropdown-item" href="#">Action</a>
      <a class="dropdown-item" href="#">Another action</a>
      <a class="dropdown-item" href="#">Something else here</a>
    </div>
  </div>
</div>
Constipation answered 23/8, 2018 at 8:58 Comment(0)
B
25

I wanted to tackle this problem with CSS alone.

Bootstrap's dropdown's uses Popper.js for the positioning of the dropdown menu. This makes the task challenging since Popper.js seems to check and evaluate the position of the dropdown when the window is scrolled so I needed to use an !important rule to override Popper.js.

Here's the code I came up with, based on your example.

.dropdown-menu{
    transform: translate3d(5px, 35px, 0px)!important;
}

Example codepen: https://codepen.io/Washable/pen/xPdqVp

This will always force the dropdown to be below the button, even if the button is at the bottom of the screen.

Bromide answered 12/11, 2017 at 12:28 Comment(0)
O
23

Bootstrap 4 uses Popper.js for positioning the dropdowns. Additionally, Bootstrap 4 allows you to pass some data-* attributes to control the behaviour of Popper.js on that dropdown.

The option that needs to be tweaked is the flip option of Popper.js. By default Bootstrap 4 sets this to true, causing dropdowns to appear above the dropdown-toggle element when there is not enough room at the bottom of the viewport.

To force the dropdown to always appear at the bottom, add data-flip="false" as an attribute of your dropdown-toggle element. For example:

<div class="dropdown">
  <button class="btn btn-secondary dropdown-toggle" data-flip="false" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Dropdown button
  </button>
  <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
    <a class="dropdown-item" href="#">Action</a>
    <a class="dropdown-item" href="#">Another action</a>
    <a class="dropdown-item" href="#">Something else here</a>
  </div>
</div>
Oxbow answered 13/6, 2018 at 3:2 Comment(3)
In Bootstrap ≥ 4.1 you can completely disable Popper.js dynamic positioning by setting data attribute data-display="static" See Bootstrap 4.1 Dropdowns OptionsQuesenberry
Completely disabling Popper.js will break the dropdown positioning. So the dropdown may not display below the dropdown button.Linville
This guy deserves a medal, or goldfish, or a hug from someone! Absolute legend and only solution from all the above that actually worked - keeping the menu under the button on all accounts.Inwardly
D
1

For Bootstrap 5 and above, to disable dynamic positioning, add this to the dropdown button class:

data-bs-display="static"

I had to do this because it was randomly putting the actual dropdown menu in the wrong spot depending on the scroll position of the window. Could have been a bug with Popper, Bootstrap 5.1, or Chromium... Not sure, that'd be a topic for another thread.

See here: https://getbootstrap.com/docs/5.1/components/dropdowns/#responsive-alignment

Decline answered 14/10, 2021 at 20:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.