フォームレイアウトのパターン
flexとgridを使い、間隔と配置のユーティリティを一貫させながら、ラベルと入力欄を縦並びまたは横並びに配置します。
「フォームレイアウトのパターン」はCoddyKit上の無料Tailwind CSS Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応の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.
よくある質問
「フォームレイアウトのパターン」レッスンは無料ですか?
はい。「フォームレイアウトのパターン」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Tailwind CSS Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Tailwind CSS Academyコースには全4レッスンが含まれています。
「フォームレイアウトのパターン」で何を学びますか?
flexとgridを使い、間隔と配置のユーティリティを一貫させながら、ラベルと入力欄を縦並びまたは横並びに配置します。 ブラウザで直接実行するハンズオンコードでTailwind CSS Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Tailwind CSS Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのTailwind CSS Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「フォームレイアウトのパターン」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このTailwind CSS Academyレッスンでコードを書いて実行できますか?
はい。すべてのTailwind CSS Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- テキスト入力とテキストエリアのスタイリング
- セレクトメニューとチェックボックス
- フォームレイアウトのパターン
- バリデーションとエラー状態