Dropdownmenykomponent
Skapa en positionerad dropdownmeny som visas under en utlösande knapp med absolut positionering, skugga och rundade hörn.
Dropdownmenykomponent är en gratis lektion i Tailwind CSS Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Tailwind CSS Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Tailwind CSS Academy innehåller totalt 4 lektioner.
Vad är en rullgardinsmeny
En rullgardinsmeny är en panel med alternativ som visas under (eller bredvid) ett utlösande element när den aktiveras. Till skillnad från en inbyggd <select> kan en anpassad rullgardinsmeny innehålla ikoner, beskrivningar, märken, avdelare och annat HTML-innehåll.
Den största utmaningen med rullgardinsmenyer är positioneringen: panelen måste visas direkt under utlösaren och hålla sig inom visningsområdet. Tailwinds positioneringsverktyg i kombination med en liten mängd JavaScript gör detta möjligt utan något externt bibliotek.
Struktur för utlösarknappen
Rullgardinsmenyns utlösare är vanligtvis en knapp som visar det valda alternativet eller en åtgärdsetikett. Omslut utlösaren och rullgardinspanelet tillsammans i en relative-behållare så att panelen positioneras relativt till utlösaren.
Utlösarknappen använder inline-flex items-center gap-2 för att justera en etikett och en chevronikon. Chevronikonen kan roteras med rotate-180 när rullgardinsmenyn är öppen för att visa dess status.
<div class="relative inline-block">
<button
id="dd-trigger"
onclick="toggleDropdown()"
class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium
text-gray-700 bg-white border border-gray-300 rounded-lg
hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500">
Options
<svg id="dd-chevron" class="w-4 h-4 transition-transform duration-200"
fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
</svg>
</button>
</div>Positionering av rullgardinspane
Rullgardinspanelet använder absolute top-full left-0 mt-1 för att positioneras direkt under utlösarknappen. top-full placerar panelens överkant vid underkanten av den relativa föräldern, och mt-1 lägger till ett litet mellanrum på 4 px mellan utlösaren och panelen.
Lägg till min-w-48 w-56 för att ge panelen en bekväm minsta bredd oavsett utlösarens storlek. Om rullgardinsmenyn riskerar att skäras av vid högerkanten använder du right-0 i stället för left-0 för att justera den mot utlösarens högra kant.
<div
id="dropdown"
class="absolute top-full left-0 mt-1 z-50
w-56 bg-white border border-gray-200 rounded-xl shadow-lg
hidden">
<!-- menu items -->
</div>Objekt i rullgardinsmenyn
Varje menyobjekt är en länk eller knapp med full bredd och flex items-center gap-3 w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 för en bekväm yta vid hovring. Det första objektet använder rounded-t-xl och det sista rounded-b-xl för att klippa hovringsmarkeringarna inom panelens rundade hörn.
Alternativt kan ni lägga till rounded-xl på varje objekt individuellt, med en indragen marginal på 4 px från panelens utfyllnad, för att skapa en svävande markeringseffekt.
<div class="py-1">
<a href="/profile"
class="flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
<svg class="w-4 h-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/>
</svg>
View Profile
</a>
<a href="/settings"
class="flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
<svg class="w-4 h-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
Settings
</a>
</div>Avdelare och sektionsgrupper
Avdelare separerar grupper av relaterade objekt i en rullgardinsmeny. Använd ett <hr class='border-t border-gray-100 my-1'>-element mellan grupperna. Alternativt kan ni lägga till en liten sektionsrubrik ovanför varje grupp med px-4 py-1 text-xs font-semibold uppercase tracking-wider text-gray-400.
Placera riskfyllda åtgärder (som att logga ut eller ta bort) längst ned, under en avdelare, och färgsätt dem med rött så att det omedelbart framgår att de är destruktiva.
<div class="py-1">
<!-- Main section -->
<a href="/profile" class="flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">View Profile</a>
<a href="/settings" class="flex items-center gap-3 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Settings</a>
<!-- Divider -->
<hr class="border-t border-gray-100 my-1" />
<!-- Danger section -->
<button class="flex items-center gap-3 w-full px-4 py-2 text-sm text-red-600 hover:bg-red-50">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/>
</svg>
Sign Out
</button>
</div>Växlingslogik och stängning vid klick utanför
Rullgardinsmenyns växlingslogik visar och döljer panelen. Ännu viktigare är att den måste stängas när användaren klickar utanför rullgardinsmenyn. Lägg till en klicklyssnare på dokumentet som kontrollerar om klickets mål inte finns inuti rullgardinsmenyns behållare.
Använd contains() för att kontrollera om klicket skedde inuti rullgardinsmenyns omslutande element. Om inte döljer ni rullgardinsmenyn och roterar tillbaka chevronikonen.
<script>
const wrapper = document.getElementById('dd-wrapper');
const panel = document.getElementById('dropdown');
const chevron = document.getElementById('dd-chevron');
function toggleDropdown() {
panel.classList.toggle('hidden');
chevron.classList.toggle('rotate-180');
}
// Close when clicking outside
document.addEventListener('click', (e) => {
if (!wrapper.contains(e.target)) {
panel.classList.add('hidden');
chevron.classList.remove('rotate-180');
}
});
// Close on Escape key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
panel.classList.add('hidden');
chevron.classList.remove('rotate-180');
}
});
</script>Rullgardinsmeny med toningsanimation
Lägg till en tonings- och skalningsanimation när rullgardinspanelet öppnas genom att använda samma teknik som för modalen: övergå från scale-95 opacity-0 till scale-100 opacity-100 med transition-all duration-150 origin-top.
Verktyget origin-top anger transformationens origo till panelens överkant, så att den skalas ut från utlösaren och animationen känns kopplad till knappen som öppnade den.
<div
id="dropdown"
class="absolute top-full left-0 mt-1 z-50
w-56 bg-white border border-gray-200 rounded-xl shadow-lg
transition-all duration-150 origin-top
scale-95 opacity-0 pointer-events-none">
<!-- items -->
</div>
<script>
function openDropdown() {
const d = document.getElementById('dropdown');
d.classList.remove('scale-95', 'opacity-0', 'pointer-events-none');
d.classList.add('scale-100', 'opacity-100', 'pointer-events-auto');
}
function closeDropdown() {
const d = document.getElementById('dropdown');
d.classList.remove('scale-100', 'opacity-100', 'pointer-events-auto');
d.classList.add('scale-95', 'opacity-0', 'pointer-events-none');
}
</script>Högerjusterad rullgardinsmeny
När en rullgardinsmenys utlösare befinner sig nära skärmens högra kant (till exempel en användaravatar längst upp till höger i en navigeringsrad) bör panelen justeras mot utlösarens högra kant för att undvika att den hamnar utanför skärmen. Använd right-0 i stället för left-0 på panelen.
Detta är en viktig detalj som nybörjare ofta missar – en vänsterjusterad rullgardinsmeny vid en utlösare på höger sida hamnar delvis eller helt utanför skärmen på mobila enheter.
<div class="relative inline-block">
<!-- Right-side trigger (e.g., user avatar) -->
<button onclick="toggleDropdown()" class="w-8 h-8 rounded-full bg-blue-600 text-white text-sm font-bold">JD</button>
<!-- Panel aligned to right edge of trigger -->
<div
id="dropdown"
class="hidden absolute top-full right-0 mt-1 z-50
w-56 bg-white border border-gray-200 rounded-xl shadow-lg py-1">
<div class="px-4 py-2 border-b border-gray-100">
<p class="text-sm font-semibold text-gray-900">Jane Doe</p>
<p class="text-xs text-gray-500">jane@example.com</p>
</div>
<a href="/profile" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Profile</a>
<a href="/settings" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Settings</a>
<hr class="border-t border-gray-100 my-1" />
<button class="block w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-red-50">Sign Out</button>
</div>
</div>Rullgardinsmeny med bockmarkeringar för aktiva objekt
En rullgardinsmeny för val visar en bockmarkering bredvid det alternativ som är valt. Använd flex items-center justify-between på varje objekt för att placera bockmarkeringen till höger, eller flex items-center gap-3 för att placera den till vänster före etiketten.
Färgsätt det aktiva objektet med text-blue-600 font-semibold och visa en färgad bockikon. Inaktiva objekt använder standardklassen text-gray-700.
<div class="py-1">
<!-- Active item -->
<button class="flex items-center justify-between w-full px-4 py-2 text-sm font-semibold text-blue-600 hover:bg-blue-50">
English
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
</svg>
</button>
<!-- Inactive items -->
<button class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">French</button>
<button class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">German</button>
<button class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Japanese</button>
</div>Kontextmeny som rullgardinsmeny
En kontextmeny visas vid ett högerklick eller där en knapp med tre punkter finns för att erbjuda kontextuella åtgärder för ett specifikt objekt (till exempel en fil, rad eller ett kort). Positionera den vid de koordinater där användaren klickade med absolute-positionering och JavaScript.
För mönstret med tre punkter (det vanligaste tillvägagångssättet) placerar ni en relative-behållare på objektet och en knapp med tre punkter vid top-2 right-2. Rullgardinspanelet visas under eller bredvid knappen.
<div class="relative">
<!-- Item row -->
<div class="flex items-center justify-between p-4 bg-white rounded-lg border border-gray-200">
<span class="text-sm font-medium text-gray-900">Project Alpha.zip</span>
<!-- Three-dot button -->
<div class="relative">
<button onclick="toggleCtx()" class="p-1 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-md">
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
<path d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z"/>
</svg>
</button>
<div id="ctx-menu" class="hidden absolute top-full right-0 mt-1 z-50 w-40 bg-white border border-gray-200 rounded-xl shadow-lg py-1">
<button class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Rename</button>
<button class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Download</button>
<hr class="border-t border-gray-100 my-1" />
<button class="block w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-red-50">Delete</button>
</div>
</div>
</div>
</div>Kapslad rullgardinsmeny (undermeny)
En kapslad undermeny visas till höger om ett överordnat menyobjekt när det hovras över eller klickas på. Använd group relative på det överordnade objektet och group-hover:block absolute left-full top-0 på undermenyns panel för att placera den bredvid det överordnade objektet.
Lägg till en högerpekande chevronikon på det överordnade objektet för att visa att det har en undermeny. Kapslade menyer bör begränsas till en nivå — två nivåer är redan komplext; tre nivåer är sällan motiverat.
<div class="py-1 relative">
<a href="/" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Profile</a>
<!-- Parent with submenu -->
<div class="group relative">
<button class="flex items-center justify-between w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
Export
<svg class="w-4 h-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
</svg>
</button>
<!-- Submenu -->
<div class="hidden group-hover:block absolute left-full top-0 ml-1 w-40 bg-white border border-gray-200 rounded-xl shadow-lg py-1 z-50">
<button class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">As PDF</button>
<button class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">As CSV</button>
<button class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">As Excel</button>
</div>
</div>
</div>Snabbtest
Testa din förståelse av koncepten i Tailwind CSS Mastery från den här lektionen.
Sammanfattning av lektionen
I den här lektionen lärde du dig att positionering av rullgardinsmenyer använder relative på omslaget och absolute top-full left-0 mt-1 på panelen; högerjustering använder right-0 i stället för left-0 för att förhindra att innehållet hamnar utanför skärmen vid högersidiga utlösare; och stängning vid klick utanför kräver en dokumentklicklyssnare som kontrollerar contains() för att upptäcka klick utanför omslagselementet. Härnäst gör vi modaler och rullgardinsmenyer helt tillgängliga.
Lär dig HTML med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”Dropdownmenykomponent” gratis?
Ja – hela texten till ”Dropdownmenykomponent” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Tailwind CSS Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Tailwind CSS Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Dropdownmenykomponent”?
Skapa en positionerad dropdownmeny som visas under en utlösande knapp med absolut positionering, skugga och rundade hörn. Ni övar på Tailwind CSS Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Tailwind CSS Academy?
Du behöver inga förkunskaper. Utbildningen i Tailwind CSS Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Dropdownmenykomponent”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Tailwind CSS Academy-lektionen?
Ja. Varje Tailwind CSS Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Struktur för modaldialoger
- Animation för att öppna och stänga modaler
- Dropdownmenykomponent
- Tillgängliga modaler och dropdownmenyer