موقعیتدهی و سرریز
تا اینجا عنصرها همیشه سر جای طبیعی خودشان بودند. در این فصل یاد میگیریم آنها را از جریان عادی صفحه بیرون بکشیم و هر جا که خواستیم قرار دهیم.
۱. جریان عادی صفحه
مرورگر عنصرها را به ترتیبی که در HTML نوشتهاید میچیند: بلوکیها زیر هم و درونخطیها کنار هم. به این ترتیب طبیعی، جریان عادی میگویند.
ویژگی position به ما اجازه میدهد این جریان را بشکنیم.
مقدار پیشفرضش static است که یعنی «همان جریان عادی».
چهار مقدار دیگر هم دارد که این فصل درباره آنهاست.
هر چهار حالت با چهار ویژگی همراه، جای دقیق عنصر را تعیین میکنند: top، bottom، right و left. این چهار ویژگی روی عنصر static هیچ اثری ندارند و تنها وقتی position را عوض کنید کار میکنند.
۲. position: relative
.box {
position: relative;
top: 20px;
right: 30px;
}
position relative: نمونه 01-position-relative
شرح مثال
relative عنصر را نسبت به جای اصلی خودش
جابهجا میکند. در این مثال جعبه بیست پیکسل از بالا و
سی پیکسل از سمت راست خودش فاصله میگیرد.
نکته مهم اینکه جای اصلی عنصر خالی میماند. بقیه عنصرها طوری رفتار میکنند که انگار این عنصر هنوز سر جایش است. پس relative تنها ظاهر را جابهجا میکند و چیدمان بقیه را به هم نمیزند.
راستش را بخواهید، relative را به ندرت برای جابهجا کردن عنصر به کار میبریم. کاربرد اصلیاش این است که به یک عنصر position: relative بدهیم بدون هیچ مقدار top و right، تنها برای اینکه بشود عنصرهای absolute را داخلش قرار داد. در بخش بعد میبینید چرا.
۳. position: absolute
.card {
position: relative; /* والد مرجع */
width: 300px;
height: 200px;
}
.badge {
position: absolute;
top: 10px;
left: 10px;
background-color: #ff6347;
color: white;
padding: 5px 12px;
border-radius: 20px;
}
position absolute: نمونه 02-position-absolute
شرح مثال
absolute عنصر را کاملاً از جریان عادی
بیرون میکشد. جای اصلیاش دیگر خالی نمیماند و
بقیه عنصرها جایش را پر میکنند، انگار که اصلاً وجود ندارد.
سؤال مهم این است: نسبت به چه چیزی جابهجا میشود؟ جواب: نسبت به نزدیکترین والدی که position غیر از static دارد. اگر هیچ والدی چنین چیزی نداشته باشد، نسبت به کل صفحه محاسبه میشود.
به همین دلیل در مثال بالا به کارت position: relative دادیم.
این کار کارت را «مرجع» میکند تا نشان کوچک دقیقاً در گوشه
کارت بنشیند، نه در گوشه صفحه.
اگر عنصر absolute شما به جای گوشه کارت،
به گوشه کل صفحه پرید، دلیلش صد در صد این است که
به والدش position: relative ندادهاید.
این جفت، همیشه با هم میآیند:
والد relative، فرزند absolute.
موارد کاربرد رایج: نشان تخفیف روی گوشه محصول، دکمه بستن در گوشه یک پنجره، متن روی تصویر.
۴. position: fixed
.top-bar {
position: fixed;
top: 0;
right: 0;
left: 0;
background-color: #2f4f4f;
padding: 15px;
}
.back-to-top {
position: fixed;
bottom: 25px;
left: 25px;
}
body {
padding-top: 60px; /* جبران ارتفاع نوار ثابت */
}
position fixed: نمونه 03-position-fixed
شرح مثال
fixed هم عنصر را از جریان بیرون میکشد، اما مرجعش همیشه پنجره مرورگر است، نه هیچ والدی. نتیجهاش این است که عنصر با اسکرول کردن صفحه حرکت نمیکند و همیشه سر جایش روی صفحه باقی میماند.
در مثال بالا با دادن right: 0 و left: 0
به نوار بالا، آن را به تمام عرض صفحه کشیدهایم.
این ترفند رایجی برای منوهای ثابت است.
چون عنصر fixed از جریان بیرون است، جایی برای خودش
اشغال نمیکند و روی محتوای ابتدای صفحه میافتد و آن را میپوشاند.
راهحل، دادن padding-top به body
به اندازه ارتفاع نوار است، دقیقاً همان خط آخر مثال.
۵. position: sticky
.section-title {
position: sticky;
top: 0;
background-color: white;
padding: 12px;
}
position sticky: نمونه 04-position-sticky
شرح مثال
sticky ترکیبی از دو حالت قبل است و رفتار جالبی دارد:
- تا وقتی عنصر در محدوده دید است، مانند یک عنصر عادی رفتار میکند و با صفحه حرکت میکند.
- به محض اینکه بخواهد از بالای صفحه خارج شود، در همان نقطه میچسبد و مانند
fixedثابت میماند. - وقتی والدش هم از صفحه خارج شود، بار دیگر با آن میرود.
دو شرط برای کار کردن sticky لازم است:
باید حتماً یکی از top یا bottom را
مشخص کنید، و والد عنصر نباید overflow: hidden داشته باشد.
اگر sticky شما کار نمیکند، این دو را بررسی کنید.
| مقدار | نسبت به چه | جای اصلی خالی میماند | با اسکرول حرکت میکند |
|---|---|---|---|
static | جریان عادی | خودش آنجاست | بله |
relative | جای خودش | بله | بله |
absolute | نزدیکترین والد غیر static | خیر | بله |
fixed | پنجره مرورگر | خیر | خیر |
sticky | ترکیبی | بله | تا نقطه چسبیدن |
۶. z-index و لایهبندی
وقتی عنصرها از جریان بیرون میآیند، ممکن است روی هم بیفتند.
z-index تعیین میکند کدام رو باشد و کدام زیر.
.background-layer {
position: absolute;
z-index: 1;
}
.content-layer {
position: absolute;
z-index: 10; /* روی لایه قبلی */
}
.modal {
position: fixed;
z-index: 1000; /* روی همه چیز */
}
z-index: نمونه 05-z-index
شرح مثال
-
عدد بزرگتر یعنی جلوتر. عنصری با
z-index: 10روی عنصری باz-index: 1قرار میگیرد. z-indexتنها روی عنصرهایی کار میکند کهpositionغیر ازstaticدارند. این پرتکرارترین دلیل کار نکردن آن است.-
اگر
z-indexندهید، عنصری که در HTML پایینتر نوشته شده رو قرار میگیرد.
عادت بدی که بسیار رایج است، نوشتن اعداد بیحساب مانند ۹۹۹۹۹ است. بعد از مدتی هیچکس نمیداند چه چیزی روی چه چیزی است. یک نظم ساده انتخاب کنید: مثلاً ۱ تا ۱۰ برای محتوای عادی، ۱۰۰ برای منوی ثابت و ۱۰۰۰ برای پنجرههای بازشو.
۷. overflow
وقتی محتوا از جعبهاش بزرگتر است چه اتفاقی میافتد؟
به طور پیشفرض بیرون میزند و روی بقیه صفحه میریزد.
overflow این را کنترل میکند.
.box {
width: 300px;
height: 150px;
}
.visible {
overflow: visible; /* پیشفرض: بیرون میریزد */
}
.hidden {
overflow: hidden; /* اضافهها بریده میشوند */
}
.scroll {
overflow: scroll; /* همیشه نوار اسکرول */
}
.auto {
overflow: auto; /* فقط در صورت نیاز نوار اسکرول */
}
.only-vertical {
overflow-x: hidden;
overflow-y: auto;
}
overflow: نمونه 06-overflow
شرح مثال
| مقدار | نتیجه |
|---|---|
visible | پیشفرض. محتوا از جعبه بیرون میزند. |
hidden | هر چه بیرون بزند بریده و پنهان میشود. |
scroll | نوار اسکرول همیشه هست، حتی وقتی لازم نیست. |
auto | نوار اسکرول تنها وقتی محتوا بسیار باشد. بهترین انتخاب. |
دو نسخه جهتدار هم دارد: overflow-x برای افقی و
overflow-y برای عمودی. ترکیب رایج آنها،
همان دو خط آخر مثال است: اسکرول عمودی مجاز، افقی ممنوع.
اول، overflow: hidden روی جعبهای که
border-radius دارد و داخلش تصویر است.
بدون آن، گوشههای تصویر از گوشه گرد جعبه بیرون میزنند.
دوم، overflow-x: auto روی جدولهای عریض،
تا روی موبایل به جای خراب کردن کل صفحه، خودشان اسکرول بخورند.
۸. نمونه نهایی فصل
<body>
<header class="navbar">
<div class="logo">فروشگاه</div>
<nav><a href="#">خانه</a><a href="#">محصولات</a></nav>
</header>
<main>
<h2 class="sticky-title">محصولات ویژه</h2>
<div class="products">
<div class="product">
<span class="badge">۳۰٪ تخفیف</span>
<div class="image"></div>
<h3>محصول اول</h3>
</div>
<div class="product">
<span class="badge">جدید</span>
<div class="image"></div>
<h3>محصول دوم</h3>
</div>
</div>
<div class="note-box">
<p>متن طولانی که داخل یک جعبه با ارتفاع محدود قرار دارد...</p>
</div>
</main>
<a href="#" class="to-top">بالا</a>
</body>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Tahoma, sans-serif;
}
body {
background-color: #f5f5f5;
line-height: 1.9;
padding-top: 65px; /* جبران نوار ثابت */
}
/* نوار بالا: همیشه ثابت */
.navbar {
position: fixed;
top: 0;
right: 0;
left: 0;
z-index: 100;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #2f4f4f;
color: white;
padding: 18px 30px;
}
.navbar a {
color: white;
text-decoration: none;
margin-right: 18px;
}
/* عنوان چسبان */
.sticky-title {
position: sticky;
top: 65px;
z-index: 50;
background-color: #f5f5f5;
color: #2f4f4f;
padding: 15px 30px;
}
.products {
display: flex;
flex-wrap: wrap;
gap: 20px;
padding: 20px 30px;
}
/* کارت محصول: مرجع نشان تخفیف */
.product {
position: relative;
width: 250px;
background-color: white;
border-radius: 10px;
overflow: hidden; /* تا تصویر از گوشه گرد بیرون نزند */
padding-bottom: 15px;
}
.product .image {
height: 160px;
background-color: #dddddd;
}
.product h3 {
padding: 12px 15px 0;
color: #2f4f4f;
}
/* نشان تخفیف در گوشه کارت */
.badge {
position: absolute;
top: 10px;
left: 10px;
z-index: 5;
background-color: #ff6347;
color: white;
padding: 4px 12px;
border-radius: 20px;
font-size: 13px;
}
/* جعبه با ارتفاع محدود و اسکرول داخلی */
.note-box {
margin: 20px 30px;
height: 120px;
overflow-y: auto;
background-color: white;
padding: 15px;
border-radius: 10px;
}
/* دکمه شناور بازگشت به بالا */
.to-top {
position: fixed;
bottom: 25px;
left: 25px;
z-index: 200;
background-color: #ff6347;
color: white;
text-decoration: none;
padding: 12px 18px;
border-radius: 50px;
}
نمونه نهایی فصل: نمونه 07-final-example
شرح مثال
در این صفحه هر چهار حالت position و هر دو مفهوم دیگر فصل نقش دارند:
-
fixed روی نوار بالا و روی دکمه بازگشت به بالا.
هر دو با اسکرول حرکت نمیکنند. توجه کنید که
padding-top: 65pxرویbodyجای نوار را جبران کرده است. -
sticky روی عنوان بخش، با
top: 65px. یعنی «وقتی به شصت و پنج پیکسلی بالای صفحه رسیدی بچسب»، دقیقاً زیر نوار ثابت. این عدد باید با ارتفاع نوار هماهنگ باشد. -
relative و absolute به صورت جفت: کارت محصول
relativeاست و نشان تخفیفabsolute. به همین دلیل نشان در گوشه کارت مینشیند، نه گوشه صفحه. - z-index با یک نظم مشخص: ۵ برای نشان روی کارت، ۵۰ برای عنوان چسبان، ۱۰۰ برای نوار بالا و ۲۰۰ برای دکمه شناور. به این ترتیب همیشه معلوم است چه چیزی روی چه چیزی میافتد.
-
overflow در دو نقش:
hiddenروی کارت محصول تا گوشههای گرد تمیز بمانند، وoverflow-y: autoروی جعبه یادداشت تا متن طولانی به جای بیرون زدن، داخل خودش اسکرول بخورد.
پوشه 09-position-and-overflow شامل نمونههای
01-position-relative تا 07-final-example.
خلاصه فصل
| ویژگی | کارش |
|---|---|
position: relative | جابهجایی نسبت به جای خود؛ مرجع فرزندان absolute |
position: absolute | خروج از جریان، نسبت به نزدیکترین والد غیر static |
position: fixed | ثابت روی پنجره، بیتأثیر از اسکرول |
position: sticky | عادی تا نقطهای، بعد چسبیده |
top bottom right left | تعیین جای دقیق. روی static اثر ندارند. |
z-index | ترتیب لایهها. تنها با position غیر static. |
overflow: hidden | بریدن محتوای اضافه |
overflow: auto | اسکرول تنها در صورت نیاز |
تمرینهای فصل نه
- یک منوی ثابت بالای صفحه بسازید و با
padding-topجای آن را جبران کنید. - یک کارت محصول با نشان تخفیف در گوشهاش بسازید.
- عمداً
position: relativeوالد را حذف کنید و ببینید نشان کجا میرود. - یک دکمه بازگشت به بالا در گوشه پایین صفحه بگذارید که با اسکرول حرکت نکند.
- یک عنوان چسبان بسازید و صفحه را اسکرول کنید تا رفتارش را ببینید.
- جعبهای با ارتفاع ثابت بسازید و متن طولانی داخلش بگذارید. یک بار با
hiddenو یک بار باautoامتحان کنید.