بستن

آموزش کامل position در CSS

position در CSS شامل Static، Relative، Absolute، Fixed و Sticky

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

🎯 اهداف یادگیری این جلسه

  • فرق دقیق پنج مقدار position (static, relative, absolute, fixed, sticky) رو بفهمی
  • یاد بگیری «Containing Block» دقیقاً چیه و چرا تعیین‌کننده‌ست
  • با top, right, bottom, left و inset کار کنی
  • مفهوم z-index و Stacking Context رو کامل درک کنی
  • یه مرجع جامع از رفتار هر مقدار position داشته باشی

📍 position در CSS دقیقاً چیه؟

ویژگی position مشخص می‌کنه یه عنصر چطور تو صفحه جای‌گذاری بشه — تو جریان عادی صفحه (Normal Flow) بمونه، یا نسبت به یه نقطه‌ی خاص جابه‌جا بشه. وقتی position رو رو یه مقدار غیر از static بذاری، می‌تونی با چهار ویژگی top، right، bottom و left دقیقاً بگی عنصر چقدر از هر لبه فاصله داشته باشه.

1️⃣ static — مقدار پیش‌فرض

.box {
  position: static;
}

این مقدار پیش‌فرض همه‌ی عناصره. عنصر دقیقاً تو همون جایی قرار می‌گیره که جریان عادی HTML می‌گه — بدون هیچ جابه‌جایی. ویژگی‌های top, right, bottom, left رو این مقدار کاملاً نادیده می‌گیره.

2️⃣ relative — جابه‌جایی نسبت به جای اصلی خودش

.box {
  position: relative;
  top: 20px;
  left: 10px;
}

عنصر اول تو جریان عادی جاش رو می‌گیره (دقیقاً مثل static)، ولی بعد نسبت به همون جای اصلی‌اش جابه‌جا می‌شه. نکته‌ی مهم: جای خالی اصلی عنصر همچنان تو صفحه محفوظ می‌مونه — یعنی عناصر اطرافش طوری رفتار می‌کنن که انگار عنصر هنوز همون‌جاست، حتی اگه بصری جابه‌جا شده باشه.

مهم‌ترین کاربرد relative: اغلب خودش تنها برای جابه‌جایی استفاده نمی‌شه، بلکه برای این استفاده می‌شه که یه Containing Block برای فرزندهای absolute بسازه (پایین‌تر کامل توضیح می‌دیم).

3️⃣ absolute — خارج کامل از جریان عادی

.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 0;
  right: 0;
}
<div class="parent">
  <div class="child">گوشه بالا-راست</div>
</div>

عنصر absolute کاملاً از جریان عادی صفحه خارج می‌شه — جای خالی‌ای هم پشت سرش نمی‌ذاره (انگار برای بقیه‌ی عناصر اصلاً وجود نداره) و نسبت به نزدیک‌ترین جد (Ancestor) که positionش چیزی غیر از static باشه، قرار می‌گیره.

⚠️ نکته‌ی حیاتی که اکثر مبتدی‌ها گیرش می‌افتن: اگه هیچ‌کدوم از جدهای یه عنصر absolute، position غیر-static نداشته باشن، اون عنصر نسبت به کل صفحه (<html>) قرار می‌گیره — که معمولاً نتیجه‌ای کاملاً غیرمنتظره می‌ده. برای همینه که تقریباً همیشه باید رو والد مستقیم، position: relative بذاری تا یه «لنگرگاه» درست براش بسازی.

4️⃣ fixed — چسبیده به viewport

.back-to-top {
  position: fixed;
  bottom: 20px;
  right: 20px;
}

شبیه absoluteه (از جریان عادی خارج می‌شه)، ولی به‌جای نسبت به یه جد، نسبت به خود Viewport (پنجره‌ی قابل دیدِ مرورگر) قرار می‌گیره و حتی با اسکرول کردن صفحه هم ثابت می‌مونه.

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

⚠️ نکته‌ی پیشرفته: اگه یکی از جدهای عنصر fixed، ویژگی transform، filter یا will-change داشته باشه، رفتار fixed می‌شکنه و عنصر به‌جای viewport، نسبت به همون جد قرار می‌گیره — یکی از عجیب‌ترین باگ‌های CSS که خیلی وقت‌ها ساعت‌ها وقت می‌گیره تا پیدا بشه!

5️⃣ sticky — ترکیب هوشمند relative و fixed

.section-header {
  position: sticky;
  top: 0;
}

این مدرن‌ترین و هوشمندترین مقدار position‌ه: عنصر مثل relative رفتار می‌کنه (تو جریان عادی می‌مونه) تا وقتی که موقع اسکرول به نقطه‌ای که تعیین کردی (مثلاً top: 0) برسه — از اون لحظه به بعد، مثل fixed می‌چسبه و ثابت می‌مونه، ولی فقط تا وقتی که والدش تو دید باشه.

کاربرد کلاسیک: عنوان بخش‌های یه لیست بلند (مثل حروف الفبا تو لیست مخاطبین) یا هدر یه جدول که موقع اسکرول همیشه بالا بمونه.

⚠️ نکته‌ی رایج که باعث نکار کردن sticky می‌شه: اگه والد عنصر overflow: hidden یا overflow: auto داشته باشه، رفتار sticky ممکنه اصلاً کار نکنه؛ چون مرورگر نمی‌تونه به‌درستی محدوده‌ی «چسبندگی» رو تشخیص بده.

📊 جدول جامع مقایسه تمام مقادیر position

مقدارتو جریان عادی می‌مونه؟نسبت به چی قرار می‌گیره؟جای خالی می‌ذاره؟
static✅ بله✅ بله (طبیعی)
relative✅ بلهجای اصلی خودش✅ بله
absolute❌ خیرنزدیک‌ترین جد غیر-static❌ خیر
fixed❌ خیرViewport❌ خیر
sticky⚠️ نیمه (بسته به اسکرول)ترکیب والد + viewport✅ بله

🧭 inset — میان‌بر مدرن برای top/right/bottom/left

.overlay {
  position: absolute;
  inset: 0;
}

این معادل کوتاه‌تریه برای نوشتن هر چهارتای top: 0; right: 0; bottom: 0; left: 0; با هم. دقیقاً مثل سینتکس margin، می‌تونی ۱ تا ۴ مقدار بهش بدی: inset: 10px 20px; یعنی بالا/پایین ۱۰px و چپ/راست ۲۰px.

🗂️ z-index و Stacking Context — کدوم عنصر روی کدوم قرار می‌گیره؟

وقتی چند عنصر positioned (یعنی position‌شون غیر از static باشه) روی هم قرار می‌گیرن، z-index تعیین می‌کنه کدوم بالاتر (نزدیک‌تر به چشم کاربر) نمایش داده بشه:

.modal {
  position: fixed;
  z-index: 100;
}

.overlay-background {
  position: fixed;
  z-index: 50;
}

هرچی عدد z-index بزرگ‌تر باشه، عنصر بالاتر (جلوتر) قرار می‌گیره. نکات مهم:

  • z-index فقط رو عناصری اثر می‌ذاره که positionشون static نباشه
  • می‌تونه مقدار منفی هم بگیره (برای بردن یه عنصر به پشت بقیه)
  • مقایسه‌ی z-index فقط بین عناصری معناداره که تو یه Stacking Context مشترک باشن

Stacking Context چیه؟ این یه مفهوم پیشرفته‌ست: بعضی ویژگی‌ها (مثل position همراه با z-index، یا opacity کمتر از ۱، یا transform) باعث می‌شن یه عنصر و همه‌ی فرزندانش یه «زمینه‌ی چیدمانی جدید» بسازن. نتیجه‌ی عملیش اینه: اگه یه فرزند z-index: 9999 داشته باشه ولی والدش تو یه Stacking Context با z-index کمتر گیر افتاده باشه، اون فرزند هرگز نمی‌تونه از عناصر خارج اون Stacking Context جلو بزنه — مهم نیست عددش چقدر بزرگ باشه! این دقیقاً همون چیزیه که باعث می‌شه بعضی وقتا z-index «کار نکنه» با اینکه عدد درستی گذاشتی.

⚠️ اشتباهات رایج در کار با position

  • فراموش کردن position: relative رو والد: باعث می‌شه فرزند absolute نسبت به کل صفحه (نه والد مورد نظر) جابه‌جا بشه.
  • استفاده از fixed برای عنصری که باید فقط تو یه بخش خاص چسبان باشه: اینجا باید از sticky استفاده کنی، نه fixed؛ چون fixed کاملاً به viewport وابسته‌ست و به مرز والدش احترام نمی‌ذاره.
  • گذاشتن overflow: hidden رو والد یه عنصر sticky: این رایج‌ترین دلیل «چرا sticky من کار نمی‌کنه»‌ست.
  • تنظیم z-index بدون تنظیم position: z-index رو عناصر static (پیش‌فرض) هیچ اثری نداره؛ باید حتماً position غیر-static هم داشته باشه.

🧪 تمرین این جلسه

یه <div class="card"> با position: relative بساز. داخلش یه <span class="badge">جدید</span> بذار با position: absolute; top: -10px; right: -10px; تا مثل یه بج اعلان گوشه‌ی کارت بشینه. بعد یه دکمه‌ی «بازگشت به بالا» با position: fixed; bottom: 20px; left: 20px; بساز و ببین موقع اسکرول ثابت می‌مونه.

❓ سوالات متداول

فرق absolute و fixed در یه جمله چیه؟

absolute نسبت به نزدیک‌ترین جد positioned جابه‌جا می‌شه و با اسکرول همراه صفحه حرکت می‌کنه؛ fixed نسبت به viewport ثابته و حتی با اسکرول هم جاش عوض نمی‌شه.

چرا position: absolute من نسبت به کل صفحه قرار می‌گیره، نه والدش؟

چون هیچ‌کدوم از جدهاش position غیر-static ندارن. راه‌حل: رو والد مستقیم عنصر، position: relative بذار.

چرا sticky من کار نمی‌کنه؟

محتمل‌ترین دلیل: والد عنصر overflow: hidden یا overflow: auto داره، یا فراموش کردی top (یا یکی دیگه از چهار جهت) رو مشخص کنی.

🎯 جمع‌بندی و قدم بعدی

حالا با پنج مقدار اصلی position در CSS کامل آشنا شدی: static، relative، absolute، fixed و sticky، به‌همراه z-index و مفهوم Stacking Context. جلسه بعد می‌ریم سراغ Flexbox — یکی از قدرتمندترین ابزارهای چیدمان مدرن.

جلسه هشتم: آموزش کامل Flexbox در CSS ←

💬 نوبت توئه!

تا حالا با مشکل «z-index کار نمی‌کنه» مواجه شده بودی؟ حالا فهمیدی مشکل از کجا بود؟ همین پایین برامون بنویس 🚀

شهرام نجفی

شهرام نجفی

شهرام نجفی — بیش از ۱۵ سال طراحی و توسعهٔ وب به‌صورت فریلنس. قالب اختصاصی آوای وب را از صفر نوشته‌ام. مطالب این سایت را بر پایهٔ مستندات رسمی MDN و WHATWG می‌نویسم و قبل از انتشار در مرورگرهای واقعی تست می‌کنم. نمونه‌کارهایم در shahramnajafi.com است.

نظر شما در این مورد چیه؟