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

فصل ۲ از ۱۱

پیشرفت ترم
۰٪

ترم ۲ · CSS: کنترل ظاهر

selector ها

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

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

در فصل قبل رنگ را با اسمِ tag اعمال کردی — نوشتی body یا h1 و قاعده به آن نوع عنصر خورد. ولی همیشه نمی‌خواهی همهٔ <p> ها یک‌شکل باشند؛ گاهی فقط یکی‌شان را می‌خواهی جدا کنی، یا فقط لینک‌های یک ناحیهٔ خاص را. آخر این فصل یک صفحهٔ خوراکی داری که در آن دقیقاً می‌دانی چطور هر تکه را جدا نشانه بگیری: بعضی عنصرها را با نوعشان، بعضی را با یک برچسبِ مشترک، و یکی را چون یکتاست.

سه راهِ نشانه‌گرفتن عنصرها کنار هم: همهٔ عنصرهای یک‌نوع باهم، چند عنصرِ پراکنده که یک برچسبِ مشترک دارند، و یک عنصرِ یکتا

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

  • با selectorِ نوع، همهٔ عنصرهای یک tag را با هم هدف بگیری
  • با , چند selector را در یک قاعده گروه کنی
  • یک class بسازی و آن را روی چند عنصر به‌کار ببری، و بگویی چرا class انتخابِ اولت است
  • با id یک عنصرِ یکتا را هدف بگیری و با یک فاصله، فقط عنصرهای داخلِ یک ناحیه را

قبل از شروع#

  • از فصل ۱ این ترم: ساختارِ قاعده (selector، property، value) و رنگ با color و background-color. این فصل فقط سراغِ بخشِ selector می‌رود و همان دو property را نگه می‌دارد.
  • از ترم ۱: class و id را به‌عنوان attribute داخلِ tag دیده‌ای؛ اینجا یاد می‌گیری از داخلِ CSS نشانه‌شان بگیری.

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

۱. selectorِ نوع، و گروه‌کردن با ,#

selectorی که در فصل قبل نوشتی — همان body و h1 — اسمِ رسمی‌اش type selector است: عنصرها را با نوعشان (اسمِ tag) هدف می‌گیرد. بنویسی p، به هر <p>ِ صفحه می‌خورد؛ بنویسی li، به هر <li>.

بیا در صفحهٔ خوراکی، هر دو تیتر — <h1> و <h2> ها — را سرمه‌ای کنیم. می‌شود دو قاعدهٔ جدا نوشت، ولی وقتی رنگشان یکی است، می‌توانی با یک , هر دو را در یک قاعده جمع کنی:

h1, h2 {
  color: navy;
}

آن , یعنی «و همچنین». این قاعده می‌گوید «به <h1> و به <h2> این رنگ را بده». اگر ده نوع را بخواهی یک‌شکل کنی، همه را با , پشتِ هم می‌آوری، به‌جای ده قاعدهٔ تکراری.

چک کن: تیترِ اصلی «خوراکی‌های محبوب من» و هر دو تیترِ بخش («شیرینی‌ها» و «ترش‌ها») باید سرمه‌ای شده باشند. متنِ پاراگراف‌ها و آیتم‌های فهرست هنوز دست‌نخورده‌اند.

selectorِ نوع جای خودش را دارد و قوی است: وقتی می‌خواهی یک پیش‌فرضِ کلی برای همهٔ عنصرهای یک نوع بگذاری — مثلاً همهٔ پاراگراف‌های سایت یک رنگ، یا همهٔ لینک‌ها یک شکل — دقیقاً همین را می‌خواهی. برای همین معمولاً قاعده‌های نوع را اول می‌نویسی (پیش‌فرضِ کلیِ سایت) و بعد با selector های دقیق‌ترِ این فصل استثناها را می‌سازی. این همان لایه‌به‌لایه‌فکرکردن است که پشتش را در فصل بعد کامل می‌بینی.

⚠️ مواظب باش: آن , را جا نینداز. h1, h2 یعنی «هر دو تیتر»، ولی h1 h2 (بدونِ ,) معنیِ کاملاً دیگری دارد که همین چند بخش بعد می‌بینی‌اش و به یک <h2>ِ داخلِ یک <h1> اشاره می‌کند — چیزی که تقریباً هیچ‌وقت وجود ندارد. یک ویرگولِ کوچک، دو معنیِ خیلی متفاوت.

۲. class: یک برچسب که می‌شود بارها به‌کارش برد#

type selector همهٔ عنصرهای یک نوع را با هم می‌گیرد. ولی اگر فقط بعضی از <p> ها را بخواهی چه؟ در صفحهٔ ما دو پاراگراف هست که یک نقش دارند: هر دو یک توضیحِ کوتاهِ کناری‌اند. به این دو، در HTML یک برچسب داده‌ایم: class="note".

class یک attribute است که تو انتخابش می‌کنی؛ مثلِ یک برچسب که روی هر عنصری که بخواهی می‌چسبانی. از داخلِ CSS، این برچسب را با یک . قبل از اسمش نشانه می‌گیری:

.note {
  color: gray;
}

آن . علامتِ «این یک class است» می‌دهد. این قاعده به هر عنصری که class="note" دارد می‌خورد، فرقی ندارد <p> باشد یا چیزِ دیگر.

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

همین است که class را این‌قدر پرکاربرد می‌کند: قابلِ تکرار است. یک برچسب را روی هر تعداد عنصر که بخواهی می‌گذاری و همه با یک قاعده استایل می‌گیرند. حالا بیا خوراکی‌های محبوب‌تر را برجسته کنیم؛ در HTML به دو تا <li> برچسبِ class="fav" داده‌ایم. این قاعده را اضافه کن:

.favorite {
  background-color: gold;
}

نگاه کن به فهرست. هیچ آیتمی طلایی نشد. باز هم نه خطایی، نه تغییری — سکوت.

🔧 اگر کار نکرد: طلایی‌شدن اتفاق نیفتاد چون selector به هیچ عنصری نمی‌خورد. در HTML برچسب fav است، ولی ما در CSS نوشتیم .favorite. مرورگر دنبالِ عنصری با class="favorite" گشت، پیدا نکرد، و قاعده را روی هوا رها کرد. selectorِ class باید مو‌به‌مو با اسمِ داخلِ HTML یکی باشد — حتی یک حرفِ فرق، یعنی به هیچ‌چیز نمی‌خورد. اسم را درست کن:

.fav {
  background-color: gold;
}

چک کن: حالا «شکلات» و «آلوچه» — همان دو آیتمی که برچسبِ fav دارند — پس‌زمینهٔ طلایی گرفتند. بقیهٔ آیتم‌ها دست‌نخورده‌اند.

این یک درسِ کلیدیِ selector هاست: selectorی که به هیچ‌چیز نمی‌خورد، خطا نمی‌دهد؛ فقط بی‌اثر است. پس اگر یک قاعده کار نکرد، بعد از چک‌کردنِ اتصالِ فایل (فصل ۱)، مظنونِ بعدی این است که اسمِ selector با HTML جور نیست — یک غلطِ املایی، یک حرفِ کم‌وزیاد، یا حتی حروفِ بزرگ و کوچک که در class فرق دارند.

🤖 با AI: یک سناریوی واقعی: به دستیار AI ات بگو «این قاعدهٔ CSS را نوشتم ولی رنگ اعمال نمی‌شود، چرا؟» و کد را بده. این یک کاربردِ خوبِ AI است — کمک برای فهمیدنِ یک مشکل. ولی همان‌جا قانونِ سومِ ما یادت باشد: AI هم اشتباه می‌کند. ممکن است با اطمینان بگوید مشکل از property توست، در حالی که مشکل یک غلطِ املایی در اسمِ class است. هر حدسی که داد، خودت در آزمایشگاه امتحانش کن؛ چیزی که با چشمت دیدی حرفِ آخر را می‌زند، نه توضیحِ AI.

۳. id: عنصرِ یکتا، و چرا class انتخابِ اول است#

بعضی عنصرها در صفحه فقط یکی‌اند و یکتا: نوارِ بالای صفحه، یک ناحیهٔ به‌خصوص. برای اینها یک attributeِ دیگر هست: id. در صفحهٔ ما بخشِ شیرینی‌ها id="sweet" دارد. از CSS، id را با یک # قبل از اسمش نشانه می‌گیری:

#sweet {
  background-color: cornsilk;
}

چک کن: کلِ بخشِ «شیرینی‌ها» باید یک پس‌زمینهٔ کِرِمیِ ملایم گرفته باشد، ولی بخشِ «ترش‌ها» نه.

ظاهراً id و class یک کار می‌کنند — هر دو یک عنصر را نشانه می‌گیرند. پس چرا دو تا؟ تفاوتِ اصلی در یک قانون است: هر id در کلِ صفحه فقط یک بار مجاز است. id یعنی «این عنصرِ یکتا». ولی یک class را می‌توانی روی هر تعداد عنصر بگذاری — همان‌طور که note را روی دو پاراگراف گذاشتیم.

برای همین class انتخابِ پیش‌فرضِ توست، نه id. استایل معمولاً چیزی است که می‌خواهی تکرارش کنی: همهٔ کارت‌ها، همهٔ دکمه‌ها، همهٔ هشدارها یک‌شکل. class دقیقاً برای همین ساخته شده. id یکتاست و برای استایل زیادی سفت‌وسخت است؛ به‌دردِ کارهای دیگری می‌خورد (مثلِ همان #idی که در ترم ۱ برای پرش داخلِ صفحه دیدی). قانونِ ساده: تا وقتی دلیلِ محکمی برای id نداری، class بزن.

یک مثالِ ملموس: در یک فروشگاه، دکمهٔ «افزودن به سبد» ده‌ها بار روی صفحه تکرار می‌شود و همه باید یک‌شکل باشند — این آشکارا کارِ class است. ولی نوارِ جست‌وجوی بالای صفحه فقط یکی است و یکتاست. هر وقت شک کردی، یک سؤالِ ساده از خودت بپرس: «آیا ممکن است روزی بیش از یکی از این چیز روی صفحه داشته باشم؟» اگر جواب حتی ممکن است بله باشد، class بزن. id را برای چیزی نگه دار که مطمئنی همیشه یکی می‌ماند.

قبل از ادامه، جواب بده: می‌خواهی «قیمتِ تخفیف‌خورده» را در ده‌ها کارتِ محصول قرمز کنی. class یا id؟


جواب: class. چون این استایل قرار است روی ده‌ها عنصر تکرار شود، و id در هر صفحه فقط یک بار مجاز است. یک class="sale" بساز و روی همهٔ قیمت‌های تخفیف‌خورده بگذار. هر وقت چیزی را می‌خواهی روی بیش از یک عنصر ببینی، خودبه‌خود یعنی class.

۴. selectorِ نسبی: با یک فاصله، «داخلِ»#

تا اینجا هر selector یک عنصر را مستقیم نشانه گرفت. ولی گاهی می‌خواهی بگویی «فقط لینک‌هایی که داخلِ منو هستند». در صفحهٔ ما دو جور لینک هست: لینک‌های داخلِ <nav>. اگر بنویسی a, به هر لینکِ صفحه می‌خورد. ولی اگر بین دو selector یک فاصله بگذاری، معنی عوض می‌شود:

nav a {
  color: teal;
}

آن فاصلهٔ بینِ nav و a یعنی «هر <a>یی که داخلِ یک <nav> است». به این می‌گویند descendant selector. لینک‌های بیرونِ منو دست‌نخورده می‌مانند.

چک کن: دو لینکِ منو («شیرینی‌ها» و «ترش‌ها» بالای صفحه) باید سبزآبی (teal) شده باشند. چون در این صفحه لینکِ دیگری بیرونِ منو نداریم، برای دیدنِ تفاوت یک <a href="#">تماس</a> بیرونِ <nav> و داخلِ <main> اضافه کن و ببین آن سبزآبی نمی‌شود — چون داخلِ <nav> نیست.

چرا descendant selector این‌قدر پرکاربرد است؟ چون به تو اجازه می‌دهد یک عنصر را بر اساسِ جایی که هست استایل بدهی، نه فقط بر اساسِ نوعش. همان <a>، وقتی داخلِ منوست یک شکل می‌گیرد و وقتی وسطِ یک پاراگراف است شکلِ دیگر — بدونِ اینکه به هیچ‌کدام class بدهی. به این «استایل بر اساسِ زمینه» می‌گویند و یکی از قوی‌ترین ایده‌های CSS است.

💡 نکته: فاصله را با , قاطی نکن. nav a (با فاصله) یعنی «<a>ِ داخلِ <nav>»، ولی nav, a (با ویرگول) یعنی «<nav> و همچنین هر <a>ِ صفحه». اولی یک زیرمجموعهٔ کوچک را هدف می‌گیرد، دومی هر دو نوع را کاملاً. همین یک نویسه فرقِ بینِ «داخلِ» و «و همچنین» است.

اینها همهٔ فایلِ styles.cssِ این فصل است:

/* styles.css */
h1, h2 {
  color: navy;
}

nav a {
  color: teal;
}

.note {
  color: gray;
}

.fav {
  background-color: gold;
}

#sweet {
  background-color: cornsilk;
}

و این هم HTMLِ کاملِ صفحه که برچسب‌ها و id هایش را از CSSِ بالا نشانه گرفتیم:

<!-- index.html -->
<!DOCTYPE html>
<html lang="fa" dir="rtl">
  <head>
    <meta charset="UTF-8">
    <title>خوراکی‌های من</title>
    <link rel="stylesheet" href="styles.css">
  </head>
  <body>
    <header>
      <h1>خوراکی‌های محبوب من</h1>
      <nav>
        <a href="#sweet">شیرینی‌ها</a>
        <a href="#sour">ترش‌ها</a>
      </nav>
    </header>

    <main>
      <section id="sweet">
        <h2>شیرینی‌ها</h2>
        <p class="note">اینها را همیشه دوست دارم.</p>
        <ul>
          <li>بستنی</li>
          <li class="fav">شکلات</li>
          <li>حلوا</li>
        </ul>
      </section>

      <section id="sour">
        <h2>ترش‌ها</h2>
        <p class="note">اینها بستگی به حالم دارد.</p>
        <ul>
          <li>لواشک</li>
          <li class="fav">آلوچه</li>
        </ul>
      </section>
    </main>
  </body>
</html>

یک نمودار از عنصرهای تودرتو: چند لینک داخلِ یک جعبهٔ منو رنگی شده‌اند و لینک‌های بیرونِ آن جعبه دست‌نخورده مانده‌اند، تا معنیِ «داخلِ» را نشان دهد

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

کلمه تلفظ به حروف فارسی یعنی چه
type selector تایپ سِلِکتور عنصرها را با اسمِ tag هدف می‌گیرد (مثل p)
class کلَس برچسبی که تو می‌سازی و روی چند عنصر تکرارش می‌کنی؛ در CSS با .
id آی‌دی شناسهٔ یکتا، در هر صفحه فقط یک بار؛ در CSS با #
descendant selector دِسِندِنت سِلِکتور با یک فاصله: عنصری که داخلِ عنصرِ دیگری است (مثل nav a)
grouping گروپینگ با , چند selector را در یک قاعده جمع‌کردن

تمرین‌ها

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

در فصل بعد#

الان می‌توانی هر عنصری را دقیق نشانه بگیری. ولی یک سؤالِ بزرگ باقی مانده که همین فصل چند بار لبه‌اش رفتیم: وقتی چند قاعده به یک عنصر بخورند و رنگ‌های متفاوتی بخواهند، کدام برنده می‌شود؟ چرا آن h1ِ فصل قبل بر رنگِ body غلبه کرد؟ فصل بعد — که کوتاه‌ترین و مهم‌ترین فصلِ این ترم است — دقیقاً همین را جواب می‌دهد: cascade، specificity و inheritance. این همان جایی است که بیشترِ تازه‌کارها گیر می‌کنند؛ ما با شمردن، نه حدس‌زدن، از رویش رد می‌شویم.

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

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