آکادمی بنو/آموزش CSS

Position و Z-Index در CSS

بهنام نوبخت · ۱۴۰۵/۶/۲۸

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

برای انجام این کارها، CSS ابزار بسیار مهمی به نام position در اختیار ما قرار می‌دهد.

با position می‌توانیم روش قرارگیری یک عنصر در صفحه را تغییر دهیم و با ویژگی‌هایی مانند top، right، bottom و left موقعیت آن را کنترل کنیم. همچنین با z-index می‌توانیم مشخص کنیم هنگام روی‌هم قرار گرفتن چند عنصر، کدام عنصر بالاتر نمایش داده شود.

در این مقاله ابتدا مفهوم Position را یاد می‌گیریم و سپس با z-index به سراغ مدیریت لایه‌های عناصر می‌رویم.

Position چیست؟

ویژگی position مشخص می‌کند یک عنصر چگونه در Layout صفحه قرار بگیرد.

ساختار کلی:

.element {
    position: value;
}

مقادیر اصلی که در این مقاله بررسی می‌کنیم عبارت‌اند از:

position: static;
position: relative;
position: absolute;
position: fixed;
position: sticky;

هرکدام از این مقادیر رفتار متفاوتی دارند.

موقعیت static

مقدار پیش‌فرض position:

position: static;

است.

اگر برای یک عنصر هیچ position خاصی تعیین نکنیم، معمولاً در حالت static قرار دارد.

مثال:

.box {
    position: static;
}

در این حالت عنصر طبق جریان عادی صفحه قرار می‌گیرد.

آیا top و left در حالت static کار می‌کنند؟

خیر.

مثلاً:

.box {
    position: static;
    top: 50px;
    left: 50px;
}

تغییر قابل‌انتظاری ایجاد نمی‌کند؛ زیرا top و left برای جابه‌جایی عنصر static کاربرد ندارند.

بنابراین اگر می‌خواهیم از top، right، bottom یا left برای جابه‌جایی استفاده کنیم، باید ابتدا Position مناسب دیگری انتخاب کنیم.

Position نسبی — relative

یکی از مهم‌ترین مقادیر:

position: relative;

است.

وقتی یک عنصر relative باشد، همچنان جای اصلی خود را در جریان عادی صفحه حفظ می‌کند، اما می‌توانیم آن را نسبت به موقعیت معمول خودش جابه‌جا کنیم. فضای اولیه عنصر نیز همچنان برای آن حفظ می‌شود.

مثال:

<div class="box">
    Box
</div>
.box {
    position: relative;
    top: 20px;
    left: 30px;
}

عنصر نسبت به جای اصلی خودش:

  • ۲۰ پیکسل به پایین

  • ۳۰ پیکسل به سمت چپ

جابه‌جا می‌شود.

آیا عناصر دیگر جای عنصر relative را می‌گیرند؟

خیر.

این نکته بسیار مهم است.

فرض کنید:

<div class="box box-1">Box 1</div>
<div class="box box-2">Box 2</div>
<div class="box box-3">Box 3</div>

و:

.box-2 {
    position: relative;
    top: 30px;
}

Box 2 به پایین منتقل می‌شود، اما فضای اولیه آن همچنان در Layout حفظ می‌شود.

به زبان ساده:

Box 1

فضای اصلی Box 2
        ↓
      Box 2

Box 3

به همین دلیل relative با absolute تفاوت بسیار مهمی دارد.

ویژگی‌های top، right، bottom و left

بعد از تعیین Position مناسب، می‌توانیم از این ویژگی‌ها برای تعیین Offset استفاده کنیم:

top: 20px;
right: 20px;
bottom: 20px;
left: 20px;

مثلاً:

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

یعنی عنصر نسبت به موقعیت خود با Offset عمودی جابه‌جا شود.

یا:

.box {
    position: relative;
    left: 30px;
}

یعنی عنصر نسبت به موقعیت طبیعی خود در جهت افقی جابه‌جا شود.

این ویژگی‌ها «موقعیت نهایی» عنصر را تحت تأثیر قرار می‌دهند و رفتار دقیق آن‌ها به مقدار position بستگی دارد.

Position مطلق — absolute

حالا به یکی از مهم‌ترین بخش‌های این مقاله می‌رسیم:

position: absolute;

عنصر absolute از جریان عادی Layout خارج می‌شود.

یعنی دیگر فضای معمول خود را مانند یک عنصر عادی در صفحه حفظ نمی‌کند و موقعیت آن بر اساس Containing Block مربوط به خودش تعیین می‌شود.

مثال:

<div class="box">
    Box
</div>
.box {
    position: absolute;
    top: 20px;
    right: 20px;
}

حالا عنصر می‌تواند به موقعیتی خارج از جریان عادی منتقل شود.

تفاوت relative و absolute

این تفاوت را حتماً یاد بگیرید.

relative

position: relative;
  • عنصر در جریان عادی باقی می‌ماند.

  • فضای آن حفظ می‌شود.

  • می‌توان آن را نسبت به موقعیت طبیعی خودش جابه‌جا کرد.

absolute

position: absolute;
  • عنصر از جریان عادی خارج می‌شود.

  • فضای عادی آن در Layout حفظ نمی‌شود.

  • موقعیت آن نسبت به Containing Block مناسب تعیین می‌شود.

به همین دلیل absolute برای قرار دادن عناصر روی عناصر دیگر بسیار کاربردی است.

چرا معمولاً relative را روی والد قرار می‌دهیم؟

یکی از مهم‌ترین الگوهای CSS این است:

.parent {
    position: relative;
}

.child {
    position: absolute;
}

چرا؟

چون عنصر absolute معمولاً می‌خواهیم نسبت به یک والد مشخص موقعیت‌دهی شود.

مثلاً:

<div class="card">

    <span class="badge">
        جدید
    </span>

    <h2>دوره طراحی وب</h2>

    <p>
        آموزش کامل طراحی وب.
    </p>

</div>

CSS:

.card {
    position: relative;
}

.badge {
    position: absolute;
    top: 10px;
    right: 10px;
}

در اینجا badge نسبت به محدوده مناسب .card موقعیت‌دهی می‌شود.

این الگو در طراحی کارت‌ها، تصاویر، اعلان‌ها، Badgeها و بسیاری از رابط‌های کاربری بسیار پرکاربرد است.

یک مثال واقعی: Badge روی کارت

HTML:

<div class="product-card">

    <span class="badge">
        جدید
    </span>

    <h2>دوره HTML و CSS</h2>

    <p>
        آموزش طراحی صفحات وب از پایه.
    </p>

</div>

CSS:

.product-card {
    position: relative;
    width: 300px;
    padding: 30px;
    border: 1px solid #ddd;
    border-radius: 12px;
}

.badge {
    position: absolute;
    top: 10px;
    right: 10px;
    padding: 5px 10px;
    background-color: #222;
    color: white;
    border-radius: 5px;
}

نتیجه:

┌──────────────────────────┐
│                    جدید  │
│                          │
│   دوره HTML و CSS        │
│                          │
│   آموزش طراحی صفحات وب  │
│                          │
└──────────────────────────┘

این یکی از کاربردهای واقعی relative و absolute است.

Position ثابت — fixed

حالت بعدی:

position: fixed;

است.

عنصر fixed نسبت به Viewport موقعیت‌دهی می‌شود و از جریان عادی صفحه خارج می‌شود. در نتیجه می‌توان عناصری ساخت که هنگام Scroll در موقعیت مشخصی از صفحه باقی بمانند.

مثلاً:

.help-button {
    position: fixed;
    right: 20px;
    bottom: 20px;
}

می‌توانیم با این روش یک دکمه شناور در گوشه صفحه ایجاد کنیم.

مثال دکمه ثابت

HTML:

<button class="help-button">
    پشتیبانی
</button>

CSS:

.help-button {
    position: fixed;
    right: 20px;
    bottom: 20px;
    padding: 12px 20px;
}

حالا دکمه در گوشه پایین صفحه قرار می‌گیرد و هنگام Scroll نیز در همان ناحیه Viewport باقی می‌ماند.

این روش برای مواردی مانند:

  • دکمه پشتیبانی

  • دکمه بازگشت به بالا

  • نوارهای ثابت

  • بعضی اعلان‌ها

  • کنترل‌های شناور

کاربرد دارد.

Position چسبنده — sticky

مقدار دیگر:

position: sticky;

است.

sticky رفتاری ترکیبی دارد.

عنصر در حالت عادی در جریان صفحه قرار دارد، اما هنگام Scroll می‌تواند پس از رسیدن به Offset تعیین‌شده، در موقعیت مشخصی باقی بماند.

مثلاً:

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

یعنی عنصر هنگام رسیدن به بالای Viewport می‌تواند در آن ناحیه باقی بماند.

مثال Header چسبنده

<header class="header">
    منوی سایت
</header>

<main>
    <p>محتوای زیاد...</p>
    <p>محتوای زیاد...</p>
    <p>محتوای زیاد...</p>
    <p>محتوای زیاد...</p>
</main>

CSS:

.header {
    position: sticky;
    top: 0;
    padding: 15px;
    background-color: white;
    border-bottom: 1px solid #ddd;
}

در این حالت Header در جریان صفحه قرار دارد، اما هنگام Scroll می‌تواند در بالای صفحه بچسبد.

برای اینکه sticky روی یک محور عمل کند، باید حداقل یکی از Offsetهای همان محور مانند top مقدار غیر auto داشته باشد.

تفاوت fixed و sticky

این دو را با هم اشتباه نگیرید.

ویژگی

fixed

sticky

در جریان عادی؟

خیر

بله

نسبت به Viewport؟

معمولاً بله

نسبت به محدوده Scroll مناسب

هنگام Scroll ثابت می‌ماند؟

بله

پس از رسیدن به Offset

فضای اولیه حفظ می‌شود؟

خیر

بله

کاربرد رایج

دکمه شناور

Header یا عنوان چسبنده

مقایسه تمام حالت‌های Position

مقدار

در جریان عادی

جابه‌جایی با Offset

کاربرد

static

بله

خیر

حالت پیش‌فرض

relative

بله

بله

جابه‌جایی نسبی و والد Absolute

absolute

خیر

بله

قرارگیری دقیق داخل والد

fixed

خیر

بله

عناصر ثابت نسبت به Viewport

sticky

بله

بله

عناصر چسبنده هنگام Scroll

این جدول را می‌توانید به‌عنوان خلاصه بخش اول مقاله نگه دارید.

z-index چیست؟

حالا فرض کنید دو عنصر روی یکدیگر قرار گرفته‌اند.

کدام‌یک باید روی دیگری دیده شود؟

اینجاست که:

z-index

وارد می‌شود.

z-index ترتیب قرارگیری عناصر در محور عمودی فرضی Z را کنترل می‌کند؛ عدد بزرگ‌تر معمولاً باعث می‌شود عنصر در همان Stacking Context روی عنصر با عدد کوچک‌تر قرار بگیرد.

مثلاً:

.box-one {
    z-index: 1;
}

.box-two {
    z-index: 2;
}

در شرایط مناسب، box-two روی box-one قرار می‌گیرد.

مفهوم محور Z

ما معمولاً صفحه را در دو محور تصور می‌کنیم:

X → افقی
Y ↓ عمودی

اما وقتی عناصر روی یکدیگر قرار می‌گیرند، یک محور سوم نیز اهمیت پیدا می‌کند:

Z → جلو و عقب

مثلاً:

لایه 3  ← بالاتر
لایه 2
لایه 1
لایه 0
لایه -1 ← پایین‌تر

z-index برای کنترل این ترتیب استفاده می‌شود.

مثال ساده z-index

HTML:

<div class="box red">
    Box 1
</div>

<div class="box blue">
    Box 2
</div>

CSS:

.box {
    position: absolute;
    width: 150px;
    height: 150px;
}

.red {
    top: 50px;
    left: 50px;
    z-index: 1;
}

.blue {
    top: 100px;
    left: 100px;
    z-index: 2;
}

چون:

z-index: 2;

از:

z-index: 1;

بیشتر است، Box دوم در ترتیب لایه‌ای بالاتر قرار می‌گیرد.

آیا z-index همیشه کار می‌کند؟

این یکی از نکات مهم است.

z-index به مفهوم Stacking Context وابسته است و فقط با مقایسه ساده همه عناصر صفحه نمی‌توان رفتار آن را پیش‌بینی کرد.

برای مثال، وقتی یک عنصر در یک Stacking Context قرار دارد، z-index فرزندان آن الزاماً با z-index عناصر خارج از همان Context مستقیماً مقایسه نمی‌شود.

در سطح فعلی دوره، فعلاً کافی است این قانون ساده را به خاطر بسپارید:

اگر عناصر روی یکدیگر قرار گرفته‌اند، z-index می‌تواند ترتیب لایه‌های آن‌ها را کنترل کند؛ اما نتیجه نهایی به Stacking Context نیز وابسته است.

جزئیات Stacking Context را بعداً می‌توان در مباحث پیشرفته‌تر CSS بررسی کرد.

z-index منفی

z-index می‌تواند مقدار منفی نیز داشته باشد:

z-index: -1;

مثلاً:

.background {
    position: absolute;
    z-index: -1;
}

اما استفاده از مقادیر منفی نیازمند دقت است، زیرا نتیجه آن به Stacking Context و ساختار صفحه بستگی دارد.

برای شروع بهتر است بیشتر با مقادیر ساده مانند:

z-index: 1;
z-index: 2;
z-index: 10;

کار کنید.

یک پروژه کاربردی: تصویر با Badge

حالا یک مثال کامل‌تر بسازیم.

HTML:

<div class="card">

    <img
        src="images/course.jpg"
        alt="دوره طراحی وب"
    >

    <span class="badge">
        ویژه
    </span>

    <div class="card-content">
        <h2>دوره طراحی وب</h2>

        <p>
            یادگیری HTML و CSS از پایه.
        </p>
    </div>

</div>

CSS:

.card {
    position: relative;
    width: 320px;
    overflow: hidden;
    border: 1px solid #ddd;
    border-radius: 12px;
}

.card img {
    display: block;
    width: 100%;
}

.badge {
    position: absolute;
    top: 15px;
    right: 15px;
    z-index: 2;

    padding: 6px 12px;
    border-radius: 6px;

    background-color: #222;
    color: white;
}

.card-content {
    padding: 20px;
}

در این مثال:

.card {
    position: relative;
}

باعث می‌شود کارت مرجع مناسبی برای Badge باشد.

و:

.badge {
    position: absolute;
}

Badge را در موقعیت مشخصی از کارت قرار می‌دهد.

همچنین:

z-index: 2;

به ما کمک می‌کند Badge در ترتیب لایه‌ای مناسب قرار بگیرد.

مثال کاربردی دیگر: لایه روی تصویر

یکی از کاربردهای بسیار رایج Position، ایجاد Overlay روی تصویر است.

HTML:

<div class="image-box">

    <img
        src="images/banner.jpg"
        alt="بنر دوره"
    >

    <div class="overlay">
        مشاهده دوره
    </div>

</div>

CSS:

.image-box {
    position: relative;
    width: 400px;
}

.image-box img {
    display: block;
    width: 100%;
}

.overlay {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;

    display: flex;
    align-items: center;
    justify-content: center;

    background-color: rgba(0, 0, 0, 0.5);
    color: white;
}

در این مثال overlay روی تصویر قرار می‌گیرد.

flex در این مثال فقط برای وسط‌چین کردن محتوای Overlay استفاده شده است. Flexbox را در بخش مربوط به خودش به‌صورت کامل یاد خواهیم گرفت.

اشتباهات رایج در Position

اشتباه اول: استفاده از absolute بدون شناخت والد

گاهی می‌نویسیم:

.badge {
    position: absolute;
    top: 10px;
    right: 10px;
}

اما عنصر در جای مورد انتظار قرار نمی‌گیرد.

یکی از دلایل رایج این است که والد مناسب برای موقعیت‌دهی مشخص نشده است.

در بسیاری از طراحی‌ها، الگوی زیر راه‌حل مناسبی است:

.parent {
    position: relative;
}

.child {
    position: absolute;
}

اشتباه دوم: استفاده از absolute برای همه چیز

absolute ابزار قدرتمندی است، اما نباید تمام Layout صفحه را با آن طراحی کنیم.

برای Layout اصلی صفحه در آینده ابزارهایی مانند:

  • Flexbox

  • Grid

را یاد خواهیم گرفت.

absolute بیشتر برای موقعیت‌دهی دقیق عناصر خاص بسیار مناسب است.

اشتباه سوم: انتظار داشتن از fixed برای حفظ فضای عنصر

عنصر fixed از جریان عادی خارج می‌شود.

بنابراین اگر یک Header را به شکل زیر ثابت کنیم:

header {
    position: fixed;
    top: 0;
}

ممکن است محتوای صفحه زیر Header قرار بگیرد.

در چنین شرایطی معمولاً باید فضای مناسب برای Header در Layout در نظر گرفته شود.

اشتباه چهارم: استفاده بیش از حد از z-index

مثلاً:

z-index: 999999;

لزوماً مشکل را حل نمی‌کند.

اگر Stacking Contextها درست درک نشده باشند، حتی یک عدد بسیار بزرگ نیز ممکن است نتیجه مورد انتظار را ایجاد نکند.

بهتر است ابتدا ساختار لایه‌ها را بررسی کنید و سپس مقدار منطقی برای z-index تعیین کنید.

پروژه تمرینی کامل

یک کارت پروفایل طراحی کنید:

<div class="profile-card">

    <span class="status">
        آنلاین
    </span>

    <img
        src="images/profile.jpg"
        alt="تصویر پروفایل"
    >

    <h2>علی احمدی</h2>

    <p>
        توسعه‌دهنده وب
    </p>

    <button>
        مشاهده پروفایل
    </button>

</div>

CSS اولیه:

.profile-card {
    position: relative;
    width: 300px;
    padding: 20px;
    text-align: center;
    border: 1px solid #ddd;
    border-radius: 12px;
}

.profile-card img {
    width: 120px;
    height: 120px;
    border-radius: 50%;
}

.status {
    position: absolute;
    top: 15px;
    right: 15px;

    padding: 5px 10px;
    border-radius: 20px;

    background-color: #222;
    color: white;

    z-index: 2;
}

در این پروژه باید بررسی کنید:

  • چرا profile-card باید relative باشد؟

  • چرا status باید absolute باشد؟

  • چرا z-index برای Status می‌تواند مفید باشد؟

  • اگر profile-card را relative نکنیم چه اتفاقی ممکن است بیفتد؟

تمرین‌های مقاله

تمرین ۱ — Relative

سه Box بسازید و Box دوم را با relative به اندازه 30 پیکسل پایین ببرید.

تمرین ۲ — Absolute

یک کارت بسازید و یک Badge را در گوشه بالای کارت قرار دهید.

راهنمایی:

.card {
    position: relative;
}

.badge {
    position: absolute;
    top: 10px;
    right: 10px;
}

تمرین ۳ — Fixed

یک دکمه در پایین سمت راست صفحه قرار دهید که هنگام Scroll نیز در همان محل باقی بماند.

تمرین ۴ — Sticky

یک Header ایجاد کنید که هنگام Scroll در بالای صفحه باقی بماند.

header {
    position: sticky;
    top: 0;
}

تمرین ۵ — Z-Index

دو Box بسازید که روی یکدیگر قرار بگیرند.

سپس:

.box-one {
    z-index: 1;
}

.box-two {
    z-index: 2;
}

را امتحان کنید.

بعد مقدارها را جابه‌جا کنید و نتیجه را ببینید.

جمع‌بندی

در این مقاله یکی از مهم‌ترین ابزارهای CSS برای کنترل موقعیت عناصر را یاد گرفتیم.

static حالت پیش‌فرض عناصر است.

relative به ما اجازه می‌دهد عنصر را نسبت به موقعیت طبیعی خودش جابه‌جا کنیم، بدون اینکه فضای اصلی آن از Layout حذف شود.

absolute عنصر را از جریان عادی خارج می‌کند و برای قرار دادن دقیق عناصر، مخصوصاً داخل یک والد مشخص، بسیار کاربردی است.

fixed برای عناصری مناسب است که می‌خواهیم نسبت به Viewport در موقعیت مشخصی باقی بمانند.

sticky رفتاری بین حالت عادی و ثابت دارد و برای Headerها و بخش‌هایی که هنگام Scroll باید در موقعیت مشخصی باقی بمانند بسیار مفید است.

در نهایت با z-index با مفهوم لایه‌ها و ترتیب قرارگیری عناصر روی یکدیگر آشنا شدیم. عدد بزرگ‌تر در یک Stacking Context مناسب، عنصر را در لایه بالاتری قرار می‌دهد.

۱۰

نظرات

کد در دسترس نیست

هنوز نظری ثبت نشده است.