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

فصل ۱۱ از ۱۱

پیشرفت ترم
۰٪

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

صفحهٔ ترم ۱ را زنده کن

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

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

این آخرین فصلِ ترمِ CSS است، و مفهومِ تازه‌ای ندارد. کارِ امروز ترکیب است: همان صفحهٔ semantic ای را که در ترم ۱ ساختی — «وبلاگ من» — برمی‌داری و از صفر با CSS زنده‌اش می‌کنی. آن صفحه الان فقط متنِ سیاه روی سفید است؛ آخرِ این فصل یک صفحهٔ تمیز و خوش‌ظاهر می‌شود: theme با رنگ‌های خودت، فونتِ فارسی، فاصله‌های درست، و بخش‌هایی که مثلِ کارت روی صفحه نشسته‌اند. هر چیزی که این ترم یاد گرفتی، این‌جا کنارِ هم می‌آید.

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

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

  • یک صفحهٔ semantic ای موجود را بدون تغییرِ ساختارش، فقط با CSS زیبا کنی
  • یک theme کوچک با custom property بسازی و کلِ صفحه را با آن هماهنگ کنی
  • محتوا را در یک ستونِ وسط‌چین، در جریانِ عادی، مرتب کنی
  • بخش‌های صفحه را با تزئینِ فصل ۸ به کارت تبدیل کنی

قبل از شروع#

  • از ترم ۱: صفحهٔ «وبلاگ من» — همان index.html که در فصل semantic ساختی، نقطهٔ شروعِ ماست.
  • از فصل ۱: <link rel="stylesheet"> — این‌طور CSS را به HTML وصل می‌کنیم.
  • از فصل‌های ۸ و ۹: تزئین (حاشیه، گوشهٔ گرد، سایه) و custom property.

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

۱. نقشهٔ کار: از صفحهٔ لخت شروع کن#

این همان صفحه‌ای است که در ترم ۱ ساختی — با چند کلاس که فقط برای این‌که با CSS راحت هدفشان بگیریم اضافه شده‌اند (site-header، menu، card، more، site-footer). ساختارش دست‌نخورده است؛ همان <header>، <nav>، <main>، <article>، <section>، <aside>، <footer>:

<!-- 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 class="site-header">
      <h1>وبلاگ من</h1>
      <nav>
        <ul class="menu">
          <li><a href="#posts">پست‌ها</a></li>
          <li><a href="#about">دربارهٔ من</a></li>
        </ul>
      </nav>
    </header>

    <main>
      <article id="posts" class="card">
        <h2>اولین روزم با CSS</h2>
        <p>امروز یاد گرفتم چطور یک صفحهٔ ساده را با رنگ و فاصله و تزئین زنده کنم.</p>
        <p>دیگر صفحه‌ام فقط متنِ سیاه روی سفید نیست.</p>
        <a class="more" href="#">ادامهٔ مطلب ←</a>
      </article>

      <section id="about" class="card">
        <h2>چند کلمه دربارهٔ من</h2>
        <p>تازه ساختن سایت را یاد می‌گیرم و هر چه یاد بگیرم همین‌جا می‌نویسم.</p>
      </section>
    </main>

    <aside class="card">
      <h2>لینک‌های مفید</h2>
      <ul>
        <li><a href="#">راهنمای HTML</a></li>
        <li><a href="#">تمرین‌های بیشتر</a></li>
      </ul>
    </aside>

    <footer class="site-footer">
      <p>ساختهٔ من — ۱۴۰۵</p>
    </footer>
  </body>
</html>

دقت کن که در <head> یک خطِ <link rel="stylesheet" href="styles.css"> هست — همان از فصل ۱. این خط به مرورگر می‌گوید استایل‌ها را از فایلی به‌نامِ styles.css بخوان. حالا کنارِ همین فایل، یک فایلِ خالی به‌نامِ styles.css بساز. فعلاً خالی است، پس صفحه هنوز لخت می‌ماند — و این درست است.

🔧 اگر کار نکرد: بعد از این‌که چند خط CSS نوشتی و هیچ‌کدام اعمال نشد و صفحه کاملاً لخت ماند، اولین چیزی که چک کن، همین href است. اگر اشتباهی href="style.css" نوشته باشی (بدونِ «s») ولی فایلت styles.css باشد، مرورگر دنبالِ فایلی می‌گردد که وجود ندارد، پیدایش نمی‌کند، و هیچ استایلی اعمال نمی‌شود — بدون هیچ پیامِ خطا. اسمِ داخلِ href باید مو‌به‌مو با اسمِ فایل یکی باشد.

۲. یک theme بساز و ستون را وسط بیاور#

اول، مثلِ فصل ۶، فونتِ فارسیِ Vazirmatn را با یک بلوکِ @font-face بالای فایل بار می‌کنیم تا وقتی در font-family صدایش زدیم واقعاً موجود باشد. بعد یک theme تعریف می‌کنیم — همان custom property های فصل ۹ — تا رنگ و اندازه‌ها یک‌جا و هماهنگ باشند. آخر هم به body جان می‌دهیم: فونتِ فارسی، رنگِ متن، پس‌زمینه، و یک نکتهٔ مهم — کلِ محتوا را در یک ستونِ باریکِ وسط‌چین می‌گذاریم تا خطوطِ متن زیادی دراز نشوند و خواندنشان راحت باشد.

@font-face {
  font-family: "Vazirmatn";
  src: url("https://cdn.jsdelivr.net/npm/@fontsource/vazirmatn/files/vazirmatn-arabic-400-normal.woff2") format("woff2");
  font-weight: 400;
}

:root {
  --brand: #5a4bff;
  --ink: #1b2440;
  --muted: #55607a;
  --card-bg: #ffffff;
  --page-bg: #eef1f7;
  --radius: 16px;
  --space: 20px;
  --line: #e4e8f0;
}

body {
  max-width: 640px;
  margin: 0 auto;
  padding: 24px;
  font-family: Vazirmatn, Tahoma, sans-serif;
  color: var(--ink);
  background-color: var(--page-bg);
  line-height: 1.9;
}

آن max-width: 640px به‌همراهِ margin: 0 auto همان ترفندِ وسط‌چینی است که در فصل ۸ دیدی: وقتی یک جعبه عرضِ محدود دارد و margin چپ و راستش auto باشد، مرورگر فضای اضافه را دو طرفش به‌طورِ مساوی پخش می‌کند — یعنی جعبه وسط می‌ایستد. font-family هم Vazirmatn را می‌خواهد که همین بالا با @font-face بارش کردیم؛ اگر به هر دلیل بار نشد، مرورگر سراغِ Tahoma و بعد sans-serif می‌رود.

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

💡 نکته: آن max-width: 640px فقط برای زیبایی نیست. اگر یک متن تا کلِ عرضِ یک صفحهٔ بزرگ کش بیاید، چشم موقعِ برگشتن از آخرِ یک خط به اولِ خطِ بعد، خط را گم می‌کند و خواندن خسته‌کننده می‌شود. یک ستونِ باریک‌تر، خطوطِ کوتاه‌تر و خواناتری می‌سازد — به همین دلیل تقریباً هر سایتِ خوش‌خوانی، متنِ اصلی‌اش را در یک ستونِ محدود نگه می‌دارد، نه تمامِ عرض.

اینجا یک چیزِ مهم را روشن کنم: همهٔ بخش‌ها هنوز زیرِ هم چیده شده‌اند — سرصفحه، بعد محتوا، بعد <aside>، بعد پاصفحه. این «جریانِ عادی» است، همان‌طور که در فصل ۷ دیدی. چیدمانِ واقعی — مثلاً گذاشتنِ ستونِ کناری (<aside>) در کنارِ محتوای اصلی به‌جای زیرِ آن — کارِ ترمِ بعد است، با flexbox و grid. این را در ترم ۳ کامل یاد می‌گیریم. فعلاً همه‌چیز زیرِ هم می‌ماند، و این کاملاً خوب است؛ یک صفحه می‌تواند در جریانِ عادی هم تمیز و خوش‌ظاهر باشد.

۳. بخش‌ها را کارت کن#

حالا سراغِ همان تزئینی می‌رویم که در فصل ۸ ساختی. سه بخشِ صفحه — مطلب، معرفی و لینک‌های مفید — همه کلاسِ card دارند. با یک قاعده، هر سه را به کارت تبدیل می‌کنیم: پس‌زمینهٔ سفید، حاشیهٔ نازک، گوشهٔ گرد و سایهٔ ملایم. همه‌شان از متغیرهای theme تغذیه می‌کنند:

.card {
  margin-bottom: var(--space);
  padding: var(--space);
  background-color: var(--card-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 12px 30px rgb(23 36 64 / 0.10);
}

.card h2 {
  margin: 0 0 10px;
  color: var(--ink);
}

.card p {
  margin: 0 0 10px;
  color: var(--muted);
}

.more {
  color: var(--brand);
  font-weight: 700;
}

چک کن: حالا هر سه بخش مثلِ کارت‌های سفیدِ گوشه‌گرد روی پس‌زمینهٔ خاکستری نشسته‌اند، با یک سایهٔ نرم که کمی از صفحه بلندشان کرده و یک فاصلهٔ منظم بینشان. لینکِ «ادامهٔ مطلب» هم به رنگِ اصلیِ theme درآمده. همان --space و --radius که یک‌بار بالای فایل تعریف کردی، حالا فاصله و گوشهٔ هر سه کارت را با هم کنترل می‌کنند.

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

۴. سرصفحه و منو#

سرصفحه دو چیز دارد: عنوانِ سایت و منو. عنوان را به رنگِ اصلیِ theme درمی‌آوریم. منو یک <ul> است؛ می‌خواهیم لینک‌هایش به‌جای این‌که زیرِ هم و با نقطهٔ فهرست بیایند، کنارِ هم و مثلِ دکمه‌های قرصی‌شکل باشند. برای این کار، از display: inline-block فصل ۷ استفاده می‌کنیم:

.site-header h1 {
  margin: 0 0 12px;
  color: var(--brand);
}

.menu {
  margin: 0 0 8px;
  padding: 0;
}

.menu li {
  display: inline-block;
  margin-left: 10px;
}

.menu a {
  display: inline-block;
  padding: 6px 14px;
  background-color: var(--card-bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink);
  font-weight: 700;
}

وقتی هر <li> را inline-block می‌کنی، دو اتفاق با هم می‌افتد: اول، لینک‌ها به‌جای زیرِ هم، کنارِ هم در یک ردیف می‌آیند (چون دیگر بلوک نیستند که کلِ عرض را بگیرند). دوم، نقطهٔ فهرست هم خودبه‌خود ناپدید می‌شود — چون نقطه فقط روی عنصری می‌آید که «آیتمِ فهرست» باشد، و ما آن را inline-block کرده‌ایم. border-radius: 999px هم یک عددِ خیلی بزرگ است که لینک را کاملاً قرصی‌شکل می‌کند.

چک کن: بالای صفحه، عنوانِ «وبلاگ من» به رنگِ اصلی درآمده و زیرش دو لینکِ قرصی‌شکل کنارِ هم نشسته‌اند، بدون هیچ نقطهٔ فهرستی. حالا خرابش کن: display: inline-block را از .menu li بردار و ببین لینک‌ها دوباره زیرِ هم می‌روند و نقطهٔ فهرست برمی‌گردد. حالا فهمیدی این یک خط دقیقاً چه کاری می‌کند. برگردانش.

۵. پاصفحه و صفحهٔ کامل#

آخرین تکه، پاصفحه است: یک متنِ کم‌رنگ و وسط‌چین. text-align: center را از فصل ۶ یادت هست:

.site-footer {
  margin-top: 8px;
  color: var(--muted);
  text-align: center;
}

و حالا فایلِ styles.css کامل، از اول تا آخر — همهٔ تکه‌هایی که ساختیم، پشتِ هم:

/* styles.css */
@font-face {
  font-family: "Vazirmatn";
  src: url("https://cdn.jsdelivr.net/npm/@fontsource/vazirmatn/files/vazirmatn-arabic-400-normal.woff2") format("woff2");
  font-weight: 400;
}

:root {
  --brand: #5a4bff;
  --ink: #1b2440;
  --muted: #55607a;
  --card-bg: #ffffff;
  --page-bg: #eef1f7;
  --radius: 16px;
  --space: 20px;
  --line: #e4e8f0;
}

body {
  max-width: 640px;
  margin: 0 auto;
  padding: 24px;
  font-family: Vazirmatn, Tahoma, sans-serif;
  color: var(--ink);
  background-color: var(--page-bg);
  line-height: 1.9;
}

.site-header h1 {
  margin: 0 0 12px;
  color: var(--brand);
}

.menu {
  margin: 0 0 8px;
  padding: 0;
}

.menu li {
  display: inline-block;
  margin-left: 10px;
}

.menu a {
  display: inline-block;
  padding: 6px 14px;
  background-color: var(--card-bg);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--ink);
  font-weight: 700;
}

.card {
  margin-bottom: var(--space);
  padding: var(--space);
  background-color: var(--card-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 12px 30px rgb(23 36 64 / 0.10);
}

.card h2 {
  margin: 0 0 10px;
  color: var(--ink);
}

.card p {
  margin: 0 0 10px;
  color: var(--muted);
}

.more {
  color: var(--brand);
  font-weight: 700;
}

.site-footer {
  margin-top: 8px;
  color: var(--muted);
  text-align: center;
}

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

مقایسهٔ همان صفحه در دو حالت: سمتِ راست نسخهٔ لختِ ترم ۱ (فقط متنِ سیاه روی سفید)، سمتِ چپ همان صفحه بعد از CSS با کارت‌های رنگی و منوی قرصی‌شکل

🤖 با AI: صفحهٔ نهایی‌ات را به دستیار AI ات بده و بپرس: «رنگِ متنِ کم‌رنگ (--muted) روی پس‌زمینهٔ سفیدِ کارت، از نظرِ خوانایی و contrast به‌اندازهٔ کافی تیره هست؟». این یک کاربردِ خوبِ AI است — بازبینیِ کدِ خودت بعد از نوشتنش. ولی هر پیشنهادی داد، با چیزی که در آزمایشگاه می‌بینی چک کن: رنگ را عوض کن و با چشمِ خودت ببین خوانا‌تر شد یا نه. دسترس‌پذیری را در ترمِ حرفه‌ای‌شدن عمیق‌تر می‌بینیم.

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

این فصل یک فصلِ پروژه‌ای است و واژهٔ فنیِ تازه‌ای ندارد؛ فقط مفاهیمِ ترمِ ۲ — theme و custom property، تزئین، فونتِ فارسی، جریانِ عادی و وسط‌چینیِ افقی — را کنارِ هم به‌کار می‌گیرد.

تمرین‌ها

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

در فصل بعد#

اینجا آخرِ ترمِ CSS است. حالا رنگ، فونت، جعبه، فاصله و تزئین را کنترل می‌کنی، cascade را می‌فهمی نه حدس می‌زنی، با DevTools اشکال پیدا می‌کنی، و یک theme منظم می‌سازی. ولی یک چیزِ بزرگ هنوز جا مانده: چیدمان. تا اینجا هر چیزی زیرِ هم بوده. در ترمِ بعد — Layout — یاد می‌گیری چیزها را کنارِ هم بگذاری، ستون بسازی، و صفحه را واقعاً بچینی، با دو ابزارِ اصلیِ CSSِ امروز: flexbox و grid. همان <aside> که این فصل زیرِ محتوا ماند، آنجا می‌رود کنارش، درست جایی که باید باشد.

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

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