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

فصل ۱ از ۱۱

پیشرفت ترم
۰٪

ترم ۳ · Layout: چیدمان

چیدمان: از جریان عادی شروع کن

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

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

تا اینجای دوره هر چیزی که ساختی را خودِ مرورگر چیده است — تیترها زیر هم، پاراگراف‌ها پشت سرِ هم، تصویرها سرِ جایشان. به این چیدنِ خودکار می‌گویند جریان عادی (normal flow)، و نقطهٔ شروعِ هر layout همین است. در این فصل اول می‌بینی این جریان دقیقاً چطور کار می‌کند و چرا جعبه‌ها زیرِ هم می‌افتند نه کنارِ هم. بعد عمداً به یک دیوار می‌خوریم: می‌خواهیم دو جعبه کنارِ هم بنشینند و با هر چیزی که تا حالا بلدی، نمی‌شود. همین دیوار در است به flexbox — ابزارِ اصلیِ این ترم که از فصل بعد شروع می‌شود. بزن بریم.

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

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

  • بگویی جریان عادی چیست و چرا جعبه‌های block زیرِ هم می‌چینند نه کنارِ هم
  • توضیح بدهی چرا در یک صفحهٔ RTL محتوای inline از سمتِ راست شروع می‌شود
  • خطای «دو جعبه که کنارِ هم نمی‌روند» را ببینی و بفهمی چرا با ابزارِ فعلی حل نمی‌شود
  • بگویی چرا float دیگر ابزارِ چیدمان نیست و امروز فقط برای پیچیدنِ متن دورِ تصویر به‌کار می‌رود

قبل از شروع#

  • از ترم ۲ فصل ۷: display: block و inline و inline-block — قلبِ این فصل دقیقاً همان تفاوتِ block و inline است.
  • از ترم ۲ فصل ۴: box model و box-sizing: border-box — هر چیزی که می‌چینیم یک جعبه است.
  • از ترم ۲ فصل ۷: direction و RTL — اینجا می‌بینی جریان چطور با جهتِ صفحه عوض می‌شود.

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

۱. جریان عادی: کاری که مرورگر خودش می‌کند#

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

قاعده دو حالت دارد که هر دو را در ترم ۲ دیدی:

  • عنصرهای block (مثل <section>، <p>، <h1>) هرکدام یک خطِ کامل را برای خودشان می‌گیرند و از بالا به پایین روی هم می‌چینند. هرچقدر هم باریک باشند، عنصرِ بعدی می‌رود خطِ بعد.
  • عنصرهای inline (مثل <a>، <strong>، <em>) در امتدادِ همان خط، پشتِ سرِ هم می‌آیند و تا آخرِ خط پُر که شد، تازه می‌روند خطِ بعد — مثلِ کلمه‌ها در یک پاراگراف.

بیا این را با چشم ببینیم. در آزمایشگاه یک سرصفحه و دو جعبه و یک پاصفحه بساز:

<header class="bar">تارنمای من</header>

<section class="box">محتوای اصلی</section>
<aside class="box">نوار کناری</aside>

<footer class="bar">پاصفحه</footer>

و یک CSS ساده که فقط رنگ و فاصله می‌دهد تا جعبه‌ها پیدا باشند:

.bar {
  padding: 16px;
  background-color: #2a6b93;
  color: #ffffff;
  text-align: center;
}

.box {
  padding: 24px;
  margin: 12px 0;
  background-color: #ffffff;
  border: 2px solid #2a6b93;
}

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

۲. همین جریان، در یک صفحهٔ RTL#

صفحهٔ ما dir="rtl" است. این روی جریان اثر می‌گذارد، ولی فقط روی یک محور. حواست به این تفاوت باشد، چون تا آخرِ ترم همراهت است:

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

این را ببین: به .box یک خط اضافه کن که چند تکهٔ inline کنارِ هم بگذارد.

<section class="box">
  <strong>اول</strong> <em>دوم</em> <a href="#">سوم</a>
</section>

چک کن: «اول»، «دوم» و «سوم» در امتدادِ یک خط پشتِ سرِ هم آمده‌اند و چون صفحه RTL است، «اول» سمتِ راست است و بقیه به چپ می‌روند. همین «راست به چپ»ِ محورِ inline، در فصل بعد وقتی سراغِ flexbox برویم دوباره برمی‌گردد — پس همین‌جا جا بیندازش.

💡 نکته: جریان عادی یک بدهیِ پنهان ندارد؛ همیشه پشتِ صحنه روشن است. هر ابزارِ چیدمانی که در این ترم یاد می‌گیری — flexbox، grid، position — در واقع دارد به مرورگر می‌گوید «از جریانِ عادی برای این عنصر خارج شو و به‌جایش این‌طور بچین». برای همین جریانِ عادی نقطهٔ شروع است، نه یک درسِ فرعی.

۳. حالا دو جعبه را کنارِ هم بگذار (اینجا به دیوار می‌خوریم)#

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

.box {
  width: 40%;
  padding: 24px;
  margin: 12px 0;
  background-color: #ffffff;
  border: 2px solid #2a6b93;
}

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

🔧 اگر کار نکرد: بله، این عمدی است و باید همین را ببینی. مشکل از عرض نیست؛ مشکل ذاتِ block است. یک عنصرِ block هرچقدر هم باریکش کنی، باز هم کلِ خط را برای خودش قُرق می‌کند و عنصرِ بعدی را به خطِ بعد می‌فرستد. عرضِ ۴۰٪ فقط خودِ جعبه را باریک کرد، ولی آن خطِ خالیِ کنارش هنوز مالِ همان جعبه است. پس عنصرِ block را نمی‌شود فقط با کم‌کردنِ عرض کنارِ هم نشاند.

شاید یادت بیفتد که در ترم ۲ یک چاره داشتیم: display: inline-block. آن واقعاً جعبه‌ها را کنارِ هم می‌آورد و می‌ارزد یک‌بار امتحانش کنی. ولی برای چیدمانِ واقعی زود به دردسر می‌افتد: یک فاصلهٔ اسرارآمیز از فضای خالیِ بینِ tag ها بینشان می‌افتد، ته‌شان روی یک خطِ نامرئی می‌چسبد نه بالاشان، و هم‌قدکردنِ دو ستون کارِ سختی می‌شود. این‌ها هک‌های ریز می‌خواهند، و ما در تاروپود هک نمی‌نویسیم.

پس فعلاً همین‌طور بگذارشان زیرِ هم و آن width را بردار؛ فصل بعد با flexbox این را در یک خط و تمیز حل می‌کنیم — دقیقاً همین مسئلهٔ «کنارِ هم» چیزی است که flexbox برایش ساخته شده.

چک کن: بعد از برداشتنِ width، دوباره دو جعبهٔ تمام‌عرض داری که زیرِ هم‌اند. این حالتِ سالمِ صفحه است تا فصل بعد. مهم این است که حالا می‌دانی چرا کنارِ هم نرفتند — نه اینکه فقط دیدی نرفتند.

۴. یک جملهٔ تاریخی دربارهٔ float#

شاید جایی به کلمهٔ float بربخوری و فکر کنی راهِ چیدمان همان است. یک جملهٔ تاریخی: سال‌ها پیش که هنوز flexbox و grid نبودند، برنامه‌نویس‌ها کلِ چیدمانِ صفحه را با float می‌ساختند — ابزاری که در اصل برای پیچیدنِ متن دورِ یک تصویر ساخته شده بود، نه برای چیدمان — و این یک هکِ شکننده و پُردردسر بود که امروز دیگر برای layout استفاده نمی‌شود.

تنها کاربردِ درستِ امروزیِ float همان کارِ اصلی‌اش است: وادارکردنِ متن به پیچیدن دورِ یک عنصر. این را ببین — یک جعبهٔ کوچک بساز و متنی کنارش که دورش بپیچد:

<div class="thumb"></div>
<p>این پاراگراف آن‌قدر بلند است که دورِ آن جعبهٔ کوچک بپیچد و کنارش جا بگیرد، و وقتی به پایینِ جعبه رسید، دوباره تمامِ عرض را می‌گیرد. متن ادامه دارد و ادامه دارد تا این رفتار خوب دیده شود.</p>
.thumb {
  float: right;
  width: 80px;
  height: 80px;
  margin-left: 16px;
  background-color: #bc3e1c;
}

چک کن: جعبهٔ نارنجی سمتِ راست نشسته و متن دورِ گوشهٔ چپش پیچیده و کنارش جا گرفته. چون صفحه RTL است float: right یعنی «به سمتِ شروع»، و متن از سمتِ چپِ جعبه سرازیر می‌شود. این تنها جایی است که float هنوز درست است.

💡 نکته: گاهی وقتی چیزی را float می‌کنی، جعبهٔ والدش «جمع» می‌شود و انگار ارتفاعش را از دست می‌دهد. پاسخِ امروزیِ این مشکل یک خط است: به جعبهٔ والد display: flow-root بده. روش‌های قدیمی‌تر را کلاً فراموش کن؛ flow-root تمیزترین و تنها راهی است که باید بلد باشی.

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

این هم دو فایلِ کاملِ این فصل، یک‌جا — همان صفحهٔ جریانِ عادی که با آن شروع کردیم. اول index.html:

<!-- 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="bar">تارنمای من</header>

    <section class="box">محتوای اصلی</section>
    <aside class="box">نوار کناری</aside>

    <footer class="bar">پاصفحه</footer>
  </body>
</html>

و styles.css:

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

body {
  margin: 0;
  padding: 16px;
  background-color: #f6edda;
  font-family: system-ui, sans-serif;
}

.bar {
  padding: 16px;
  background-color: #2a6b93;
  color: #ffffff;
  text-align: center;
}

.box {
  padding: 24px;
  margin: 12px 0;
  background-color: #ffffff;
  border: 2px solid #2a6b93;
}

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

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

کلمه تلفظ به حروف فارسی یعنی چه
normal flow نُرمال فلو چیدنِ پیش‌فرضِ مرورگر: block روی هم، inline در امتدادِ خط
layout لِی‌اوت چیدمانِ عنصرها روی صفحه؛ موضوعِ کلِ این ترم
block بلاک عنصری که کلِ خط را می‌گیرد و زیرِ هم می‌چیند
inline این‌لاین عنصری که در امتدادِ خط، پشتِ سرِ هم می‌آید
float فلوت ابزارِ قدیمیِ چیدمان؛ امروز فقط برای پیچیدنِ متن دورِ تصویر
flow-root فلو-روت مقدارِ display که جعبهٔ float-دار را دوباره جمع‌وجور می‌کند

تمرین‌ها

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

در فصل بعد#

الان می‌دانی جریانِ عادی چیست و چرا جعبه‌های block کنارِ هم نمی‌روند. این فصل یک بدهی گذاشت: «دو جعبه را کنارِ هم بنشان». فصل بعد این بدهی را کامل می‌پردازد. با یک خط — display: flex روی جعبهٔ والد — جعبه‌ها در یک ردیف کنارِ هم می‌نشینند، و تازه آنجا با main axis و cross axis و flex-direction و gap آشنا می‌شویم؛ یعنی همان محورِ راست‌به‌چپی که همین‌جا در RTL دیدی، دوباره سروکله‌اش پیدا می‌شود.

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

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