مقدمه

اولین موضوعی که در ارتباط با طرح‌بندی (layout) صفحات وب بررسی می‌کنیم، تعیین موقعیت مکانی عناصر در صفحه و به عبارت بهتر، تغییر مکان پیش‌فرض عناصر است. برای این منظور، در اولین گام باید با مفهومی به نام Normal Flow آشنا شویم که به طور خلاصه به طرح‌بندی پیش‌فرض یک صفحه‌ی وب گفته می‌شود که از روی استایل‌شیت داخلی مرورگرها تعیین می‌شود. بعد از آن، با پراپرتی position‌ آشنا می‌شویم که موقعیت مکانی عناصر در صفحه را مشخص می‌کند. چهار پراپرتی top، right، bottom و left به همراه پراپرتی position مکان یک عنصر در صفحه را تعیین می‌کنند.

Normal Flow چیست؟

به طور کلی، پراپرتی‌های CSS را می‌توان در دو گروه قرار داد:

  • پراپرتی‌های مربوط به presentation که به ظاهر عنصر (بدون در نظر گرفتن آن عنصر به عنوان بخشی از یک صفحه و یا ارتباط آن با سایر عناصر) مربوط می‌شوند. برای مثال، پراپرتی‌هایی مانند color و font-size در این گروه قرار می‌گیرند.
  • پراپرتی‌های مربوط به layout که به طرح‌بندی صفحه مربوط می‌شوند و شامل پراپرتی‌هایی مانند display و position می‌شود.

مقادیر پیش‌فرضی که مرورگرها به پراپرتی‌های مربوط به layout اختصاص می‌دهند، روال یا جریانی را برای سند به وجود می‌آورند که از ان با نام Normal Flow یا جریان عادی سند یاد می‌شود. یادآوری می‌کنم که کار ما در CSS تعریف یا خلق استایل نیست، بلکه تغییر استایل‌های پیش‌فرض (با طی یک روند سلسله‌مراتبی) است. با این حساب، اگر بخواهیم دقیق باشیم، باید به جای عبارت «تعیین مکان» از «تغییر مکان» استفاده کنیم و نتیجتاً بخش عمده‌ای از کار ما در این فصل به معرفی روش‌ها و تکنیک‌های تغییر layout پیش‌فرض یا همان normal flow اختصاص دارد. این کار را با معرفی روش‌های تغییر موقعیت مکانی پیش‌فرض عناصر شروع می‌کنیم که توسط یک پراپرتی با نام position انجام می‌شود.

تعیین مکان عناصر با پراپرتی position

پراپرتی position تعیین‌کننده‌ی روش تعیین مکان عناصر در صفحه است. با استفاده از این پراپرتی و 4 + 1 پراپرتی top، right، bottom، left و z-index می‌توانیم مکان یک عنصر را تعیین کنیم. مقداری که پراپرتی position دریافت می‌کند، روش تعیین مکان عنصر یا عناصر انتخابی را مشخص می‌کند و سپس، مقادیر تخصیص داده شده به ۵ پراپرتی مذکور، مکان عنصر را مشخص می‌کند.

پراپرتی position می‌تواند یکی از مقادیر زیر را دریافت کند:

  • static: این مقدار که به طور پیش‌فرض برای پراپرتی position در نظر گرفته شده، به این معناست که عنصر مورد نظر در موقعیت نرمال خود در صفحه ظاهر می‌شود و پراپرتی‌های top، right، bottom، left و z-index تأثیری روی مکان عنصر ندارند.
  • relative: اگر مقدار پراپرتی position را برای یک عنصر برابر با relative قرار دهیم، محل قرارگیری عنصر نسبت به محل نرمال آن سنجیده می‌شود و لذا با استفاده از پراپرتی‌های top، right، bottom و left می‌توانیم میزان جابجایی عنصر نسبت به وضعیت نرمال خود را از جهات مختلف تعیین کنیم. در این روش، عنصر مورد نظر همچنان بخشی از جریان نرمال سند باقی می‌ماند و بنابراین، فضای اصلی مربوط به عنصر حفظ می‌شود.
  • absolute: اگر از مقدار absolute برای پراپرتی position یک عنصر استفاده کنیم، محل قرارگیری عنصر نسبت به اولین عنصر والد آن که مقداری غیر از static را برای پراپرتی position تعیین کرده، سنجیده می‌شود و لذا پراپرتی‌های top، right، bottom و left تعیین‌کننده‌ی فاصله‌ی عنصر نسبت به آن عنصر والد است. در این روش، عنصر مورد نظر دیگر بخشی از جریان عادی سند نیست و به یک لایه بالاتر منتقل می‌شود. بنابراین، این عنصر روی سایر عناصر قرار می‌گیرد.
  • fixed: مقدار fixed برای پراپرتی position باعث می‌شود عنصر از جریان نرمال سند خارج شده و موقعیتش نسبت به viewport سنجیده شود. عنصری که با استفاده از این روش تعیین موقعیت شود، با اسکرول صفحه حرکت نمی‌کند و ثابت می‌ماند.
  • sticky: ترکیبی از دو مقدار relative و fixed است. عنصر تا زمانی که به مقدار تعریف‌شده از پراپرتی های top، right، bottom و left برسد، به صورت relative و از آن به بعد به صورت fixed رفتار می‌کند.

پراپرتی‌های top، right، bottom و left نیز محل قرارگیری عنصر در چهار جهت مختلف را تعیین می‌کنند. عملکرد این پراپرتی‌ها به مقدار پراپرتی position بستگی دارد اما مقداری که دریافت می‌کنند، یک مقدار طولی یا درصدی است.

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

با توجه به مطالب گفته شده، باید روش تعیین مکان یک عنصر برایتان روشن شده باشد:

ابتدا روش مورد نظرمان برای تعیین مکان عنصر را با تخصیص مقدار مناسب به پراپرتی position تعیین می‌کنیم و سپس با مقداردهی پراپرتی‌های top، right، bottom، left و z-index مکان عنصر را تعیین می‌کنیم. در ادامه، مثال‌هایی از هر یک از روش‌های تعیین مکان عناصر ارائه می‌شود.

تعیین مکان عناصر به روش static

همانطور که گفته شد، static مقدار پیش‌فرض پراپرتی position است و حاکی از موقعیت نرمال عناصر در صفحه است. تا زمانی که این مقدار پیش‌فرض پراپرتی position را تغییر ندهیم، استفاده از پراپرتی‌های top، right، bottom و left هیچ نتیجه‌ای نخواهد داشت. مثال زیر را ببینید.

 Copy Icon CSS
h2{
  top: 100px;
  left: 200px;
}

تعیین مکان عناصر به روش relative

عنصری که مقدار relative را برای پراپرتی position تعیین کرده، مکانش با استفاده از یک رویکرد نسبی تعیین می‌شود. به این صورت که پراپرتی‌های top، right، bottom و left عنصر را از چهار جهت نسبت به وضعیت نرمالی که دارد، فاصله می‌دهند. بدیهی است که اگر مقدار پراپرتی position را روی relative تنظیم کنیم اما از این چهار پراپرتی استفاده نکنیم، تغییری در مکان عنصر ایجاد نمی‌شود.

 Copy Icon CSS
h2{
  position: relative;
  top: 100px;
  left: 200px;
}

همانطور که با اجرای مثال بالا دیدید، در اینجا عنصر نسبت به وضعیت نرمال خود، به اندازه‌ی 100px از بالا و 200px از چپ فاصله می‌گیرد. در ضمن، از آنجایی که مقدار relative عنصر را از جریان نرمال خارج نمی‌کند، فضای اصلی مربوط به عنصر h2 حفظ می‌شود.

اگر هر دو پراپرتی top و bottom را مقداردهی کنیم، فقط پراپرتی top در نظر گرفته می‌شود و bottom نادیده گرفته می‌شود. در مورد مقداردهی همزمان پراپرتی‌های left و right هم اگر جهت متن چپ‌به‌راست (ltr) باشد، پراپرتی left اعمال می‌شود و اگر جهت متن راست‌به‌چپ باشد، مقدار پراپرتی right اعمال می‌شود.

تعیین مکان عناصر به روش absolute

مقدار absolute هم مانند مقدار relative باعث می‌شود که مکان عنصر با استفاده از پراپرتی‌های top، right، bottom و left تغییر کند اما با دو تفاوت:

اول اینکه مقدار absolute باعث می‌شود که عنصر مورد نظر از جریان عادی سند حذف شده و روی آن شناور شود. بنابراین، تغییر مکان سایر عناصر در صفحه به‌گونه‌ای است که انگار این عنصر اصلاً وجود ندارد.

تفاوت دوم در نحوه‌ی تفسیر فاصله‌هایی است که با استفاده از پراپرتی‌های top، right، bottom و left تعیین می‌شود. این فاصله‌ها نسبت به اولین عنصر والد positioned سنجیده می‌شوند؛ یعنی اولین عنصر والدی که مقداری غیر از fixed را برای پراپرتی position تعیین کرده است. مثال زیر را ببینید.

 Copy Icon CSS
.outer{
  background-color: red;
  height: 10rem;
  width: 10rem;
}

.inner{
  background-color: blue;
  height: 7rem;
  width: 7rem;
}

.core{
  background-color: green;
  position: absolute;
  right: 0;
  height: 4rem;
  width: 4rem;
}

با اجرای مثال بالا خواهید دید که باکس سبز رنگ به لبه‌ی راست viewport چسبیده است. علت این امر آن است که این عنصر هیچ والدی ندارد که positioned باشد و بنابراین، مقدار پراپرتی right و به‌طور کلی، تعیین فاصله برای این عنصر نسبت به خود سند انجام می‌شود. حالا اجازه دهید مقدار relative را به پراپرتی position مربوط به باکس دیگر اختصاص دهیم و ببینیم چه تغییری رخ می‌دهد:

 Copy Icon CSS
.outer{
  background-color: red;
  height: 10rem;
  width: 10rem;
  position: relative;
}

.inner{
  background-color: blue;
  height: 7rem;
  width: 7rem;
}

.core{
  background-color: green;
  position: absolute;
  right: 0;
  height: 4rem;
  width: 4rem;
}

این بار باکس سبز رنگ نسبت به باکس قرمز رنگ مکان‌دهی می‌شود که اولین والد positioned برای باکس سبز است. حالا اجازه دهید باکس آبی را به صورت relative تعیین کنیم:

 Copy Icon CSS
.outer{
  background-color: red;
  height: 10rem;
  width: 10rem;
  position: relative;
}

.inner{
  background-color: blue;
  height: 7rem;
  width: 7rem;
  position: relative;
}

.core{
  background-color: green;
  position: absolute;
  right: 0;
  height: 4rem;
  width: 4rem;
}

حالا این باکس آبی است که نزدیکترین والد positioned برای باکس سبز است و بنابراین، باکس سبز نسبت به باکس آبی مکان‌دهی می‌شود.

تعیین مکان عناصر به روش fixed

روش fixed نیز مانند روش absolute باعث حذف عنصر از جریان نرمال می‌شود اما با این تفاوت که در مورد روش fixed، مکان عنصر همیشه نسبت به viewport تعیین می‌شود. این یعنی اینکه حتی در صورت اسکرول صفحه هم مکان عنصر ثابت می‌ماند. این روش برای مواردی مثل ایجاد navigation bar یا یک هدر ثابت مفید است.

یک عنصر block که به صورت static یا relative تعیین مکان شده باشد، به طور پیش‌فرض، کل عرض کانتینرش را اشغال می‌کند. با این حال، عنصری که با استفاده از روش absolute یا fixed تعیین مکان شده باشد، اینطور نیست. چنین عنصری فقط به اندازه‌ی مورد نیاز عرض دارد. اگر بخواهیم این رویه را تغییر دهیم، کافیست از پراپرتی width با مقدار 100%‌ استفاده کنیم.

 Copy Icon CSS
nav{
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  padding: 1em;
  background-color: yellow;
}

تعیین مکان عناصر به روش sticky

روش sticky برای تعیین مکان عناصر، ترکیبی است از روش‌های relative و fixed. به این ترتیب که عنصر مورد نظر مثل یک عنصر relative همراه با سند اسکرول می‌شود و وقتی سند به نقطه‌ی معینی برسد، مثل یک عنصر fixed عمل می‌کند. تعیین نقطه‌ی تغییر توسط پراپرتی‌های top، right، bottom و left انجام می‌شود.

پراپرتی z-index

وقتی مکان عناصر را با استفاده از یکی از روش‌های absolute، fixed یا sticky تعیین کنیم، امکان تداخل (overlap)‌ آنها با هم وجود دارد. پراپرتی z-index تعیین می‌کند که عنصر در راستای محور Z نسبت به سایر عناصر در چه سطحی قرار گیرد. مقدار این پراپرتی یک عدد صحیح است که بیانگر اولویت قرارگیری عنصر است و اعداد بزرگتر به معنای اولویت بالاتر است. این پراپرتی می‌تواند مقادیر عددی مثبت یا منفی را دریافت کند. در واقع، مقداری که پراپرتی z-index دریافت می‌کند یک مقدار نسبی است که اولویت قرارگیری عنصر در راستای محور Z را تعیین می‌کند.

 Copy Icon CSS
.box1{
  position: absolute;
  width: 200px;
  height: 200px;
  background-color: red;
  top: 50px;
  left: 50px;
  z-index: 1;
}

.box2{
  position: absolute;
  width: 200px;
  height: 200px;
  background-color: blue;
  top: 100px;
  left: 100px;
  z-index: 2;
}