Dropdown
Dropdown provides end-users with a list of options on a temporary surface. It appears when the user interacts with a button, or other control.
- Markup
- Menu items
- Dense menu
- States
- Selected menu
- Positioning
- Sizing
- Carets
- Arrows
- CSS Customization
- JavaScript Instantiation
Markup
A basic menu opens underneath the anchor element by default (positioning can be changed via class modifiers). To create a menu:
- Create a wrapper element with the
.drop-container
class. - Nest any clickable element (usually
.btn
) with the.js-drop-trigger
class to control the dropdown. - Create the dropdown menu as the next sibling of the anchor element as
.drop-menu
. - Nest your menu as
.menu
inside the dropdown.
<div class="drop-container">
<button type="button" class="btn btn-dropdown">Dropdown trigger</button>
<div class="drop-menu js-drop-menu">
<ul class="menu">
<li>Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
</ul>
</div>
</div>
Menu items
Menu items have a few different options to provide additional content. To align content inside an item, wrap the main content in .item-body
with left or right content in .item-left
or .item-right
:
<ul class="menu">
<li>
<span class="item-left"><span class="fa fa-inbox color-gray-500"></span></span>
<span class="item-body">Inbox</span>
<span class="item-right"><span class="label">4</span></span>
</li>
</ul>
Use .menu-divider
on menu item to separate menu items or add .menu-header
to the first item to give a menu a heading:
<ul class="menu">
<li class="menu-header">Options</li>
...
<li class="menu-divider"></li>
...
</ul>
Dense menu
For larger menus with multiple items, you can use the .menu-dense
modifier on .menu
to reduce the padding and text size.
<div class="drop-container">
<button type="button" class="btn btn-dropdown js-drop-trigger">Dropdown trigger</button>
<div class="drop-menu js-drop-menu">
<ul class="menu menu-dense">
<li>Back</li>
<li>Forward</li>
<li>Reload</li>
<li class="menu-divider"></li>
<li>Save As...</li>
<li>Print...</li>
<li>Cast...</li>
<li class="menu-divider"></li>
<li>View Page Source</li>
<li>Inspect</li>
</ul>
</div>
</div>
States
Menu items come with a handful of convenient states to help with different use-cases. Add the classes .active
.selected
or .disabled
to a list item to help provide context:
<ul class="menu">
<li class="disabled">.disabled</li>
<li class="active">.active</li>
<li class="selected">.selected</li>
<li class="checked">
<span class="item-body">.checked</span>
<span class="item-right"><span class="fa fa-check"></span>
</li>
</ul>
Selected Menu
Dropdown offers three different options for selectable menus.
.js-select-menu
- Add this modifier class to the.menu
to toggle the.selected
class on items when clicked..js-check-menu
- Add this modifier class to the.menu
to toggle the.checked
class on items when clicked..js-active-menu
- Add this modifier class to the.menu
to toggle the.active
class on items when clicked.
Note that when using the .js-menu-check
modifier, Frontbx will automatically include a checkmark on the checked item.
<div class="drop-container">
<input type="hidden" name="menu" value="">
<button type="button" class="btn btn-dropdown js-drop-trigger">.js-select-menu</button>
<div class="drop-menu js-drop-menu">
<ul class="menu js-select-menu">
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
<li>Option 5</li>
<li>Option 6</li>
</ul>
</div>
</div>
Additionally, adding the js-drop-selectable
modifier to the anchor element will replace the anchor element innerText
with the text of a selected menu item.
You may also nest a hidden input
inside the .drop-container
to store the input value of the selected menu item. If items have a data-value
attribute - the input value will be updated to this attribute rather than the text of the menu item.
<div class="drop-container">
<input type="hidden" name="menu" value="">
<button type="button" class="btn btn-dropdown js-drop-trigger js-drop-selectable">.js-select-menu</button>
<div class="drop-menu js-drop-menu">
<ul class="menu js-select-menu">
<li data-value="1">Option 1</li>
<li data-value="2">Option 2</li>
<li data-value="3">Option 3</li>
<li data-value="4">Option 4</li>
<li data-value="5">Option 5</li>
<li data-value="6">Option 6</li>
</ul>
</div>
</div>
Positioning
You can change the alignment of the dropdown to different directions by adding a directional class to the .drop-menu
element. The directions are .drop-s
.drop-se
.drop-sw
.drop-n
.drop-ne
.drop-nw
<div class="drop-container">
<button type="button" class="btn btn-dropdown js-drop-trigger">.drop-s</button>
<div class="drop-menu drop-s js-drop-menu">
...
</div>
</div>
Sizing
Dropdown height is sized via max-height
on .menu
. This value can be overidden via either Sass or CSS variables.
.drop-container {
--fbx-dropdown-height: 300px;
}
Dropdown width is sized via min-width
on .menu
. This value can be overidden via either Sass or CSS variables. Longer text will wrap, however you can add menu-ellipsis
to the menu to prevent this from happening
.drop-container {
--fbx-dropdown-width: 160px;
}
<ul class="menu menu-ellipsis">
<li><span class="item-body">Menu item with additional text that spills over</span></li>
</ul>
Carets
Add a caret to the button by using either a .caret-s
or caret-n
element inside inside the button or a caret icon
<button type="button" class="btn btn-dropdown js-drop-trigger">
.caret-s <span class="caret-s"></span>
</button>
Arrows
Add an arrow on the border of the dropdown using the .arrow
with an arrow position arrow-[position]
class. Arrow positions are .arrow-s
.arrow-se
.arrow-sw
.arrow-n
.arrow-ne
.arrow-nw
<div class="drop-container">
...
<div class="drop-menu drop-s arrow arrow-n js-drop-menu">
...
</div>
</div>
CSS Customization
Dropdown uses local CSS variables on .drop-container
and .menu
along with Sass variables for enhanced component customization and styling. The base values are used by the UI to create all the styling. Values for the CSS variables are set via Sass, so pre-compilation customization is still supported too.
.custom-drop
{
--fbx-dropdown-bg: var(--fbx-black);
}
.custom-drop .menu
{
--fbx-menu-color: var(--fbx-white);
--fbx-menu-item-color-hover: var(--fbx-white);
--fbx-menu-item-color-active: var(--fbx-theme-primary);
--fbx-menu-item-color-selected: var(--fbx-theme-primary);
--fbx-menu-item-bg-hover: var(--fbx-gray-900);
--fbx-menu-item-bg-active: var(--fbx-gray-900);
--fbx-menu-item-bg-selected: var(--fbx-gray-900);
--fbx-menu-divider-color: var(--fbx-gray-600);
}
Default values are set in the scss/_config.scss
file in Frontbx's source.
scss/_config.scss
// Dropdown
$dropdown-border-radius: var(--fbx-border-radius) !default;
$dropdown-width: 160px !default;
$dropdown-height: 300px !default;
$dropdown-shadow-level: 2 !default;
$dropdown-bg: var(--fbx-white) !default;
// Menu
$menu-bg: var(--fbx-white) !default;
$menu-color: var(--fbx-gray-700) !default;
$menu-font-size: 1.3rem !default;
$menu-item-bg: transparent !default;
$menu-item-color-hover: var(--fbx-gray-700) !default;
$menu-item-color-active: var(--fbx-gray-700) !default;
$menu-item-color-selected: var(--fbx-white) !default;
$menu-item-bg-hover: var(--fbx-gray-200) !default;
$menu-item-bg-active: var(--fbx-theme-info-100) !default;
$menu-item-bg-selected: var(--fbx-theme-info) !default;
$menu-item-pad-y: 10px !default;
$menu-item-pad-x: 12px !default;
$menu-divider-color: var(--fbx-gray-200) !default;
$menu-divider-space: 5px;
scss/components/dropdown.scss
.drop-container {
--fbx-dropdown-border-radius: var(--fbx-border-radius);
--fbx-dropdown-width: 160px;
--fbx-dropdown-height: 300px;
--fbx-dropdown-bg: var(--fbx-white);
}
scss/components/menu.scss
.menu {
--fbx-menu-bg: var(--fbx-white);
--fbx-menu-color: var(--fbx-gray-700);
--fbx-menu-font-size: 1.3rem;
--fbx-menu-item-color-hover: var(--fbx-gray-700);
--fbx-menu-item-color-active: var(--fbx-gray-700);
--fbx-menu-item-color-selected: var(--fbx-white);
--fbx-menu-item-bg: transparent;
--fbx-menu-item-bg-hover: var(--fbx-gray-200);
--fbx-menu-item-bg-active: var(--fbx-theme-info-100);
--fbx-menu-item-bg-selected: var(--fbx-theme-info);
--fbx-menu-item-pad-y: 10px;
--fbx-menu-item-pad-x: 12px;
--fbx-menu-divider-color: var(--fbx-gray-200);
--fbx-menu-divider-space: 5px;
}
JavaScript Instantiation
Dropdown can be instantiated via JavaScript to generate dynamic content on the fly. To create a Dropdown dynamically, use Frontbx's Component.Create
method either via the frontbx.Dom
or the Dropdown Component directly:
let options =
{
anchorText: 'Basic',
items:
[
'Option One',
{
left: '<span class="fa fa-sun"></span>',
body: 'Option Two'
},
{
left: '<span class="fa fa-sun"></span>',
body: 'Option 3',
right: '<span class="fa fa-user"></span>',
}
]
};
let container = document.querySelector('.my-container');
// Via Frontbx dom
frontbx.Dom().create('Dropdown', options, container);
// Or via Component directly
frontbx.Dom().component('Dropdown').create(options, container);
Below are the available options
Option | Default | Example | Behavior |
---|---|---|---|
anchorTag |
button |
div |
Tag element for anchor element |
anchorClass |
'' |
my-button |
Additional class name(s) on anchor element. |
anchorText |
'' |
click me |
Text inside anchor element |
caret |
false |
s |
Adds caret to anchor element - either n or s |
position |
sw |
ne' |
Position of dropdown menu |
dense |
false |
true |
Makes dense menu |
ellipsis |
false |
true |
Makes dropdown menu text overflow ellipsis |
checkable |
false |
true |
Checkable menu items with checkmarks |
selectable |
false |
true |
Adds a hidden input and makes menu items selectable |
input |
null |
myinput |
Hidden input name attribute when selectable is true |
selected |
null |
option 2 |
Text or value of default selected item when selectable or checkable is true |
items |
[] |
['option 1', 'option 2'] |
Array of menu items as text or objects with sub item properties |
items.item.left |
null |
{left:<span class="fa fa-sun"></span>' |
Optional HTML string of optional menu item left |
items.item.right |
null |
{right: '<span class="fa fa-user"></span>' |
Optional HTML string of optional menu item right |
items.item.body |
null |
{right: 'Option 1' |
Optional HTML string or text of optional menu item body |
items.item.state |
null |
{state: 'selected' |
Optional Menu item state class |