--- layout: layouts/page.njk title: Dropdown Menu description: Displays a menu to the user — such as a set of actions or functions — triggered by a button. toc: - label: Usage id: usage children: - label: HTML + JavaScript id: usage-html-js children: - label: "Step 1: Include the JavaScript files" id: usage-html-js-1 - label: "Step 2: Add your dropdown menu HTML" id: usage-html-js-2 - label: HTML structure id: usage-html-js-3 - label: Jinja and Nunjucks id: usage-macro - label: Examples id: examples children: - label: Checkboxes id: example-checkboxes - label: Radio Group id: example-radio-group --- {% from "macros/code_block.njk" import code_block %} {% from "macros/code_preview.njk" import code_preview %} {% from "dropdown-menu.njk" import dropdown_menu %} {% set code_html %} {% call dropdown_menu( id="demo-dropdown-menu", trigger="Open", trigger_attrs={"class": "btn-outline"}, popover_attrs={"class": "min-w-56"} ) %}
My Account


{% endcall %} {% endset %} {{ code_preview("dropdown-menu", code_html | prettyHtml) }}

Usage

HTML + JavaScript

Step 1: Include the JavaScript files

Include the dropdown-menu.js file. It is recommended to also include the CSS anchor positioning polyfill to support older browsers. Add this to the <head> of your page:

{% set code_script %} {% endset %} {{ code_block(code_script | prettyHtml, "html") }}
Components with JavaScript {% lucide "arrow-right" %} Use the CLI {% lucide "arrow-right" %} dropdown-menu.js {% lucide "arrow-right" %}

Step 2: Add your dropdown menu HTML

{{ code_block(code_html | prettyHtml, "html") }}

HTML structure

<div class="dropdown-menu">
Wraps around the entire component.
<button type="button" popovertarget="{ POPOVER_ID }">

The trigger to open the popover, can also have the following attributes:

  • id="{BUTTON_ID}": linked to by the aria-labelledby attribute of the listbox.
  • aria-haspopup="menu": indicates that the button opens a menu.
  • aria-controls="{ MENU_ID }": points to the menu's id.
  • aria-expanded="false": tracks the popover's state.
<div popover class="popover" id="{ POPOVER_ID }">
As with the Popover component, you can set up the side and alignment of the popover using the data-side and data-align attributes.
<div role="menu">
The menu containing the options. Should have the following attributes:
  • id="{ MENU_ID }": refered to by the aria-controls attribute of the trigger.
  • aria-labelledby="{ BUTTON_ID }": linked to by the button's id attribute.
<button role="menuitem">
Menu item.
<button role="menuitemcheckbox">
Menu item with a checkbox.
<button role="menuitemradio">
Menu item with a radio button.
<hr role="separator"> Optional
Separator between groups/options.
<div role="group"> Optional
Group of options, can have a aria-labelledby attribute to link to a heading.
<span role="heading">
Group heading, must have an id attribute if you use the aria-labelledby attribute on the group.

Jinja and Nunjucks

You can use the dropdown_menu() Nunjucks or Jinja macro for this component.

Use Nunjucks or Jinja macros {% lucide "arrow-right" %} Jinja macro {% lucide "arrow-right" %} Nunjucks macro {% lucide "arrow-right" %}
{% set raw_code %}{% raw %}{% call dropdown_menu( id="dropdown-menu", trigger="Open", trigger_attrs={"class": "btn-outline"}, content_attrs={"class": "min-w-56"}, register_on=["alpine:init", "htmx:afterSwap"] ) %}
My Account


{% endcall %}{% endraw %}{% endset%} {{ code_block(raw_code, "jinja") }}

Examples

Checkboxes

{% set code %}{% call dropdown_menu( id="dropdown-menu-checkboxes", trigger="Open", trigger_attrs={"class": "btn-outline"}, content_attrs={"class": "min-w-56"}, register_on=["alpine:init", "htmx:afterSwap"] ) %}
Account Options

Appearance

{% endcall %}{% endset %} {{ code_preview("dropdown-menu-checkboxes", code | prettyHtml) }}

Radio Group

{% set code %}{% call dropdown_menu( id="dropdown-menu-radio-group", trigger="Open", trigger_attrs={"class": "btn-outline"}, popover_attrs={"class": "min-w-56"} ) %}
Panel Position
{% endcall %}{% endset %} {{ code_preview("dropdown-menu", code | prettyHtml) }}