Reputation: 121
Trying to create a filter on a web page that utilizes Bootstrap's drop-down menu and places each filter in columns side-by-side, but instead it stacks them right now. The filter menu is created dynamically by looping through an array of items I want to create and each item is a new column I want to place on my menu. I was trying to utilize the grid layout (container > row > column) with the class row-cols-# on my row element but that does not work as I thought it would.
I can force my menu to be a certain width using the style
property and make the columns position correctly, but then my menu is no longer sizing appropriately based on n columns.
I am utilizing d-flex, flex-row and flex-column to create my sidebar navigation and and I am wondering if that is causing some of the issues?
Here is a sample of webpage stripped-down to illustrate. Filter Menu Help
Upvotes: 1
Views: 483
Reputation: 1315
The main reason they're stacking is because you're using .col-auto
while .row
by default has flex-wrap: wrap;
, so it will keep each column as small as possible and wrap them.
The second reason is that the dropdown-menu
is positioned absolutely but relatively to the .dropdown
wrapper. Because you positioned the wrapper on the right side of the page, the dropdown-menu
won't grow in width as you would expect.
So:
max-width
on the dropdown-menu
.<div class="dropdown"></div>
wrapper.Here's an example how you could make your dropdown in Codeply using your layout.
On small screen sizes the columns will stack using <div class="row flex-column flex-sm-row">
. Each filter column utilizes a list <ul><li>...</li></ul>
to contain the check-boxes and for easy styling.
<form class="dropdown-menu p-2 mt-1 overflow-auto">
<div class="container-fluid">
<div class="row flex-column flex-sm-row">
<ul class="col list-unstyled">
<li>
<h6 class="dropdown-header">Dropdown header</h6>
<hr class="dropdown-divider">
</li>
<li>
<input class="form-check-input me-1" type="checkbox" value="" id="first">
<label class="form-check-label stretched-link" for="first">First checkbox</label>
</li>
<li>
<input class="form-check-input me-1" type="checkbox" value="" id="second">
<label class="form-check-label stretched-link" for="second">Second checkbox</label>
</li>
<li>
<input class="form-check-input me-1" type="checkbox" value="" id="third">
<label class="form-check-label stretched-link" for="third">Third checkbox</label>
</li>
</ul>
<ul class="col list-unstyled">
...
</ul>
</div>
<div class="d-flex justify-content-end gap-3">
<button type="reset" class="btn btn-sm btn-warning clear-filter">Clear Filter</button>
<button type="submit" class="btn btn-sm btn-danger">Submit</button>
</div>
</div>
</form>
To tell Flex when to start wrapping the columns, set a max-width
on the dropdown-menu
. For the example I set it to 75vw
but it can by any width you want. You can use row-cols-*
instead, but you will have to add a column number for every break point, like .row-cols-1 row-cols-sm-2 row-cols-md-4
whereas setting a max-width
is just easier to maintain and looks better visually with how the columns will stretch.
For the stretched-link
to work the parent must have position: relative;
applied to it. And whitespace: nowrap;
is used to keep each <label>
in-line with the checkbox.
form {
max-width: 75vw;
max-height: 80vh;
}
.col li {
position: relative;
white-space: nowrap;
}
Lastly, to prevent the dropdown-menu
from closing when interacting with it add data-bs-auto-close="outside"
on the <button>
toggler.
Upvotes: 1