Lesson 14 / الدرس 14

Forms: inputs, labels and errors / النماذج: الحقول والتسميات والأخطاء

Bootstrap styles form controls for you; Tailwind does not touch them until you say so. Both leave the two things that actually matter — the label and the error — entirely up to you.

ينسّق Bootstrap عناصر النموذج عنك؛ وTailwind لا يمسّها حتى تقول. وكلاهما يترك الشيئين المهمين فعلًا — التسمية والخطأ — لك تمامًا.

BOOTSTRAP
  <label class="form-label" for="email">Email</label>
  <input class="form-control" id="email" type="email">

TAILWIND
  <label class="block text-sm font-medium mb-1" for="email">Email</label>
  <input id="email" type="email"
         class="w-full rounded border border-slate-300 px-3 py-2
                focus:border-sky-500 focus:ring-1 focus:ring-sky-500">
Note what is identical in both: the for and the id. That pair is what makes the label clickable and what a screen reader reads out when the field is focused, and no framework supplies it. Run the demonstration for a complete field, including the error state.

The label is not optional

A placeholder is not a label. It disappears the moment someone types, so the person who looks away mid-form has no way to know what the field was; it is styled as faint grey, which often fails contrast; and a screen reader treats it as a hint rather than a name. Every field needs a real <label> joined by for and id. This is the HTML course's point, and neither framework will remind you.

ControlBootstrapTailwind
Text inputform-controlA handful of border and padding classes
Selectform-selectThe same, plus appearance-none if restyling
Checkboxform-check-inputaccent-sky-600, or a plugin
Textareaform-controlThe same as a text input
A whole field groupmb-3 wrapping label and inputspace-y-1 on a wrapper
Invalid stateis-invalid + invalid-feedbackborder-red-500 + your own message

Tailwind publishes an official forms plugin that resets controls to something sensible before you style them. Without it, a <select> keeps the operating system look, which is jarring beside styled inputs — this is the one place a Tailwind page needs a plugin to look finished.

Errors that help

A useful error message does three things: it appears beside the field it is about, it says what is wrong in words rather than only in red, and it says what would be right. "Invalid input" fails all three. "That does not look like an email address — it needs an @" passes all three and is no harder to write.

Both frameworks also offer validation styles that appear as the user types. Use them carefully: telling someone their email is invalid while they are still typing the first three letters is worse than saying nothing. Validate on leaving a field, or on submit, and remove the error the moment they start fixing it.

Try it live / جرّب بنفسك

Preview / المعاينة

Check yourself / اختبر نفسك

1. Why is a placeholder not a substitute for a label?

2. What does aria-describedby do on an invalid field?

3. Which costs nothing and improves a form more than any styling?

Your task / مهمتك

Build the same four-field form in both frameworks — name, email, a select and a message — with real labels, correct input types and autocomplete attributes. Then show one field in its error state, with a message that says what is wrong and what would be right, tied to the field with aria-describedby. Finish by filling the form using only the keyboard and reporting anything awkward.

ابنِ النموذج نفسه بأربعة حقول في الإطارين — اسم وبريد وقائمة ورسالة — بتسميات حقيقية وأنواع حقول صحيحة وسمات autocomplete. ثم أظهر حقلًا واحدًا في حالة الخطأ، برسالة تقول ما الخطأ وما الصواب، مربوطة بالحقل بـaria-describedby. واختم بملء النموذج بلوحة المفاتيح وحدها والإبلاغ عن كل ما كان محرجًا.

  • Four fields, in both frameworks, every one labelled أربعة حقول في الإطارين، كل واحد موسوم
  • Correct type and autocomplete on each type وautocomplete صحيحان على كل واحد
  • An error state with a message in words حالة خطأ برسالة بالكلمات
  • Filled with the keyboard only, and reported مملوء بلوحة المفاتيح وحدها، مبلَّغ عنه
How do you want to submit? / كيف تريد التسليم؟