Tailwind CSS Academy · Les

Patronen voor formulierindelingen

Rangschik labels en invoervelden verticaal of inline met flex en grid, met consistente gap- en uitlijningsutilities.

Les 3 van 413 stappen

Patronen voor formulierindelingen is een gratis Tailwind CSS Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Tailwind CSS Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Tailwind CSS Academy bevat in totaal 4 lessen.

Waarom formulierindeling belangrijk is

De indeling van een formulier is net zo belangrijk als de opmaak van de afzonderlijke velden. Een goed gestructureerd formulier begeleidt gebruikers op een natuurlijke manier bij het invullen, terwijl een slecht ingedeeld formulier ertoe leidt dat meer gebruikers afhaken. Formulierindeling omvat de plaatsing van labels en invoervelden, de indeling van velden in meerdere kolommen en de plaatsing van acties zoals verzenden en annuleren.

De flex- en grid-utilities van Tailwind maken al deze indelingen eenvoudig zonder aangepaste CSS te schrijven.

Gestapelde (verticale) formulierindeling

Bij de gestapelde indeling staan labels direct boven hun invoervelden. Dit is de meest mobielvriendelijke en leesbare aanpak. Elk label-invoerpaar staat in een container met flex flex-col gap-1 en tussen de paren gebruikt het volledige formulier space-y-5.

Deze indeling heeft aantoonbaar de hoogste voltooiingspercentages, omdat gebruikers het label lezen voordat ze het invoerveld zien. Zo krijgen ze context voordat ze een handeling moeten uitvoeren.

<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 (horizontale) formulierindeling

Bij een inline-indeling staat het label links van de invoer op dezelfde rij. Dit is compact en werkt goed voor beheerdersformulieren of zoekfilters waarbij verticale ruimte schaars is. Gebruik flex items-center gap-4 op elke rij en geef het label een vaste breedte, zoals w-32 flex-shrink-0, zodat alle labels aan dezelfde rechterrand uitlijnen.

Op mobiele apparaten moeten deze inline-rijen met responsieve breekpunten overschakelen naar een gestapelde indeling: 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>

Formulierrooster met twee kolommen

Voor formulieren met veel velden bespaart een rooster met twee kolommen verticale ruimte door twee velden naast elkaar te plaatsen. Gebruik grid grid-cols-1 sm:grid-cols-2 gap-5 op de inhoud van het formulier. Velden die de volledige breedte nodig hebben, zoals een tekstgebied voor een bericht, gebruiken sm:col-span-2.

Dit patroon komt zeer vaak voor in formulieren voor het afrekenen, pagina's voor het bewerken van profielen en registratieformulieren.

<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>

Scheidingen tussen formuliersecties

Lange formulieren worden opgesplitst in logische secties om de cognitieve belasting te verlagen. Voeg een sectiekop toe met text-base font-semibold text-gray-900 en een subtiele scheiding met border-t border-gray-200 pt-6 mt-6 om groepen velden visueel van elkaar te scheiden.

Veelvoorkomende secties voor een profielformulier zijn: Persoonlijke gegevens, Contactgegevens, Voorkeuren en Beveiliging. Elke sectie behandelt een duidelijk onderwerp, zodat gebruikers de structuur van het formulier begrijpen voordat ze het invullen.

<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>

Aanduidingen voor verplichte velden

Verplichte velden worden meestal aangeduid met een rood sterretje. Plaats een <span class="text-red-500">*</span> direct na de labeltekst. Voeg bovenaan het formulier eventueel een toelichting toe, zoals Verplichte velden zijn gemarkeerd met *.

Valideer verplichte velden altijd aan de serverkant. De visuele aanduiding is een gebruiksgemak, geen beveiligingsmaatregel. Gebruik het HTML-attribuut required op invoervelden voor validatie door de browser als eerste 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>

Toelichtende tekst onder velden

Toelichtende tekst geeft extra context of instructies over de notatie onder een invoerveld. Gebruik mt-1 text-xs text-gray-500 op een <p>-tag onder de invoer en koppel deze via aria-describedby aan de invoer voor ondersteuning van schermlezers.

Houd de toelichtende tekst beknopt — maximaal één korte zin. Bij wachtwoordvelden voorkomt een toelichting over de vereisten voor de sterkte, zoals minimaal 8 tekens en één cijfer, frustrerende validatiefouten na het verzenden.

<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>

Plaatsing van formulieractieknoppen

De plaatsing van de verzendknop heeft invloed op het voltooiingspercentage van een formulier. Voor gestapelde formulieren met één kolom werkt een knop over de volledige breedte met w-full goed. Plaats bij formulieren in kaarten of modale formulieren de primaire en secundaire acties rechtsonder met flex justify-end gap-3.

Plaats de destructieve of secundaire actie (Annuleren, Reset) altijd links van de primaire actie (Verzenden, Opslaan), zodat gebruikers Annuleren vóór Verzenden lezen en niet per ongeluk verzenden wanneer ze proberen te annuleren.

<!-- 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>

Patroon met zwevend label

Een zwevend label begint als plaatshoudertekst in het invoerveld en zweeft boven het invoerveld wanneer de gebruiker de focus erop zet of begint te typen. Dit bespaart verticale ruimte en houdt het label toch zichtbaar. Implementeer dit met relative op de omvattende container, een absolute label dat verandert bij de statussen focus en not-placeholder-shown, en utilities met peer.

De belangrijkste utility is peer-placeholder-shown:translate-y-0 om het label in een leeg invoerveld te houden, en peer-focus:-translate-y-6 peer-focus:scale-75 om het bij focus erboven te laten zweven.

<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>

Inlineformulier (stijl van een zoekbalk)

Een inlineformulier plaatst de invoer en de verzendknop op dezelfde regel, zoals bij een aanmelding voor een nieuwsbrief of een zoekbalk in een hero-sectie. Gebruik een container met flex gap-2, waarbij de invoer flex-1 inneemt en de knop een vaste breedte heeft.

Op mobiele apparaten kunnen deze elementen verticaal worden gestapeld met flex-col sm:flex-row, zodat de invoer op kleine schermen de volledige breedte gebruikt en de knop eronder komt te staan.

<!-- 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>

Navigatie in een meerstappenformulier

Lange formulieren hebben baat bij navigatie in meerdere stappen, waarbij ze worden opgesplitst in logische fasen. Een voortgangsindicator bovenaan toont de huidige stap. De inhoud van elke stap wordt voorwaardelijk weergegeven en navigatieknoppen (Terug/Volgende) staan onderaan.

Maak de stapindicatoren op als genummerde cirkels: w-8 h-8 rounded-full flex items-center justify-center text-sm font-bold. Voltooide stappen gebruiken bg-blue-600 text-white, de huidige stap gebruikt border-2 border-blue-600 text-blue-600 en toekomstige stappen gebruiken 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>

Korte controle

Test je begrip van de concepten uit Tailwind CSS Mastery in deze les.

Samenvatting van de les

In deze les heb je geleerd dat gestapelde indelingen flex flex-col gap-1 gebruiken voor elk label-invoerpaar, met space-y-5 tussen de rijen; dat formulieren met een rooster van twee kolommen grid grid-cols-1 sm:grid-cols-2 gap-5 gebruiken, met sm:col-span-2 voor velden over de volledige breedte; en dat formulieracties op desktopmodale vensters rechts uitgelijnd worden geplaatst of op mobiele formulieren de volledige breedte krijgen. Hierna maken we validatie- en foutstatussen op.

Gratis beginnen

Leer HTML met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
30
Lessen
120

Veelgestelde vragen

Is de les “Patronen voor formulierindelingen” gratis?

Ja — de volledige tekst van “Patronen voor formulierindelingen” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Tailwind CSS Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Tailwind CSS Academy bevat in totaal 4 lessen.

Wat leer ik in “Patronen voor formulierindelingen”?

Rangschik labels en invoervelden verticaal of inline met flex en grid, met consistente gap- en uitlijningsutilities. Je oefent met Tailwind CSS Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Tailwind CSS Academy te beginnen?

Ervaring vooraf is niet nodig. Tailwind CSS Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “Patronen voor formulierindelingen”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Tailwind CSS Academy?

Ja. Elke les over Tailwind CSS Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Tekstinvoervelden en textareas opmaken
  2. Selectiemenu's en checkboxen
  3. Patronen voor formulierindelingen
  4. Validatie- en foutstatussen
← Terug naar Tailwind CSS Academy