وضعیت‌های فرم بدون جاوااسکریپت: checked، disabled، valid و invalid

در فصل ۳ (درس ۳-۸)، به‌طور کامل با Form-related Selectors آشنا شدیم؛ از جمله :checked، :disabled، :enabled، :required، :optional، :valid، :invalid و :placeholder-shown. چون این فصل (۱۷) اختصاصاً به دسته‌بندی کامل Pseudo-classها می‌پردازه، این درس، یک مرور متمرکز و تکمیلی روی مهم‌ترین این حالت‌هاست؛ با تمرکز بیشتر روی کاربردهای عملی و نکاتی که ممکنه در فصل ۳ کمتر بهشون پرداخته باشیم.

مرور سریع: checked

input[type="checkbox"]:checked {
  accent-color: seagreen;
}

همون‌طور که در فصل ۳ دیدیم، :checked، چک‌باکس یا رادیوی انتخاب‌شده رو هدف می‌گیره. یه نکته تکمیلی: این Pseudo-class، روی تگ option داخل یک select هم قابل‌استفاده‌ست؛ یعنی می‌شه ظاهر گزینه انتخاب‌شده در یک لیست کشویی رو هم، با همین Selector، هدف قرار داد (هرچند پشتیبانی بصری کامل این حالت، به‌خاطر محدودیت‌های ظاهری خود select در مرورگرهای مختلف، متفاوته).

مرور سریع: disabled و enabled

input:disabled {
  background-color: #f0f0f0;
  cursor: not-allowed;
}

یک نکته تکمیلی مهم: :disabled، فقط روی عناصری کار می‌کنه که ذاتاً قابلیت غیرفعال شدن دارن (مثل input، button، select، textarea، fieldset)؛ روی یک عنصر معمولی مثل div که ویژگی disabled رو (به‌اشتباه) داشته باشه، این Pseudo-class، معنای واقعی و رفتار مرورگری نداره.

مرور و تعمیق: valid و invalid

input:valid {
  border-color: green;
}

input:invalid {
  border-color: red;
}

در فصل ۳، به این نکته اشاره کردیم که :invalid، معمولاً حتی روی یک فیلد خالی و اجباری، بلافاصله از ابتدای بارگذاری صفحه فعاله؛ و راه‌حلش، ترکیب :not(:placeholder-shown) با :invalid بود. حالا بیایم این تکنیک رو، در بستر کامل‌تری ببینیم.

یک مثال کامل: اعتبارسنجی بصری هوشمند فرم

input {
  border: 2px solid #ccc;
  transition: border-color 0.2s;
}

input:focus {
  border-color: royalblue;
}

/* فقط بعد از شروع تایپ کاربر، وضعیت را نشان بده */
input:not(:placeholder-shown):valid {
  border-color: seagreen;
}

input:not(:placeholder-shown):invalid {
  border-color: crimson;
}
<input type="email" placeholder="ایمیل خود را وارد کنید" required>

در این مثال، تا وقتی کاربر چیزی تایپ نکرده (یعنی placeholder هنوز نمایش داده می‌شه)، هیچ رنگ قرمز یا سبزی نمایش داده نمی‌شه؛ فقط بعد از شروع تایپ، رنگ حاشیه، بر اساس معتبر یا نامعتبر بودن مقدار وارد‌شده، تغییر می‌کنه. این الگو، تجربه کاربری بسیار بهتری نسبت به نمایش فوری خطا، از همون لحظه اول بارگذاری صفحه، ارائه می‌ده.

required و optional: نشانه‌گذاری بصری فیلدهای اجباری

label:has(+ input:required)::after {
  content: " *";
  color: crimson;
}

یک تکنیک پیشرفته‌تر: با ترکیب :has() (که در فصل ۳، درس ۳-۹ دیدیم) و :required، می‌شه یک ستاره قرمز، به‌طور کاملاً خودکار و بدون تغییر HTML، بعد از هر برچسبی که مربوط به یک فیلد اجباریه، اضافه کرد؛ به شرطی که ساختار HTML، برچسب رو دقیقاً قبل از input قرار داده باشه (که این وابستگی به ساختار، محدودیت این تکنیکه).

یک ترکیب رایج: indeterminate برای چک‌باکس‌های نیمه‌انتخاب

input[type="checkbox"]:indeterminate {
  accent-color: gray;
}

یک حالت خاص که در فصل ۳ به‌طور مستقیم ندیدیم: :indeterminate. این Pseudo-class، وقتی فعاله که یک چک‌باکس، نه کاملاً تیک‌خورده و نه کاملاً خالیه؛ حالتی که معمولاً با جاوااسکریپت تنظیم می‌شه (مثل یک چک‌باکس «انتخاب همه» که وقتی فقط بعضی از گزینه‌های زیرمجموعه‌اش تیک خوردن، این وضعیت میانی رو نشون می‌ده).

یک مثال ترکیبی و کامل برای یک فرم واقعی

.form-field input {
  border: 2px solid #ccc;
}

.form-field input:focus-visible {
  border-color: royalblue;
}

.form-field input:not(:placeholder-shown):valid {
  border-color: seagreen;
}

.form-field input:not(:placeholder-shown):invalid {
  border-color: crimson;
}

.form-field input:disabled {
  background-color: #f5f5f5;
  cursor: not-allowed;
}

.form-field input:checked + label {
  font-weight: bold;
  color: seagreen;
}

این مثال، ترکیبی از تمام حالت‌های دیده‌شده در این درس (به‌همراه :focus-visible از درس قبل) رو، در یک سیستم استایل‌دهی فرم واقعی و کامل، کنار هم می‌ذاره؛ نشون‌دهنده اینه که چقدر از منطق و بازخورد بصری یک فرم مدرن، بدون حتی یک خط جاوااسکریپت، فقط با CSS، قابل‌پیاده‌سازیه.

جدول جمع‌بندی حالت‌های فرم

Pseudo-class کاربرد
:checked چک‌باکس/رادیو/option انتخاب‌شده
:disabled / :enabled عنصر غیرفعال یا فعال فرم
:required / :optional فیلد اجباری یا اختیاری
:valid / :invalid نتیجه اعتبارسنجی مقدار وارد‌شده
:indeterminate چک‌باکس در وضعیت میانی (نه تیک‌خورده، نه خالی)

نکات مهم

  • :disabled فقط روی عناصری کار می‌کند که ذاتاً قابلیت غیرفعال شدن دارند (مثل input، button، select).
  • ترکیب :not(:placeholder-shown) با :valid/:invalid، از نمایش فوری و آزاردهنده خطا، پیش از شروع تایپ کاربر، جلوگیری می‌کند.
  • :indeterminate، وضعیت میانی یک چک‌باکس را نشان می‌دهد؛ حالتی که معمولاً با جاوااسکریپت تنظیم می‌شود، نه با کلیک مستقیم کاربر.

اشتباهات رایج

  • استفاده از :disabled روی عناصری که ذاتاً قابلیت غیرفعال شدن ندارند (مثل یک div ساده).
  • نمایش فوری حالت :invalid از همان ابتدای بارگذاری صفحه، بدون ترکیب با :not(:placeholder-shown)، که تجربه کاربری آزاردهنده‌ای ایجاد می‌کند.
  • فراموش کردن این‌که تکنیک‌های مبتنی بر :has() برای نشانه‌گذاری برچسب‌ها، به ساختار دقیق HTML (ترتیب label و input) وابسته‌اند.

جمع‌بندی

Pseudo-classهای فرم، مثل :checked، :disabled، :required، :valid و :invalid، امکان استایل‌دهی کامل به وضعیت‌های مختلف عناصر فرم را، بدون نیاز به جاوااسکریپت، فراهم می‌کنند. ترکیب هوشمندانه این Pseudo-classها با یکدیگر (مثل :not(:placeholder-shown):invalid) یا با Selectorهای مدرن‌تر مثل :has()، امکان ساخت تجربه‌های کاربری روان و بصری در فرم‌ها را می‌دهد؛ دقیقاً همان بازخوردهایی که معمولاً تصور می‌شود فقط با کد جاوااسکریپت قابل‌دستیابی هستند.