DEV Community

loading...
Cover image for Dropdown with CSS / Tailwind

Dropdown with CSS / Tailwind

Tayfun Erbilen
Just another ordinary person in the planet
・3 min read

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>
Enter fullscreen mode Exit fullscreen mode

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

.dropdown nav {
   display: none;
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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: {},
  },
}
Enter fullscreen mode Exit fullscreen mode

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

Discussion (15)

Collapse
venelinn profile image
Venelin

CSS Way is the best/right way! No frameworks, no problems !

Collapse
tayfunerbilen profile image
Tayfun Erbilen Author

I was thinking like you, then I started to use SASS instead of regular CSS and a couple months later I didn't want to use regular CSS again :) And now, with tailwind I don't need to write SASS or regular CSS either.

But of course, I learned CSS deeply first :) Then I got lazy maybe little bit :)

Collapse
venelinn profile image
Venelin

When I said CSS way I meant no Tailwind, CSS/SCSS kind of the same thing

Collapse
metalmikester profile image
Michel Renaud

I'm always impressed by everything that can be done in CSS. Too bad I suck at it. lol

Collapse
samael3 profile image
samael3

I'm confuse bro use a framework or classical css
Pls give me a reply.iT will help me a lot

Collapse
hasnaindev profile image
Muhammad Hasnain

Just become proficient in CSS. Internet has a lot of bad advice. People promote tools to sell tutorials and get views on their content, as a beginner, do NOT jump the hype train. I've seen a lot of passionate developers fail at finding jobs even though they learned React, React Native, .NET, basically the full stack and were proficient at non.

Just stop focusing on damned tools. Bootstrap, jQuery, React, Vue, Tailwind all of them are something you should avoid. Become proficient at CSS and JavaScript because any hyped tool or technology is built upon these basic languages.

You good at CSS? Good. CSS frameworks would automatically become a second nature. Good at JavaScript and have a strong grasp of ESNext? Good. The first framework you learn may take some time but the others, you can learn in a week or a month. Simple as that.

Collapse
anstroy profile image
Aus G

Well, you have a point, but remember that many developers are full-stack devs, and there, CSS just plays a small part, so is fine if you use Bootstrap or those frameworks just to get the job done and focus on all the things on the backend like db, auth, serialization, security, etc.

But if you want to focus on front end dev, CSS has to be your bread and butter yeah.

Thread Thread
hasnaindev profile image
Muhammad Hasnain • Edited

Makes sense but this looks like an oversimplification. Suppose, you are a full-stack developer who ends up working on WordPress, Shopify or similar CMS type systems. These systems come with their own backends that you can only modify and tweak at best.

Not being excellent at frontend has hurt my career. You can go freelancing and clients wouldn't really care how well written your backend and even frontend codes are, they care about what they can see. They want pixel perfect results that frameworks cannot provide if the design is too dynamic.

I stick with my original point. Know the basics, have a strong foundation. Learning frameworks is easy and a new one comes out every day. I'm good at JavaScript and when the time came, I picked up Vue and Svelte without any trouble.

I hope you got my point. I don't advice to be anti framework but if you don't know your stuff, you'll be a mediocre/average developer. Seen far too many framework hyped developers who spend more time then required to solve problems just because they didn't knew the basics.

Collapse
hieptl profile image
Hiep Le • Edited

Hi @hasnaindev , I totally agree with your opinion. From my point of view, many tutorials are sharing about newest technologies for beginners. When I joined an interview as an interviewer, I asked candidates some questions in order to know about their foundation, they could not answer them well. Although, they put many keywords in their resume / CVs such as JS frameworks, message brokers, caching, cloud, AI, machine learning and so on.

In my opinion, it is similar to building a house. We should focus on the foundation first before building each floor. Many mid and big companies are asking about some questions to test our base knowledge instead of asking too much about frameworks / libraries or trending technologies.

If we want to master everything in front-end development, it is fine to learn trending technologies in front-end development such as PWA, Tailwind CSS, React Query State, Micro Front-End and so on.

However, if we want to experience in different fields and has a good career path, I think that we just need to find the key points in that fields and learn them instead of learning everything, for example, in front-end development, we just need to focus on HTML, CSS, JS and then we can take time to learn other things such as back-end and devops or even machine learning. Please do not feel guilty, if we cannot learn everything in that field. We can speed up in climbing the career ladder by having good foundation.

We could not ensure that the current technologies will be on the top forever. We could adapt with the changes by having good base knowledge. Please do not let our future depends on one or two technologies.

Thread Thread
hasnaindev profile image
Muhammad Hasnain

Thanks for the detailed reply and I totally agree. In fact, when I joined my current company as a WordPress developer, I didn't knew anything about WordPress and not even PHP but I had a strong foundation and so, I got up and running in a month.

Later priorities changed. I was handed the most important projects in company that generates the most revenue. Both of those Shopify based websites generate 7 figures a month. One uses a complex build system along with Vue and the other is simple, in a sense that the developer who previously worked on it before the project was handed to us had no idea what good code or bad code was, absolutely terrible. In that, I'm working with Svelte.

So, you see? I though I should've been explicit that learning new technologies isn't bad but if your foundation is strong enough, you can pick anything at anytime, without any hassle.

Collapse
tayfunerbilen profile image
Tayfun Erbilen Author • Edited

It really depends of what you need actually. I'm using tailwind with react mostly. I'm creating components for all my needs. And I don't need to write CSS for that 'cause tailwind really works fine and it provides an excellent codebase for my components.

So also tailwind has a purging system, you don't need to use all tailwind library, you can use what ever you used. For development process, it really helped me to getting fast. But you might be little slower while learning tailwind utilities :) I recommend learn CSS deeply first, then use tailwind for freedom :)

Collapse
samael3 profile image
samael3 • Edited

Thanks bro
I have another question bootstrap or tailwind css
I know css very well
And saas is better than raw css

Thread Thread
tayfunerbilen profile image
Tayfun Erbilen Author

I think we can't compare them, because it is not same.

Bootstrap has some cool stuff, yes. I tried both of them, and I decided to use tailwind.

If you try this example on bootstrap, you will understand why I don't liked it. Because, I don't want to use their HTML structure or limited utilities. I need real codebase like tailwind. With tailwind, I feel free. With bootstrap, I feel stuck.

But of course these are my opinion, not investment advice :)

Collapse
rks0001 profile image
rks0001

Doesn't matter if you are getting the results you want . But having knowledge of CSS is always good.

Collapse
riktar profile image
Riccardo Tartaglia

If you use React, you can use this: windy-docs.vercel.app/docs/compone...