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

فصل ۱ از ۱۰

پیشرفت ترم
۰٪

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

حالت‌ها: pseudo-class تعاملی

فصل ۱پیش‌نمایش رایگان

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

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

چهار نمای یک دکمهٔ یکسان کنار هم: نمای عادی سفید، نمای ماوس‌رو با پس‌زمینهٔ آبیِ توپُر، نمای فشرده با آبیِ تیره‌تر، و نمای غیرفعال با رنگِ کم‌جانِ خاکستری

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

  • با :hover ظاهرِ یک عنصر را وقتی ماوس رویش است عوض کنی
  • با :active لحظهٔ فشرده‌شدن را نشان بدهی
  • با :focus-visible به کسی که با صفحه‌کلید کار می‌کند بازخوردِ برابر بدهی
  • با :disabled یک دکمهٔ غیرفعال را درست استایل کنی

قبل از شروع#

  • از ترم ۱: <button> — دکمه‌ها را با همین می‌سازیم.
  • از ترم ۴ (فصل ناوبری): outline و cursor — قابِ focus و نشانگرِ ماوس.
  • از ترم ۲: background-color و color — چیزی که در هر حالت عوض می‌کنیم.

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

۱. pseudo-class چیست؟ اولین حالت: :hover#

تا حالا هر selector یی که نوشتی به یک عنصر می‌خورد، بی‌توجه به اینکه کاربر همان لحظه دارد چه می‌کند. ولی یک دکمه فقط «یک دکمه» نیست؛ حالت‌های مختلف دارد: عادی، زیرِ ماوس، در حالِ فشرده‌شدن، غیرفعال. برای هدف‌گرفتنِ این حالت‌ها یک ابزار تازه داریم: pseudo-class.

یک pseudo-class یک کلمهٔ کوتاه است که با یک : به تهِ selector می‌چسبد و می‌گوید «فقط وقتی عنصر در این حالتِ خاص است». پرکاربردترینش :hover است، یعنی «وقتی ماوس روی این عنصر است». در آزمایشگاه اول سه دکمه را استایلِ پایه بده، بعد یک قاعدهٔ :hover اضافه کن:

.btn {
  font: inherit;
  margin-inline-end: 8px;
  padding: 10px 20px;
  border: 1px solid #2a6b93;
  border-radius: 8px;
  background-color: #ffffff;
  color: #2a6b93;
  cursor: pointer;
}

.btn:hover {
  background-color: #2a6b93;
  color: #ffffff;
}

چک کن: ماوس را روی «ذخیره» ببر — پس‌زمینه‌اش آبیِ توپُر و متنش سفید می‌شود. ماوس را که برداری، همان لحظه به حالت اول برمی‌گردد. تو فقط گفتی «در حالتِ hover این‌طور باش»؛ رفتنِ ماوس روی دکمه و برگشتنش را مرورگر خودش دنبال می‌کند.

۲. :active: لحظهٔ فشردن#

:active یعنی «همان لحظه‌ای که داری روی عنصر کلیک می‌کنی» — یعنی دکمهٔ ماوس پایین است و هنوز ولش نکرده‌ای. با یک رنگِ کمی تیره‌تر، یک بازخوردِ لمسیِ کوچک بده تا کاربر حس کند دکمه واقعاً فشرده شد:

.btn:active {
  background-color: #1f4f6e;
}

چک کن: روی یک دکمه بزن و نگه‌دار — رنگش یک پله تیره‌تر می‌شود؛ تا انگشتت را برداری، دوباره به آبیِ hover برمی‌گردد.

Checkpoint — قبل از ادامه، جواب بده: اگر یک دکمه هم :hover و هم :active داشته باشد، وقتی ماوس رویش است ولی هنوز کلیک نکرده‌ای کدام دیده می‌شود؟

جواب: :hover. تا وقتی فقط روی دکمه‌ای، در حالتِ hover هستی؛ به‌محضِ اینکه بفشاری، :active هم اضافه می‌شود و چون بعد از :hover نوشته شده، رنگِ تیره‌ترش را می‌بینی.

۳. مشکلِ صفحه‌کلید#

خیلی‌ها اصلاً از ماوس استفاده نمی‌کنند — با کلیدِ Tab بینِ دکمه‌ها و لینک‌ها می‌پرند. حالا یک لحظه فکر کن: تا اینجا تنها بازخوردِ «زنده بودنِ» دکمه، آن رنگِ :hover است. و :hover به ماوس نیاز دارد. پس این کاربر چه می‌بیند؟

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

🔧 اگر کار نکرد: اینجا چیزی «به‌هم نریخته»؛ خرابی این است که کاربرِ صفحه‌کلید بازخوردِ برابر نمی‌گیرد. راهِ حل این است که برای این کاربر هم یک حالت بسازی: :focus-visible، یعنی «وقتی عنصر با صفحه‌کلید انتخاب شده». یک قابِ پررنگ و یکدست برایش بگذار:

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

چک کن: دوباره با Tab بین دکمه‌ها حرکت کن — حالا دورِ دکمه‌ای که رویش هستی یک قابِ زرشکیِ پررنگ و یکدست ظاهر می‌شود، در هر مرورگری یک‌شکل. حالا کاربرِ صفحه‌کلید هم دقیقاً می‌داند کجاست.

۴. :focus-visible در برابر :focus#

یک pseudo-class دیگر هم هست به اسمِ :focus، و فرقشان مهم است. :focus هر بار که عنصر انتخاب می‌شود فعال می‌شود — حتی وقتی با ماوس رویش کلیک می‌کنی. نتیجه این است که بعد از یک کلیکِ ماوس، آن قاب روی دکمه می‌ماند و بیشترِ وقت‌ها زیادی و زشت به‌نظر می‌رسد.

:focus-visible هوشمندتر است: قاب را فقط وقتی نشان می‌دهد که مرورگر تشخیص بدهد کاربر واقعاً به آن نیاز دارد — یعنی وقتی با صفحه‌کلید آمده، نه وقتی با ماوس کلیک کرده. برای همین :focus-visible انتخابِ بهترِ همان قابی است که ساختیم: دقیقاً به کسی که لازمش دارد نشانش می‌دهد و کاربرِ ماوس را با یک قابِ اضافه اذیت نمی‌کند.

⚠️ مواظب باش: آن قابِ focus را هیچ‌وقت با outline: none بی‌جایگزین حذف نکن (از فصل ناوبری یادت هست). اگر ظاهرِ پیش‌فرضش را نمی‌پسندی، با :focus-visible عوضش کن — حذف‌کردنش یعنی کورکردنِ کاربرِ صفحه‌کلید.

۵. :disabled: دکمهٔ خاموش#

دکمهٔ سوم در HTML صفت disabled دارد. مرورگر خودش نمی‌گذارد کلیک شود، ولی به‌طورِ پیش‌فرض هنوز مثلِ دکمه‌های فعال دیده می‌شود — و این گول‌زننده است. با :disabled ظاهرش را هم خاموش کن تا کاربر ببیند این دکمه الان کار نمی‌کند:

.btn:disabled {
  border-color: #d8ccae;
  background-color: #efe6d0;
  color: #a89b7d;
  cursor: not-allowed;
}

چک کن: دکمهٔ «حذف» حالا کم‌رنگ و خاموش است. ماوس را رویش ببر — نشانگر به شکلِ «ممنوع» درمی‌آید و رنگش هم عوض نمی‌شود.

💡 نکته: چرا رنگِ hover روی دکمهٔ غیرفعال اثر نکرد؟ چون قاعدهٔ :disabled را بعد از :hover نوشتیم. هر دو specificity برابر دارند، پس در cascade آنکه بعد آمده برنده است (از ترم ۲ یادت هست). ترتیب اهمیت دارد: حالت‌های «خاموش» را آخر بنویس.

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

اول 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>
      <p>ماوس را روی دکمه‌ها ببر و رویشان بزن. بعد دستت را از ماوس بردار و فقط با کلید Tab بین دکمه‌ها حرکت کن.</p>
      <button class="btn">ذخیره</button>
      <button class="btn">ارسال</button>
      <button class="btn" disabled>حذف</button>
    </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: 32px 24px;
}

.btn {
  font: inherit;
  margin-inline-end: 8px;
  padding: 10px 20px;
  border: 1px solid #2a6b93;
  border-radius: 8px;
  background-color: #ffffff;
  color: #2a6b93;
  cursor: pointer;
}

/* :hover = vaghti mous rooye dokme ast */
.btn:hover {
  background-color: #2a6b93;
  color: #ffffff;
}

/* :active = lahze-ye feshordan */
.btn:active {
  background-color: #1f4f6e;
}

/* :focus-visible = vaghti ba safhe-kelid be dokme miresi */
.btn:focus-visible {
  outline: 3px solid #a36207;
  outline-offset: 2px;
}

/* :disabled = dokme-ye gheyr-e faal; akhar minevisim ta rooye hover ghalabe konad */
.btn:disabled {
  border-color: #d8ccae;
  background-color: #efe6d0;
  color: #a89b7d;
  cursor: not-allowed;
}

دو مسیر که به یک دکمهٔ یکسان می‌رسند: از یک سمت یک نشانگرِ ماوس که با رسیدنش دکمه پس‌زمینهٔ رنگی می‌گیرد، از سمتِ دیگر یک کلیدِ Tab که با رسیدنش یک قابِ پررنگ دورِ دکمه روشن می‌شود

🤖 با AI: از دستیارِ AI ات بپرس «فرقِ :focus و :focus-visible چیست و کِی کدام را به‌کار ببرم؟». جوابش را با چیزی که همین الان خودت در آزمایشگاه دیدی بسنج: با ماوس روی دکمه کلیک کن و ببین :focus-visible قاب را نشان نمی‌دهد ولی با Tab نشان می‌دهد. اول خودت ببین، بعد توضیحِ AI را قبول کن — دربارهٔ همین جزئیات گاهی با اعتمادبه‌نفس اشتباه می‌گوید.

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

کلمه تلفظ به حروف فارسی یعنی چه
pseudo-class سودو-کلاس کلمه‌ای با : که یک حالتِ خاصِ عنصر را هدف می‌گیرد
:hover هاوِر وقتی ماوس روی عنصر است
:active اکتیو همان لحظهٔ فشرده‌شدن (دکمهٔ ماوس پایین)
:focus فوکِس هر بار که عنصر انتخاب می‌شود، با ماوس یا صفحه‌کلید
:focus-visible فوکِس-ویزیبل فقط وقتی focus با صفحه‌کلید است و قاب به کار می‌آید
:disabled دیس‌ایبلد وقتی عنصر صفت disabled دارد و کار نمی‌کند

تمرین‌ها

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

در فصل بعد#

الان می‌توانی به عنصرها بر اساسِ حالتشان استایل بدهی. فصل بعد سراغِ استایل‌دادن بر اساسِ جایگاهشان می‌رویم: با selector های ساختاری مثلِ :nth-child و :first-child می‌توانی بگویی «دومین آیتمِ این فهرست» یا «آخرین کارت» بدونِ اینکه به هیچ‌کدام class بدهی، و با combinator های >، + و ~ رابطهٔ بینِ عنصرها را هدف بگیری.

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

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