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

فصل ۳ از ۱۰

پیشرفت ترم
۰٪

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

pseudo-element ها

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

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

آخر این فصل یک کارتِ نقلِ‌قول داری که تزئین‌هایش اصلاً در HTML نیستند: کنارِ عنوان یک نوارِ رنگیِ کوچک نشسته، دورِ متنِ نقلِ‌قول یک جفت علامتِ گیومهٔ درشت آمده، و تهِ لینکِ «نظرهای بیشتر» یک فلشِ کوچک اضافه شده. اگر به HTML نگاه کنی، هیچ‌کدامِ این‌ها را نمی‌بینی — همه را CSS با یک ابزارِ تازه ساخته: pseudo-element.

یک جعبهٔ محتوای پُررنگ در وسط با دو جعبهٔ کم‌رنگِ خط‌چین در دو طرفش — یکی چسبیده به ابتدا و یکی به انتها — که نشان می‌دهد pseudo-element ها دو جعبهٔ اضافه‌اند که مرورگر می‌سازد و در HTML وجود ندارند

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

  • با ::before و ::after محتوایی بسازی که در HTML نیست
  • بگویی چرا property به‌اسمِ content برای این کار اجباری است
  • با pseudo-element یک عنوان، یک نقلِ‌قول و یک لینک را تزئین کنی
  • بدانی چرا این محتوا فقط تزئینی است و متنِ مهم را نباید در آن گذاشت

قبل از شروع#

  • از ترم ۲: background-color، border، color و text-decoration — استایلِ چیزی که pseudo-element می‌سازیم.
  • از ترم ۳: flexbox (display: flex، align-items، gap) — برای چیدنِ نوارِ کنارِ عنوان.
  • از این ترم (فصل ۱): ایده‌ای که selector می‌تواند چیزی فراتر از خودِ عنصر را هدف بگیرد.

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

۱. pseudo-element چیست؟ و چرا content اجباری است#

یک pseudo-element یک تکهٔ تازه است که مرورگر به‌جای تو داخلِ یک عنصر می‌سازد، بی‌آنکه تو در HTML چیزی بنویسی. با دو تای پرکاربردش شروع می‌کنیم: ::before یک تکه در ابتدای عنصر می‌سازد و ::after یک تکه در انتهای آن. دقت کن که این‌ها دو تا : دارند (::)، برخلافِ pseudo-class ها که یکی داشتند — همین علامت به تو می‌گوید داری یک تکهٔ تازه می‌سازی، نه یک حالت را هدف می‌گیری.

بیا کنارِ عنوان یک نوارِ رنگیِ کوچک بگذاریم. اول عنوان را یک flex container کن تا نوار و متن کنارِ هم بنشینند، بعد ::before را بساز:

.page h1 {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 1.5rem;
}

.page h1::before {
  width: 10px;
  height: 24px;
  border-radius: 3px;
  background-color: #bc3e1c;
}

به صفحه نگاه کن: هیچ نواری نیست! رنگ و اندازه را دادیم، ولی انگار ::before اصلاً وجود ندارد.

🔧 اگر کار نکرد: این پرتکرارترین اشتباهِ pseudo-element هاست. یک ::before یا ::after تا وقتی property به‌اسمِ content نداشته باشد، اصلاً ساخته نمی‌شود — انگار نوشته‌ای‌اش ولی مرورگر نادیده‌اش می‌گیرد. content همان چیزی است که به مرورگر می‌گوید «این تکه واقعاً باید باشد». حتی اگر محتوایی نمی‌خواهی و فقط یک جعبهٔ رنگی می‌خواهی، باید content را با یک رشتهٔ خالی بنویسی. این خط را به بالای قاعده اضافه کن:

.page h1::before {
  content: "";
  width: 10px;
  height: 24px;
  border-radius: 3px;
  background-color: #bc3e1c;
}

چک کن: حالا یک نوارِ قرمزِ کوچک درست کنارِ عنوان ظاهر شد. آن content: "" خالی است ولی حضورش لازم بود. خطِ content را یک‌بار پاک کن و ببین نوار دوباره غیب می‌شود — این را خوب یادت بماند.

۲. content با متن: علامتِ نقلِ‌قول#

content فقط خالی نمی‌ماند؛ می‌توانی داخلش متن بگذاری و مرورگر همان را روی صفحه می‌سازد. یک کاربردِ کلاسیک، گذاشتنِ علامتِ گیومه دورِ یک نقلِ‌قول است. با ::before گیومهٔ باز و با ::after گیومهٔ بسته را به متنِ نقلِ‌قول بچسبان:

.quote p::before {
  content: "«";
  color: #2a6b93;
  font-size: 1.6rem;
  font-weight: 700;
  margin-inline-end: 4px;
}

.quote p::after {
  content: "»";
  color: #2a6b93;
  font-size: 1.6rem;
  font-weight: 700;
  margin-inline-start: 4px;
}

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

۳. ::after برای یک نشانه: فلشِ «بیشتر»#

روی لینک‌ها هم ::after عالی است. بیا تهِ لینکِ «نظرهای بیشتر» یک فلشِ کوچک بگذاریم تا نشان بدهد جایی می‌برد:

.more {
  color: #2a6b93;
  font-weight: 700;
  text-decoration: none;
}

.more::after {
  content: " ←";
}

چک کن: حالا بعد از متنِ لینک یک فلش دیده می‌شود. چون صفحه راست‌به‌چپ است، فلشِ «رو به جلو» به سمتِ چپ اشاره می‌کند. عددِ فاصله و خودِ علامت را عوض کن (مثلاً " ↩" یا " •") و ببین چطور فوری تغییر می‌کند.

۴. مهم: content تزئینی است، نه متنِ واقعی#

یک قانونِ مهم که به SEO و دسترس‌پذیری وصل است: چیزی که در content می‌گذاری فقط برای تزئین است. این متن بخشِ واقعیِ صفحه نیست — انتخاب نمی‌شود، ترجمه نمی‌شود، در جست‌وجو پیدا نمی‌شود، و بعضی screen reader ها اصلاً آن را نمی‌خوانند. AI crawler ها هم که JavaScript و گاهی این محتوای ساختگی را نمی‌بینند.

⚠️ مواظب باش: هیچ‌وقت متنِ مهم را فقط در content نگذار. اگر یک جمله باید خوانده و پیدا شود، جایش داخلِ HTML واقعی است (<p>، <span>، …). گیومه و فلش و نوارِ رنگی چون فقط تزئین‌اند، جایشان در content درست است؛ ولی «۲۰٪ تخفیف» یا نامِ یک محصول هرگز نباید فقط یک pseudo-element باشد.

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

اول 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>pseudo-element ها</title>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <main class="page">
      <h1>نظر خواننده‌ها</h1>
      <blockquote class="quote">
        <p>این درس‌ها را که خواندم، اولین سایتم را در یک هفته ساختم.</p>
      </blockquote>
      <a class="more" href="#">نظرهای بیشتر</a>
    </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;
  max-width: 480px;
}

/* onvan yek nava-r-e taakid-e kenari migirad */
.page h1 {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 1.5rem;
}

/* content khali ast vali BAYAD bashad, vagarna hich chiz peyda nemishavad */
.page h1::before {
  content: "";
  width: 10px;
  height: 24px;
  border-radius: 3px;
  background-color: #bc3e1c;
}

.quote {
  margin-block: 20px;
  padding: 16px 20px;
  border-inline-start: 4px solid #2a6b93;
  border-radius: 8px;
  background-color: #ffffff;
}

.quote p {
  margin: 0;
}

/* alamat-e naghl-e ghol: metn dakhel-e content */
.quote p::before {
  content: "«";
  color: #2a6b93;
  font-size: 1.6rem;
  font-weight: 700;
  margin-inline-end: 4px;
}

.quote p::after {
  content: "»";
  color: #2a6b93;
  font-size: 1.6rem;
  font-weight: 700;
  margin-inline-start: 4px;
}

.more {
  color: #2a6b93;
  font-weight: 700;
  text-decoration: none;
}

/* flesh-e tazeini bad az matn-e link */
.more::after {
  content: " ←";
}

یک کارتِ نقلِ‌قول با یک جفت شکلِ تزئینیِ درشتِ گیومه‌مانند در گوشه‌ها، یک نوارِ رنگیِ کوچک کنارِ عنوان، و یک فلشِ کوچک تهِ لینک — همه به‌عنوانِ تزئین‌هایی که CSS اضافه کرده

🤖 با AI: از دستیارِ AI ات بپرس «فرقِ ::before با یک <span> واقعی در HTML چیست و کِی کدام را به‌کار ببرم؟». جوابش را با چیزی که همین فصل دیدی بسنج: pseudo-element برای تزئین است و متنش کپی و جست‌وجو نمی‌شود، پس متنِ مهم باید <span> واقعی باشد. اگر AI پیشنهاد داد یک متنِ معنادار را در content بگذاری، همان‌جا با این قانون ردش کن.

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

کلمه تلفظ به حروف فارسی یعنی چه
pseudo-element سودو-اِلِمنت تکه‌ای که مرورگر می‌سازد و در HTML نیست؛ با ::
::before بیفور تکه‌ای که در ابتدای عنصر ساخته می‌شود
::after افتر تکه‌ای که در انتهای عنصر ساخته می‌شود
content کانتنت property که می‌گوید pseudo-element چه محتوایی دارد؛ بدونش ساخته نمی‌شود

تمرین‌ها

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

در فصل بعد#

الان می‌توانی با selector و pseudo-element جزئیاتِ ظاهری بسازی. فصل بعد سراغِ چیزی می‌رویم که تا حالا بهش دست نزدیم: فرم‌ها. یاد می‌گیری <input>، <button>، <select> و <textarea> را استایل بدهی، با selector صفتی مثلِ [type="email"] عنصرها را بر اساسِ صفتشان هدف بگیری، با :focus-within کلِ یک ردیف را موقعِ تایپ روشن کنی، و با accent-color رنگِ چیزی مثلِ checkbox را عوض کنی.

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

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