تاروپود — خودآموز HTML و CSS

فصل ۴ از ۱۰

پیشرفت ترم
۰٪

ترم ۵ · تعامل و جزئیات

استایل فرم

فصل ۴پیش‌نمایش رایگان
۸ دقیقه مطالعه فصل ۴

در این فصل چه می‌سازی#

فرم‌ها را در ترم ۱ ساختی، ولی هیچ‌وقت استایلشان ندادی — و فرم‌های خام و پیش‌فرض، زشت و ناهماهنگ‌اند. آخر این فصل یک فرمِ تماسِ تر و تمیز داری: کادرهای متن و منوی کشویی و جعبهٔ پیام همه یک شکل و یک فونت‌اند، ردیفی که داری تویش تایپ می‌کنی روشن می‌شود تا بدانی کجایی، فیلدِ غیرفعال خاموش دیده می‌شود، و حتی رنگِ checkbox هم به رنگِ سایت درآمده.

یک فرمِ تماسِ استایل‌خورده با چند کادرِ ورودیِ هم‌شکل، یک منوی کشویی، یک جعبهٔ پیامِ بزرگ‌تر، یک checkbox رنگی و یک دکمهٔ ارسال؛ یکی از ردیف‌ها با یک هالهٔ ملایم روشن شده تا نشان دهد الان focus داخلش است

آخر این فصل می‌توانی:

  • <input>، <select>، <textarea> و <button> را یک‌دست استایل بدهی
  • با selector صفتی مثلِ [type="email"] و [disabled] عنصرها را با صفتشان هدف بگیری
  • با :focus-within کلِ ردیفِ فعال را روشن کنی
  • با accent-color رنگِ یک checkbox را عوض کنی

قبل از شروع#

  • از ترم ۱: <form>، <input>، <label>، <select>، <textarea> و <button> — همه را از قبل بلدی؛ اینجا فقط استایلشان می‌دهیم.
  • از این ترم (فصل ۱): :hover و :focus-visible — روی دکمهٔ ارسال دوباره به کارمان می‌آیند.
  • از ترم ۲: border، border-radius، background-color و specificity.

مثل همیشه فقط یک مرورگر لازم داری، یا فقط همین آزمایشگاه.

۱. یک‌دست‌کردنِ کنترل‌های متنی#

اول سه کنترلِ اصلی — کادرِ متن، منوی کشویی و جعبهٔ پیام — را یک‌شکل کن. یک نکتهٔ مهم اینجاست: کنترل‌های فرم فونتِ صفحه را به ارث نمی‌برند؛ هرکدام فونتِ پیش‌فرضِ خودشان را دارند، برای همین متنِ داخلِ <textarea> اغلب با بقیهٔ صفحه فرق دارد. با font: inherit مجبورشان کن فونتِ صفحه را بگیرند:

.field input,
.field select,
.field textarea {
  font: inherit;
  width: 100%;
  padding: 10px;
  border: 1px solid #d8ccae;
  border-radius: 8px;
  background-color: #ffffff;
  color: #2c2114;
}

چک کن: هر سه کنترل حالا یک قابِ نرم، یک اندازه و یک فونت دارند. خطِ font: inherit را یک لحظه پاک کن و به جعبهٔ پیام نگاه کن — فونتش می‌پرد به یک فونتِ دیگر. همین یک خط، ناهماهنگیِ رایجِ فرم‌ها را حل می‌کند.

۲. selector صفتی: انتخاب با [...]#

تا حالا با نوع، class و id انتخاب می‌کردی. یک راهِ دیگر هم هست: انتخاب بر اساسِ صفتِ (attribute) عنصر، با کروشه. input[type="email"] یعنی «هر <input> که صفتِ type اش email است». این برای فرم‌ها عالی است، چون فیلدها اغلب فقط با type از هم فرق دارند. بیا فیلدِ ایمیل را با یک قابِ آبی متمایز کنیم:

.contact input[type="email"] {
  border-color: #2a6b93;
}

چک کن: فقط کادرِ ایمیل قابِ آبی گرفت؛ بقیه دست‌نخورده ماندند. صفت لازم نیست مقدار داشته باشد — [disabled] تنها به وجودِ صفت نگاه می‌کند. فیلدِ «تلفن» در HTML صفتِ disabled دارد؛ بیا همهٔ کنترل‌های غیرفعال را خاموش نشان بدهیم:

.contact [disabled] {
  background-color: #efe6d0;
  color: #a89b7d;
  cursor: not-allowed;
}

چک کن: کادرِ «تلفن» کم‌رنگ و خاموش شد و نشانگرِ ماوس رویش «ممنوع» می‌شود. [disabled] هر عنصری با آن صفت را می‌گیرد، فرقی نمی‌کند <input> باشد یا <button>.

۳. :focus-within: روشن‌کردنِ کلِ ردیف#

وقتی داخلِ یک کادر تایپ می‌کنی، خودِ کادر یک قابِ focus می‌گیرد (کارِ مرورگر). ولی خوب است کلِ ردیف — برچسب و کادر با هم — هم روشن شود تا چشم راحت بفهمد کجاست. برای این کار pseudo-class تازه‌ای داریم: :focus-within، یعنی «وقتی focus داخلِ این عنصر یا یکی از فرزندانش است». روی خودِ ردیف بگذارش:

.field:focus-within {
  background-color: #f0e7d2;
}

چک کن: داخلِ یک کادر کلیک کن یا با Tab بهش برس — کلِ آن ردیف یک پس‌زمینهٔ ملایم می‌گیرد، و تا focus بیرون برود پاک می‌شود. دقت کن که رنگ روی خودِ <input> ننشست، بلکه روی <p class="field"> که دورش است؛ :focus-within والد را وقتی چیزی درونش فعال است هدف می‌گیرد. این همان چیزی است که با فقط :focus روی خودِ کادر نمی‌شد.

۴. accent-color: رنگِ کنترل‌های بومی#

حالا سراغِ checkbox می‌رویم، و اینجا به یک دیوار می‌خوریم. checkbox پیش‌فرض خاکستری است و می‌خواهی آبی‌اش کنی. کاری که برای هر جعبهٔ دیگری جواب می‌داد را امتحان کن — background-color و border:

.check input {
  background-color: #2a6b93;
  border: 2px solid #2a6b93;
}

به checkbox نگاه کن: هیچ فرقی نکرد. هنوز همان مربعِ خاکستریِ پیش‌فرض است. انگار CSS ات را نادیده گرفت.

🔧 اگر کار نکرد: درست دیدی — و این یک خطای تایپی نیست. بعضی کنترل‌های فرم مثلِ checkbox و radio را خودِ سیستم‌عامل می‌کشد، و بیشترِ property های جعبه (background-color، border) را نادیده می‌گیرند. یک property مخصوص برای همین ساخته شده: accent-color. آن قاعدهٔ بی‌اثر را پاک کن و به‌جایش این را بگذار:

.check {
  accent-color: #2a6b93;
}

چک کن: حالا checkbox را تیک بزن — تیک و مربعش آبیِ سایت شد. accent-color همان یک property درست برای رنگ‌کردنِ کنترل‌های بومی است، و چون به ارث می‌رسد، گذاشتنش روی یک والد کافی است تا همهٔ checkbox و radio های داخلش رنگ بگیرند.

💡 نکته: درسِ بزرگ‌ترِ این بخش این است: کنترل‌های فرم مثلِ جعبه‌های معمولی نیستند. بعضی چیزها (قاب، فاصله، فونت، رنگِ متن) را می‌پذیرند، بعضی چیزها (شکلِ داخلیِ checkbox) را نه. قبل از جنگیدن با یک کنترلِ لجباز، اول ببین آیا یک property مخصوص مثلِ accent-color برایش هست.

کد کاملِ این فصل#

اول index.html:

<!-- index.html -->
<!DOCTYPE html>
<html lang="fa" dir="rtl">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>استایل فرم</title>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <main class="page">
      <h1>فرم تماس</h1>
      <form class="contact">
        <p class="field">
          <label for="name">نام</label>
          <input id="name" type="text" name="name">
        </p>
        <p class="field">
          <label for="email">ایمیل</label>
          <input id="email" type="email" name="email">
        </p>
        <p class="field">
          <label for="topic">موضوع</label>
          <select id="topic" name="topic">
            <option>پرسش</option>
            <option>پیشنهاد</option>
            <option>گزارش مشکل</option>
          </select>
        </p>
        <p class="field">
          <label for="message">پیام</label>
          <textarea id="message" name="message" rows="4"></textarea>
        </p>
        <p class="field">
          <label for="phone">تلفن (فعلاً غیرفعال)</label>
          <input id="phone" type="text" name="phone" disabled>
        </p>
        <p class="check">
          <label><input type="checkbox" name="accept"> قوانین را می‌پذیرم</label>
        </p>
        <button type="submit" class="submit">ارسال</button>
      </form>
    </main>
  </body>
</html>

و styles.css:

/* styles.css */
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: Tahoma, sans-serif;
  background-color: #f6edda;
  color: #2c2114;
  line-height: 1.8;
}

.page {
  padding: 24px;
}

.contact {
  max-width: 420px;
}

.field {
  margin-block: 0 16px;
  padding: 8px;
  border-radius: 8px;
}

.field label {
  display: block;
  margin-block-end: 4px;
  font-weight: 700;
}

/* input/select/textarea font-e khodeshan ra darand va be ers nemibarand */
.field input,
.field select,
.field textarea {
  font: inherit;
  width: 100%;
  padding: 10px;
  border: 1px solid #d8ccae;
  border-radius: 8px;
  background-color: #ffffff;
  color: #2c2114;
}

/* selector-e sefati: faghat field-e email */
.contact input[type="email"] {
  border-color: #2a6b93;
}

/* selector-e sefati: har control ke disabled ast */
.contact [disabled] {
  background-color: #efe6d0;
  color: #a89b7d;
  cursor: not-allowed;
}

/* vaghti focus dakhel-e field ast, kol-e radif roshan mishavad */
.field:focus-within {
  background-color: #f0e7d2;
}

/* accent-color rang-e native-e checkbox ra avaz mikonad */
.check {
  accent-color: #2a6b93;
}

.submit {
  font: inherit;
  padding: 12px 24px;
  border: none;
  border-radius: 8px;
  background-color: #2a6b93;
  color: #ffffff;
  cursor: pointer;
}

.submit:hover {
  background-color: #1f4f6e;
}

.submit:focus-visible {
  outline: 3px solid #a36207;
  outline-offset: 2px;
}

یک checkbox پیش‌فرضِ خاکستری در برابر همان checkbox که با accent-color تیک‌خورده و آبی شده است؛ کنارشان یک ردیفِ فرم که با focus-within یک هالهٔ ملایم گرفته

🤖 با AI: از دستیارِ AI ات بپرس «چرا background-color روی یک checkbox کار نمی‌کند و راهِ درستش چیست؟». جوابش را با چیزی که همین فصل با چشمت دیدی بسنج: کنترل‌های بومی بیشترِ استایلِ جعبه را نمی‌پذیرند و رنگشان با accent-color عوض می‌شود. اگر AI پیشنهادِ یک ترفندِ پیچیده داد (مثلاً پنهان‌کردنِ checkbox و کشیدنِ یکیِ تقلبی)، همان‌جا در آزمایشگاه امتحانش کن و ببین آیا با صفحه‌کلید هم هنوز کار می‌کند — راهِ ساده‌تر معمولاً درست‌تر است.

واژه‌های تازهٔ این فصل#

کلمه تلفظ به حروف فارسی یعنی چه
selector صفتی سِلِکتورِ صفتی انتخاب با کروشه بر اساسِ صفت، مثلِ [type="email"]
[disabled] دیس‌ایبلد هر عنصری که صفتِ disabled دارد
:focus-within فوکِس-ویدین وقتی focus داخلِ عنصر یا یکی از فرزندانش است
accent-color اکسنت-کالر رنگِ کنترل‌های بومی مثلِ checkbox و radio
font: inherit فونت اینهریت کنترلِ فرم را وادار می‌کند فونتِ صفحه را بگیرد

تمرین‌ها

اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.

در فصل بعد#

الان می‌توانی یک فرم را زیبا و یک‌دست کنی. ولی یک فرمِ خوب فقط زیبا نیست — به کاربر می‌گوید کدام فیلد اجباری است و کِی چیزی را اشتباه پر کرده. فصل بعد سراغِ همین می‌رویم: با :required، :valid و :invalid از اعتبارسنجیِ بومیِ خودِ مرورگر استفاده می‌کنی تا فرم بدونِ یک خط JavaScript به کاربر بازخوردِ درست و غلط بدهد.

به آخر این فصل رسیدی!

اگر ساختی و جواب داد، این دکمه مال توست.