รูปแบบเมื่อปิดใช้งานและตัวยึดข้อความ
ตกแต่งองค์ประกอบฟอร์มที่ปิดใช้งานด้วย disabled:* และปรับแต่งลักษณะข้อความตัวยึดด้วยรูปแบบ placeholder:*
รูปแบบเมื่อปิดใช้งานและตัวยึดข้อความ เป็นบทเรียน Tailwind CSS Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Tailwind CSS Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Tailwind CSS Academy มีบทเรียนทั้งหมด 4 บทเรียน
บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ
Styling Form States
Form elements exist in multiple states beyond just default and focused. When an input is disabled, it should look visually distinct and signal that interaction is not possible. When it is empty, placeholder text hints at what the user should type. Tailwind provides the disabled: and placeholder: variant prefixes to style these specific states declaratively in HTML, without needing custom CSS rules.
<!-- Disabled and placeholder states side by side -->
<div class="space-y-3 max-w-sm">
<input type="text" placeholder="Type something here" class="w-full border rounded px-3 py-2 placeholder:text-gray-400" />
<input type="text" placeholder="Read only" disabled class="w-full border rounded px-3 py-2 disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-gray-100" />
</div>disabled: Variant Basics
The disabled: variant applies when a form element has the HTML disabled attribute. The most common styling pattern is disabled:opacity-50 disabled:cursor-not-allowed — reducing opacity to signal unavailability and switching the cursor to a blocked icon to prevent confusion. You can also add disabled:bg-gray-100 to give disabled inputs a distinctive background color that reinforces they are read-only.
<!-- Disabled form inputs with clear visual treatment -->
<div class="space-y-3 max-w-sm">
<input
type="text"
value="Active input"
class="w-full border border-gray-300 rounded-lg px-4 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none"
/>
<input
type="text"
value="Disabled input"
disabled
class="w-full border border-gray-300 rounded-lg px-4 py-2 disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-400"
/>
</div>disabled: on Buttons
Disabled buttons need to clearly communicate that the action is not available. The pattern disabled:opacity-40 disabled:cursor-not-allowed disabled:pointer-events-none creates an accessible disabled button that looks grayed out, shows a not-allowed cursor, and does not respond to clicks even with JavaScript. Adding disabled:pointer-events-none prevents hover effects from showing on disabled buttons.
<!-- Enabled vs disabled button states -->
<div class="flex gap-4 flex-wrap">
<button
class="bg-blue-600 hover:bg-blue-700 active:scale-95 text-white px-5 py-2.5 rounded-lg font-medium transition-all disabled:opacity-40 disabled:cursor-not-allowed disabled:pointer-events-none"
>
Active Button
</button>
<button
disabled
class="bg-blue-600 hover:bg-blue-700 active:scale-95 text-white px-5 py-2.5 rounded-lg font-medium transition-all disabled:opacity-40 disabled:cursor-not-allowed disabled:pointer-events-none"
>
Disabled Button
</button>
</div>disabled: on Select and Other Controls
The disabled: variant works on any HTML element that can carry the disabled attribute: inputs, selects, textareas, buttons, optgroups, and fieldsets. For a fieldset with disabled, all descendant form controls inherit the disabled state, but Tailwind's variant only applies to the direct element — so add disabled:* utilities to the fieldset, not the children.
<!-- Disabled select and textarea -->
<div class="space-y-3 max-w-sm">
<select
disabled
class="w-full border border-gray-300 rounded-lg px-4 py-2 disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-gray-50"
>
<option>Select country...</option>
<option>United States</option>
</select>
<textarea
disabled
rows="3"
placeholder="Notes (locked)"
class="w-full border border-gray-300 rounded-lg px-4 py-2 resize-none disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-gray-50"
></textarea>
</div>placeholder: Variant Basics
The placeholder: variant styles the placeholder text inside inputs and textareas. Without customization, placeholder text inherits the input's text color at reduced opacity. Common customizations include placeholder:text-gray-400 for a lighter gray, placeholder:text-sm for smaller placeholder text, and placeholder:italic to visually distinguish the hint from actual input content.
<!-- Customized placeholder text styles -->
<div class="space-y-3 max-w-sm">
<!-- Default placeholder -->
<input type="text" placeholder="Default placeholder" class="w-full border rounded px-3 py-2" />
<!-- Styled placeholder -->
<input
type="text"
placeholder="Styled placeholder"
class="w-full border border-gray-300 rounded-lg px-4 py-2 placeholder:text-gray-400 placeholder:text-sm placeholder:italic"
/>
<!-- Colored placeholder for category input -->
<input
type="text"
placeholder="Search products..."
class="w-full border border-gray-300 rounded-lg px-4 py-2 placeholder:text-blue-300 focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>Combining placeholder: With Focus
A polished UX pattern is to make placeholder text fade or change when the input is focused, giving visual confirmation that typing can begin. The combination placeholder:text-gray-400 focus:placeholder:text-gray-300 slightly fades the placeholder text on focus — a subtle effect that directs attention to the cursor. Some designs use focus:placeholder:opacity-0 to completely hide the placeholder on focus.
<!-- Placeholder fades on focus -->
<div class="space-y-3 max-w-sm">
<input
type="text"
placeholder="Click here — placeholder fades"
class="w-full border border-gray-300 rounded-lg px-4 py-2 placeholder:text-gray-400 focus:placeholder:text-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition-all"
/>
</div>placeholder: for Search and Filters
Search inputs and filter fields often use placeholder text as the primary label — especially in compact UIs where a separate label would take too much space. Style these with placeholder:text-gray-500 for good contrast and consider adding an icon alongside the placeholder. The pattern pl-10 placeholder:text-sm leaves room for a search icon positioned absolutely inside the input.
<!-- Search input with icon and styled placeholder -->
<div class="relative max-w-sm">
<!-- Search icon -->
<div class="absolute inset-y-0 left-3 flex items-center pointer-events-none">
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-4.35-4.35M17 11A6 6 0 111 11a6 6 0 0116 0z" />
</svg>
</div>
<input
type="search"
placeholder="Search by name, email..."
class="w-full border border-gray-300 rounded-xl pl-10 pr-4 py-2.5 placeholder:text-gray-400 placeholder:text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
/>
</div>Disabled Styling for Non-Input Elements
The CSS :disabled pseudo-class technically only applies to form elements. For other elements you want to make appear disabled (like a disabled list item or a grayed-out card), use aria-disabled as the hook and style it with Tailwind's aria-disabled: variant or a conditional CSS class. Alternatively, Tailwind supports [&[aria-disabled=true]]: arbitrary variant syntax for precise targeting.
<!-- Making non-form elements look disabled -->
<div class="space-y-3">
<!-- Subscription card: disabled with aria-disabled -->
<div
aria-disabled="true"
class="border border-gray-200 rounded-xl p-4 opacity-50 cursor-not-allowed select-none"
>
<h3 class="font-bold text-gray-500">Enterprise Plan</h3>
<p class="text-sm text-gray-400">Contact sales to enable</p>
</div>
<!-- Active card for comparison -->
<div class="border border-blue-200 rounded-xl p-4 cursor-pointer hover:border-blue-400">
<h3 class="font-bold">Pro Plan</h3>
<p class="text-sm text-gray-500">$29/month</p>
</div>
</div>Loading and Pending States
Beyond disabled, form elements sometimes need a loading state while an async action completes. While Tailwind does not have a built-in loading: variant, you achieve this with conditional class application. A button showing a spinner and pointer-events-none opacity-75 communicates that the action is in progress. Coupling this with animate-spin on an SVG spinner makes the state unmistakable.
<!-- Loading state on a submit button -->
<div class="flex gap-4">
<!-- Loading state (simulate with always-applied classes) -->
<button
class="flex items-center gap-2 bg-blue-600 text-white px-5 py-2.5 rounded-lg font-medium opacity-75 pointer-events-none"
>
<svg class="animate-spin w-4 h-4" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" />
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" />
</svg>
Saving...
</button>
<!-- Normal state -->
<button class="bg-blue-600 hover:bg-blue-700 text-white px-5 py-2.5 rounded-lg font-medium">
Save Changes
</button>
</div>placeholder: Best Practices
A few important guidelines: never use placeholder as the only label for an input — it disappears when typing begins, which violates WCAG 1.3.5 (Identify Input Purpose). Use placeholder as supplementary hint text alongside a visible label. Also, placeholder text typically has lower contrast than normal text, so check that your placeholder:text-* color meets the 4.5:1 contrast ratio required for WCAG AA when the input is empty and the placeholder is the user's only guide.
<!-- Best practice: label + placeholder as hint -->
<div class="max-w-sm space-y-4">
<div>
<!-- Visible label: always shown -->
<label class="block text-sm font-medium text-gray-700 mb-1">Username</label>
<!-- Placeholder: supplementary hint, not the only label -->
<input
type="text"
placeholder="e.g. john_doe"
class="w-full border border-gray-300 rounded-lg px-4 py-2 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<p class="text-xs text-gray-400 mt-1">Letters, numbers, and underscores only</p>
</div>
</div>Complete Form With All States
Here is a complete login form applying disabled, placeholder, focus, and error state styling together. This is the kind of production-quality form that handles every state a user might encounter. Each input has a label, placeholder hint, focus ring, and — for the disabled field — a grayed-out appearance. The submit button shows an enabled state, ready for hover and active styling.
<form class="max-w-sm space-y-4 p-6">
<div>
<label class="block text-sm font-medium mb-1">Email</label>
<input type="email" placeholder="you@example.com" class="w-full border border-gray-300 rounded-lg px-4 py-2 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500" />
</div>
<div>
<label class="block text-sm font-medium mb-1">Account ID</label>
<input type="text" value="ACC-12345" disabled class="w-full border border-gray-300 rounded-lg px-4 py-2 disabled:bg-gray-50 disabled:text-gray-400 disabled:cursor-not-allowed" />
<p class="text-xs text-gray-400 mt-1">Account ID cannot be changed</p>
</div>
<button class="w-full bg-blue-600 hover:bg-blue-700 active:bg-blue-800 active:scale-95 text-white py-2.5 rounded-lg font-semibold transition-all">
Update Profile
</button>
</form>Quick Check
Test your understanding of Tailwind CSS Mastery concepts from this lesson.
Lesson Recap
In this lesson you learned: disabled: styles form elements when the HTML disabled attribute is present, placeholder: targets placeholder text color, size, and style inside inputs, and combining disabled:opacity-50, disabled:cursor-not-allowed, and disabled:pointer-events-none creates a complete disabled button pattern. Next up we explore the powerful group and peer variants for parent-child and sibling interactions.
คำถามที่พบบ่อย
บทเรียน “รูปแบบเมื่อปิดใช้งานและตัวยึดข้อความ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “รูปแบบเมื่อปิดใช้งานและตัวยึดข้อความ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Tailwind CSS Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Tailwind CSS Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “รูปแบบเมื่อปิดใช้งานและตัวยึดข้อความ”
ตกแต่งองค์ประกอบฟอร์มที่ปิดใช้งานด้วย disabled:* และปรับแต่งลักษณะข้อความตัวยึดด้วยรูปแบบ placeholder:* คุณปฏิบัติ Tailwind CSS Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Tailwind CSS Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Tailwind CSS Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “รูปแบบเมื่อปิดใช้งานและตัวยึดข้อความ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Tailwind CSS Academy นี้ได้ไหม
ได้ บทเรียน Tailwind CSS Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- รูปแบบเมื่อชี้และเมื่อใช้งาน
- รูปแบบเมื่อโฟกัสและโฟกัสที่มองเห็นได้
- รูปแบบเมื่อปิดใช้งานและตัวยึดข้อความ
- รูปแบบ Group และ Peer