Tailwind CSS does not provide a base set of components that are ready to use right out of the box. One of the most missing components are dropdowns .
Dropdowns are toggleable, contextual overlays for displaying lists of links and more.
They’re made interactive with a JavaScript.
Let’s have button first:
class = " border rounded py-2 px-3 shadow "
and some simple dropdown menu:
class = " hidden z-50 w-60 text-base bg-white rounded divide-y divide-gray-200 focus:outline-none "
class = " block rounded-t py-3 px-4 text-sm text-gray-800 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white "
Then you need to add some javascript to show or hide the menu by toggling hidden
class on the menu and Popper .
Popper will provide accurate position of this menu right under button and will solve all possible conflicts with menu and browser borders for you.
and craete dropdown-menu.js file with following content:
import { createPopper } from " @popperjs/core/lib/popper-lite.js " ;
import flip from " @popperjs/core/lib/modifiers/flip.js " ;
import preventOverflow from " @popperjs/core/lib/modifiers/preventOverflow.js " ;
* data-dropdown="[ID of dropdown element]"
* data-placement="[dropdown placement]"
export function addDropdown ( button ) {
const menu = document . querySelector ( ` # ${ button . dataset . dropdown } ` );
// Popper create instance
const popper = createPopper ( button , menu , {
placement: button . dataset . placement || " bottom-start " ,
modifiers: [ flip , preventOverflow ] ,
// toggle menu on button click
button . addEventListener ( " click " , async ( event ) => {
const menu = document . querySelector ( ` # ${ event . target . dataset . dropdown } ` );
menu . classList . toggle ( " hidden " );
event . target . setAttribute (
! menu . classList . contains ( " hidden " ) ,
await popper . update (); // reposition
// close dropdown menu on Escape or click somewhere else
function closeMenu ( event ) {
event . type === " click " &&
( event . target !== button || event . key === " Escape " )
menu . classList . add ( " hidden " );
button . setAttribute ( " aria-expanded " , false );
// remove close menu handlers
document . removeEventListener ( " click " , closeMenu );
document . removeEventListener ( " keydown " , closeMenu );
document . addEventListener ( " click " , closeMenu );
document . addEventListener ( " keydown " , closeMenu );
// let's add dropdown menu to all buttons
for ( const dropDownButton of inputDocument . querySelectorAll (
addDropdown ( dropDownButton );
You can find the whole example on my GitHub at OzzyCzech/tailwind-dropdowns