表单布局模式
使用 Flex 和 Grid 以堆叠或行内布局排列标签与输入框,并配合一致的间距和对齐实用程序。
表单布局模式 是 CoddyKit 上的免费 Tailwind CSS Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Tailwind CSS Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Tailwind CSS Academy 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
Why Form Layout Matters
A form's layout is as important as the styling of its individual fields. A well-structured form guides users through completion naturally, while a poorly arranged one increases abandonment. Form layout encompasses how labels and inputs are positioned, how multi-column fields are arranged, and how actions like submit and cancel are placed.
Tailwind's flex and grid utilities make all of these arrangements straightforward without writing any custom CSS.
Stacked (Vertical) Form Layout
The stacked layout places labels directly above their inputs, which is the most mobile-friendly and readable approach. Each label-input pair lives in a flex flex-col gap-1 container, and the entire form uses space-y-5 between pairs.
This layout is proven to have the highest completion rates because users read the label before seeing the input, setting context before they must act.
<form class="max-w-md space-y-5">
<div class="flex flex-col gap-1">
<label for="fname" class="text-sm font-medium text-gray-700">First name</label>
<input id="fname" type="text" class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<div class="flex flex-col gap-1">
<label for="email" class="text-sm font-medium text-gray-700">Email address</label>
<input id="email" type="email" class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<button type="submit" class="w-full py-2.5 bg-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700">
Submit
</button>
</form>Inline (Horizontal) Form Layout
An inline layout places the label to the left of the input in the same row. This is compact and works well for admin forms or search filters where vertical space is precious. Use flex items-center gap-4 on each row, and give the label a fixed width like w-32 flex-shrink-0 so all labels align to a common right edge.
On mobile, these inline rows should switch to stacked using responsive breakpoints: flex-col sm:flex-row.
<form class="space-y-4">
<div class="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4">
<label for="h-name" class="text-sm font-medium text-gray-700 sm:w-32 sm:flex-shrink-0 sm:text-right">
Full name
</label>
<input id="h-name" type="text" class="flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<div class="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4">
<label for="h-email" class="text-sm font-medium text-gray-700 sm:w-32 sm:flex-shrink-0 sm:text-right">
Email
</label>
<input id="h-email" type="email" class="flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
</form>Two-Column Form Grid
For forms with many fields, a two-column grid saves vertical space by placing two fields side by side. Use grid grid-cols-1 sm:grid-cols-2 gap-5 on the form body. Fields that need full width (like a message textarea) use sm:col-span-2.
This pattern is extremely common in checkout forms, profile edit pages, and registration forms.
<form class="grid grid-cols-1 sm:grid-cols-2 gap-5">
<div class="flex flex-col gap-1">
<label class="text-sm font-medium text-gray-700">First name</label>
<input type="text" class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<div class="flex flex-col gap-1">
<label class="text-sm font-medium text-gray-700">Last name</label>
<input type="text" class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<!-- Full-width field -->
<div class="flex flex-col gap-1 sm:col-span-2">
<label class="text-sm font-medium text-gray-700">Email address</label>
<input type="email" class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<!-- Full-width textarea -->
<div class="flex flex-col gap-1 sm:col-span-2">
<label class="text-sm font-medium text-gray-700">Message</label>
<textarea rows="3" class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg resize-none focus:outline-none focus:ring-2 focus:ring-blue-500"></textarea>
</div>
</form>Form Section Dividers
Long forms are split into logical sections to reduce cognitive load. Add a section heading with text-base font-semibold text-gray-900 and a subtle divider using border-t border-gray-200 pt-6 mt-6 to visually separate groups of fields.
Common sections for a profile form: Personal Information, Contact Details, Preferences, and Security. Each section addresses a clear topic, helping users understand the form's structure before filling it out.
<form class="max-w-2xl space-y-8">
<!-- Section 1 -->
<div>
<h3 class="text-base font-semibold text-gray-900">Personal Information</h3>
<p class="mt-1 text-sm text-gray-500">Update your personal details.</p>
<div class="mt-5 grid grid-cols-1 sm:grid-cols-2 gap-5">
<div class="flex flex-col gap-1">
<label class="text-sm font-medium text-gray-700">First name</label>
<input type="text" class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<div class="flex flex-col gap-1">
<label class="text-sm font-medium text-gray-700">Last name</label>
<input type="text" class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
</div>
</div>
<!-- Section divider -->
<div class="border-t border-gray-200 pt-6">
<h3 class="text-base font-semibold text-gray-900">Contact Details</h3>
</div>
</form>Required Field Indicators
Conventionally, required fields are marked with a red asterisk. Place a <span class="text-red-500">*</span> immediately after the label text. Add an optional helper note like Required fields are marked with * at the top of the form.
Always validate required fields server-side. The visual indicator is a UX convenience, not a security measure. Use the HTML required attribute on inputs for browser-level validation as a first line of feedback.
<form class="max-w-md space-y-5">
<p class="text-xs text-gray-500">Fields marked with <span class="text-red-500">*</span> are required.</p>
<div class="flex flex-col gap-1">
<label for="req-name" class="text-sm font-medium text-gray-700">
Full name <span class="text-red-500">*</span>
</label>
<input id="req-name" type="text" required
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<div class="flex flex-col gap-1">
<label for="req-email" class="text-sm font-medium text-gray-700">
Email <span class="text-red-500">*</span>
</label>
<input id="req-email" type="email" required
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
<div class="flex flex-col gap-1">
<label for="opt-phone" class="text-sm font-medium text-gray-700">Phone number</label>
<input id="opt-phone" type="tel"
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" />
</div>
</form>Helper Text Below Fields
Helper text provides additional context or format instructions below an input. Use mt-1 text-xs text-gray-500 on a <p> tag below the input and link it to the input via aria-describedby for screen reader support.
Keep helper text concise — one short sentence at most. For password fields, a helper text explaining strength requirements (minimum 8 characters, one number) prevents frustrating validation failures after submission.
<div class="flex flex-col gap-1">
<label for="pw" class="text-sm font-medium text-gray-700">Password</label>
<input
id="pw"
type="password"
aria-describedby="pw-hint"
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg
focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<p id="pw-hint" class="mt-1 text-xs text-gray-500">
Must be at least 8 characters with one uppercase letter and one number.
</p>
</div>Form Action Button Placement
The submit button placement affects form completion rates. For single-column stacked forms, a full-width w-full button works well. For card-based forms or modal forms, place primary and secondary actions at the bottom right using flex justify-end gap-3.
Always put the destructive or secondary action (Cancel, Reset) to the left of the primary action (Submit, Save) so users read Cancel before Submit and do not accidentally submit when trying to cancel.
<!-- Full width (mobile forms) -->
<div class="space-y-3">
<button type="submit" class="w-full py-2.5 bg-blue-600 text-white font-semibold rounded-lg hover:bg-blue-700">
Create Account
</button>
<button type="button" class="w-full py-2.5 text-gray-700 font-semibold rounded-lg border border-gray-300 hover:bg-gray-50">
Cancel
</button>
</div>
<!-- Right-aligned (desktop forms) -->
<div class="flex justify-end gap-3 pt-6 border-t border-gray-200">
<button type="button" class="px-4 py-2 text-sm font-semibold text-gray-700 border border-gray-300 rounded-lg hover:bg-gray-50">
Cancel
</button>
<button type="submit" class="px-4 py-2 text-sm font-semibold text-white bg-blue-600 rounded-lg hover:bg-blue-700">
Save Changes
</button>
</div>Floating Label Pattern
A floating label starts inside the input as placeholder text and floats above the input when the user focuses or types. This saves vertical space while maintaining label visibility. Implement it using relative on the wrapper, an absolute label that transforms on focus and not-placeholder-shown states, and peer utilities.
The key utility is peer-placeholder-shown:translate-y-0 to keep the label inside the input when empty, and peer-focus:-translate-y-6 peer-focus:scale-75 to float it above on focus.
<div class="relative">
<input
id="float-name"
type="text"
placeholder=" "
class="peer w-full px-3 pt-5 pb-2 text-sm text-gray-900 border border-gray-300 rounded-lg
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
<label
for="float-name"
class="absolute left-3 top-3 text-sm text-gray-500 transition-all duration-200
peer-focus:top-1 peer-focus:text-xs peer-focus:text-blue-600
peer-[:not(:placeholder-shown)]:top-1 peer-[:not(:placeholder-shown)]:text-xs">
Full name
</label>
</div>Inline Form (Search Bar Style)
An inline form places the input and submit button on the same line, like a newsletter signup or hero search bar. Use a flex gap-2 container with the input taking flex-1 and the button at a fixed width.
On mobile, these can stack vertically using flex-col sm:flex-row so the input spans full width on small screens and the button stacks below it.
<!-- Email newsletter signup -->
<form class="flex flex-col sm:flex-row gap-3 max-w-md">
<input
type="email"
placeholder="Enter your email"
class="flex-1 px-4 py-2.5 text-sm border border-gray-300 rounded-lg
focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<button
type="submit"
class="px-6 py-2.5 text-sm font-semibold text-white bg-blue-600 rounded-lg
hover:bg-blue-700 whitespace-nowrap transition-colors">
Subscribe
</button>
</form>Multi-Step Form Navigation
Long forms benefit from multi-step navigation that breaks them into logical stages. A progress indicator at the top shows current step position. Each step's content is conditionally shown, and navigation buttons (Back/Next) sit at the bottom.
Style the step indicators as numbered circles: w-8 h-8 rounded-full flex items-center justify-center text-sm font-bold. Completed steps use bg-blue-600 text-white, the current step uses border-2 border-blue-600 text-blue-600, and future steps use border-2 border-gray-300 text-gray-400.
<!-- Step progress indicator -->
<div class="flex items-center gap-0">
<!-- Completed -->
<div class="w-8 h-8 rounded-full bg-blue-600 text-white flex items-center justify-center text-sm font-bold">1</div>
<div class="flex-1 h-0.5 bg-blue-600"></div>
<!-- Current -->
<div class="w-8 h-8 rounded-full border-2 border-blue-600 text-blue-600 flex items-center justify-center text-sm font-bold">2</div>
<div class="flex-1 h-0.5 bg-gray-200"></div>
<!-- Future -->
<div class="w-8 h-8 rounded-full border-2 border-gray-300 text-gray-400 flex items-center justify-center text-sm font-bold">3</div>
</div>Quick Check
Test your understanding of Tailwind CSS Mastery concepts from this lesson.
Lesson Recap
In this lesson you learned: stacked layouts use flex flex-col gap-1 for each label-input pair with space-y-5 between rows; two-column grid forms use grid grid-cols-1 sm:grid-cols-2 gap-5 with sm:col-span-2 for full-width fields; and form actions are placed right-aligned for desktop modals or full-width for mobile forms. Next up we style validation and error states.
常见问题解答
「表单布局模式」课时是免费的吗?
是的 — 「表单布局模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Tailwind CSS Academy 课程的其余内容,请升级到 CoddyKit PRO。 Tailwind CSS Academy 课程共包含 4 节课。
「表单布局模式」这节课中我会学到什么?
使用 Flex 和 Grid 以堆叠或行内布局排列标签与输入框,并配合一致的间距和对齐实用程序。 你通过在浏览器中直接运行的动手代码来练习 Tailwind CSS Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Tailwind CSS Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Tailwind CSS Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「表单布局模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Tailwind CSS Academy 课中编写并运行代码吗?
能。每节 Tailwind CSS Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。