Dropdown with CSS / Tailwind

1- CSS Way

In this article, I would like to show you, how to create dropdown menus with CSS. For do that, we will use :focus-within. New CSS features, make things easier :)

So what we need? First, we need a <div> and inside of div, we need <button> (because it is focusable) and <nav> for dropdown menu.

Let's create HTML structure first.

<div class="dropdown">
    <button>Menü</button>
    <nav>
        <ul>
            <li>
                <a href="#">
                    Edit
                </a>
            </li>
            <li>
                <a href="#">
                    Delete
                </a>
            </li>
            <li>
                <a href="#">
                    Reply
                </a>
            </li>
        </ul>
    </nav>
</div>

So first, I have to hide my <nav> tag.

.dropdown nav {
   display: none;
}

And now, when I clicked to <button>, I need to show <nav> tag again. To do that, I will use :focus-within. Let's make it.

.dropdown nav {
    display: none;
}
.dropdown:focus-within nav {
    display: block
}

This will works. But with 1 problem. Which is, if I click to nav tag (except <a> tag inside) <nav> tag will be closed because it will lose focusable and :focus-within will no longer work.

So, if this is a problem for you, you can add [tabindex="0"] to your <nav> tag. When you do that, <nav> become focusable as well. Let's do that.

<div class="dropdown">
    <button>Menü</button>
    <nav tabindex="0">
        <ul>
            ....
        </ul>
    </nav>
</div>

I know it looks ugly :) Let's make it beauty. I will use SASS, you can use anything to style it.

* {
    padding: 0;
    margin: 0;
    list-style: none;
    border: 0;
    text-decoration: none;
    box-sizing: border-box;
}
body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
.dropdown {
    position: relative;
    button {
        height: 2.5rem;
        padding: 0 1.25rem;
        background: #333;
        color: #fff;
        border-radius: 0.25rem;
        font-size: 1rem;
        cursor: pointer;
    }
    nav {
        position: absolute;
        top: 100%;
        left: 0;
        opacity: 0;
        visibility: hidden;
        transition: 300ms all;
        border: 2px solid #333;
        border-radius: 0.25rem;
        width: 12.5rem;
        ul {
            padding: 0.188rem 0;
            li {
                a {
                    display: block;
                    padding: 0.438rem 0.625rem;
                    color: #333;
                    &:hover {
                        background: #f8f8f8;
                    }
                }
            }
        }
    }
    &:focus-within nav {
        opacity: 1;
        visibility: visible;
        transform: translateY(0.25rem);
    }
}

Alright, it look fine now :)

You can checkout on codepen.

2- Tailwind Way

Using without using CSS, how we can make it faster? Yes, using tailwind :D Let's make it same dropdown with tailwind.

<div class="p-4">
    <div class="group relative">
        <button class="bg-gray-800 text-white px-6 h-10 rounded">Menü</button>
        <nav tabindex="0" class="border border-2 bg-white invisible border-gray-800 rounded w-60 absolute left-0 top-full transition-all opacity-0 group-focus-within:visible group-focus-within:opacity-100 group-focus-within:translate-y-1">
            <ul class="py-1">
                <li>
                    <a href="#" class="block px-4 py-2 hover:bg-gray-100">
                        Edit
                    </a>
                </li>
                <li>
                    <a href="#" class="block px-4 py-2 hover:bg-gray-100">
                        Delete
                    </a>
                </li>
                <li>
                    <a href="#" class="block px-4 py-2 hover:bg-gray-100">
                        Reply
                    </a>
                </li>
            </ul>
        </nav>
    </div>
</div>

and here the demo

Note: I'm using JIT. So if some variants not work (such as group-focus-within) you can configure your tailwind.config.js like this;

module.exports = {
  mode: 'jit',
  purge: ['./src/**/*.html'], // change it
  darkMode: 'media',
  theme: {
    extend: {
    },
  },
  variants: {
    extend: {},
  },
}

Thank you for reading, have a great day all of you.

13