ππ» μλλ Dropdown Menu λΆλΆμ
λλ€.
The section below is the dropdown menu.
ππ» λ μ΄μμ, ν°νΈμ¬μ΄μ¦λ λλΆλΆμ css,tailwindcss λ΄μ©μ μ΄μ ν¬μ€νΈμ λ΄μ©κ³Ό κ±°μ μ μ¬ν©λλ€.
The layout, font size, and most of the CSS and Tailwind CSS details are nearly identical to those in the previous post.
ππ» μ»΄ν¬λνΈ νμμΌλ‘ μ¬μ©ν μ μλλ‘ uiλλ ν λ¦¬κ° μΆκ°λμμ΅λλ€.
A ui directory has been added to enable usage in component form.
π νλ‘μ νΈ κ΅¬μ‘° / Project Structure
tailwindcss-nextjs/
βββ app/
βββ button-css/
βββ button-tailwind/
βββ card-css/
βββ card-tailwind/
βββ form-css/
βββ form-tailwind/
βββ dropdown-css/
βββ dropdown-tailwind/
βββ ui/
βββ page.tsx
βββ _components/
βββ button.tsx
βββ dropdown.tsx
π Dropdown Menu – Tailwind & CSS
βοΈ Tailwind
— μ€ν¬λ¦° μ· / Screen Shoot

— http://localhost:3000/dropdown-tailwind
'use client'
import { useState } from 'react'
const OPTIONS = [
{ value: '9s', label: '9S' },
{ value: '2b', label: '2B' },
{ value: '4b', label: '4B' },
]
export default function Page() {
const [open, setOpen] = useState(false)
const [value, setValue] = useState(OPTIONS[0])
return (
<main className="min-h-screen flex items-center justify-center bg-gray-50 p-4">
<div className="w-full max-w-sm bg-white rounded-2xl shadow-lg p-6">
<h2 className="text-base font-bold">λλ‘λ€μ΄/Drop down(Tailwindcss)</h2>
<p className="text-sm text-gray-400 mt-1">freelifemakers</p>
<div className="mt-6 flex flex-col gap-1.5">
<label className="text-sm font-bold text-gray-700">μ§μ
/ Role</label>
{/* Select */}
<div className="relative">
{/* 1. λ²νΌ - νμ 보μ΄λ λΆλΆ / Button - Always visible part */}
<button
onClick={() => setOpen(!open)}
className="w-full flex items-center justify-between px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-sm text-left focus:outline-none focus:ring-2 focus:ring-blue-500 focus:bg-white transition-all"
>
<span>{value.label}</span>
<span className={`transition-transform ${open? 'rotate-180' : ''}`}>βΌ</span>
</button>
{/* 2. 리μ€νΈ - openμΌ λλ§ λ³΄μ΄λ λΆλΆ / List β section visible only when open */}
{open && (
<div className="absolute z-10 mt-2 w-full bg-white border border-gray-200 rounded-xl shadow-lg overflow-hidden">
{OPTIONS.map((opt) => (
<button
key={opt.value}
onClick={() => {
setValue(opt)
setOpen(false)
}}
className={`w-full text-left px-4 py-3 text-sm hover:bg-gray-50 transition-colors ${
value.value === opt.value? 'bg-blue-50 text-blue-600 font-bold' : 'text-gray-700'
}`}
>
{opt.label}
</button>
))}
</div>
)}
</div>
<p className="text-xs text-gray-400 mt-2">μ νλ κ°/Selected Value : {value.value}</p>
</div>
</div>
</main>
)
}
βοΈ CSS
— μ€ν¬λ¦° μ· / ScreenShot

— http://localhost:3000/dropdown-css
'use client'
import { useState } from 'react'
const OPTIONS = [
{ value: '9s', label: '9S' },
{ value: '2b', label: '2B' },
{ value: '4b', label: '4B' },
]
export default function Page() {
const [open, setOpen] = useState(false)
const [value, setValue] = useState(OPTIONS[0])
return (
<>
<main className="page">
<div className="card">
<h2 className="title">λλ‘λ€μ΄/Drop down(CSS)</h2>
<p className="subtitle">freelifemakers</p>
<div className="field-group">
<label className="label">μ§μ
/ Role</label>
{/* Select 본체 - relative κΈ°μ€μ */}
<div className="select-wrap">
{/* 1. λ²νΌ */}
<button
onClick={() => setOpen(!open)}
className="select-btn"
>
<span>{value.label}</span>
<span className={`arrow ${open? 'arrow-open' : ''}`}>βΌ</span>
</button>
{/* 2. 리μ€νΈ */}
{open && (
<div className="select-list">
{OPTIONS.map((opt) => (
<button
key={opt.value}
onClick={() => {
setValue(opt)
setOpen(false)
}}
className={`select-option ${value.value === opt.value? 'selected' : ''}`}
>
{opt.label}
</button>
))}
</div>
)}
</div>
<p className="hint">μ νλ κ°/Selected Value : {value.value}</p>
</div>
</div>
</main>
<style>{`
.page {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: #f9fafb;
padding: 16px;
}
.card {
width: 100%;
max-width: 384px;
background: white;
border-radius: 16px;
box-shadow: 0 10px 15px rgba(0,0,0,0.1);
padding: 24px;
}
.title { font-size: 16px; font-weight: 700; }
.subtitle { font-size: 14px; color: #9ca3af; margin-top: 4px; }
.field-group {
margin-top: 24px;
display: flex;
flex-direction: column;
gap: 6px;
}
.label {
font-size: 14px;
font-weight: 700;
color: #374151;
}
.hint {
font-size: 12px;
color: #9ca3af;
margin-top: 8px;
}
/* Dropdown κΈ°μ€μ / benchmark - relative */
.select-wrap {
position: relative;
}
/* 1. λ²νΌ / button- w-full flex justify-between */
.select-btn {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
background: #f9fafb;
border: 1px solid #e5e7eb;
border-radius: 12px;
font-size: 14px;
text-align: left;
cursor: pointer;
transition: all 0.15s;
}
.select-btn:focus {
outline: none;
background: white;
border-color: #3b82f6;
box-shadow: 0 0 0 2px rgba(59,130,246,0.3);
}
/* νμ΄ν νμ / Rotate arrow */
.arrow {
transition: transform 0.2s;
font-size: 12px;
}
.arrow-open {
transform: rotate(180deg);
}
/* 2. 리μ€νΈ / List - absolute z-10 mt-2 */
.select-list {
position: absolute;
z-index: 10;
margin-top: 8px;
width: 100%;
background: white;
border: 1px solid #e5e7eb;
border-radius: 12px;
box-shadow: 0 10px 15px rgba(0,0,0,0.1);
overflow: hidden;
}
/* μ΅μ
νλ / One option */
.select-option {
width: 100%;
text-align: left;
padding: 12px 16px;
font-size: 14px;
border: none;
background: white;
color: #374151;
cursor: pointer;
transition: background 0.15s;
}
.select-option:hover {
background: #f9fafb;
}
.select-option.selected {
background: #eff6ff;
color: #2563eb;
font-weight: 700;
}
`}</style>
</>
)
}
π μ»΄ν¬λνΈ νμμΌλ‘ μ¬μ©νκΈ° / Using as a component
— μ€ν¬λ¦° μ· / ScreenShot

— http://localhost:3000/ui
βοΈ νμ¬ λ²νΌκ³Ό λλ‘λ€μ΄ λ©λ΄κ° _compoentsμ μμ΅λλ€.(button.tsx dropdown.tsx)
Currently, the button and dropdown menu are located in _components (button.tsx, dropdown.tsx).
βοΈ app/ui/page.tsxμμ μ¬μ©μ μλμ²λΌ μ¬μ©ν©λλ€.
When using it in app/ui/page.tsx, use it as shown below.
// compoents
import { Button } from './_components/button'
import { Dropdown } from './_components/dropdown';
export default function UIPage() {
return (
<main className="min-h-screen flex items-center justify-center bg-gray-50 p-4">
<div className="w-full max-w-sm bg-white rounded-2xl shadow-lg p-6 flex flex-col gap-6">
<h1 className="text-xl font-bold">λ΄ UI λΌμ΄λΈλ¬λ¦¬ / </h1>
<Dropdown />
<Button>μ μ₯νκΈ°/Save</Button>
</div>
</main>
)
}
λ§ν볡μ 21μ₯ 22μ / Matthew 21: 22
“λν¬κ° κΈ°λν λμ 무μμ΄λ μ§ λ―Ώκ³ κ΅¬νλ κ²μ λ€ λ°μΌλ¦¬λΌ νμλλΌ”
“And everything you ask in prayer, believing, you will receive.”