تعیین موقعیت عناصر در CSS | آموزش CSS (بخش سیام)
با تعیین موقعیت عناصر در CSS امکان خارج کردن عناصر صفحه وب از گردش نرمال صفحه و ایجاد رفتار متفاوت در آنها را فراهم میسازد. برای نمونه میتوانیم کاری کنیم که عناصر روی هم قرار گیرند یا در ویوپورت مرورگر همواره در موقعیت ثابتی قرار داشته باشند. در این مقاله به توضیح تفاوتهای بین مقادیر مختلف Position در CSS و شیوه استفاده از آنها میپردازیم.
برای مطالعه بخش قبلی این سری مقالات آموزشی روی لینک زیر کلیک کنید:
اگر میخواهید مثالهایی که در این راهنما معرفی میشوند را پیگیری کنید، یک فایل روی سیستم خود ایجاد کرده و نام آن را basic-flow.html گذاشته و کد زیر را در آن کپی کرده و ذخیره کنید:
1<!DOCTYPE html>
2<html>
3 <head>
4 <meta charset="utf-8">
5 <title>Basic document flow</title>
6
7 <style>
8 body {
9 width: 500px;
10 margin: 0 auto;
11 }
12
13 p {
14 background: aqua;
15 border: 3px solid blue;
16 padding: 10px;
17 margin: 10px;
18 }
19
20 span {
21 background: red;
22 border: 1px solid black;
23 }
24 </style>
25 </head>
26 <body>
27 <h1>Basic document flow</h1>
28
29 <p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
30
31 <p>By default we span 100% of the width of our parent element, and our are as tall as our child content. Our total width and height is our content + padding + border width/height.</p>
32
33 <p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
34
35 <p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements <span>wrap onto a new line if possible — like this one containing text</span>, or just go on to a new line if not, much like this image will do: <img src="long.jpg"></p>
36
37 </body>
38</html>
معرفی موقعیتیابی در CSS
ایده کلی «موقعیتیابی» (Positioning) این است که بتوانیم رفتار گردش نرمال سند را که در بخش قبل توضیح دادیم، دور بزنیم و جلوههای جالبی خلق کنیم. اگر بخواهیم موقعیت برخی باکسها را درون یک لیآوت از موقعیت گردش نرمال صفحه خارج کنیم تا حس متفاوتی خلق کنیم چه کار باید بکنیم؟ راهحل این مسئله موقعیتیابی است. همچنین اگر بخواهیم یک عنصر UI ایجاد کنیم که روی بقیه بخشهای صفحه قرار گیرد و یا صرف نظر از اسکرول شدن صفحه، همواره در موقعیت ثابتی روی صفحه واقع شود، باید از موقعیتیابی استفاده کنیم.
روشهای مختلفی برای موقعیتیابی وجود دارند که میتوان روی عناصر HTML مورد استفاده قرار داد. برای این که نوع خاصی از موقعیتیابی را روی یک عنصر فعال کنید، باید از مشخصه Position بهره بگیرید.
موقعیتیابی استاتیک
«موقعیتیابی استاتیک» (Static Positioning) نوع پیشفرض است که همه عناصر آن را دارند. معنی موقعیتیابی استاتیک این است که عنصر در موقعیت نرمال خود در گردش لیآوت سند قرار گیرد و هیچ تغییر خاصی صورت نپذیرد.
برای نمایش این وضعیت و آمادهسازی یک مثال برای استفاده در بخشهای ادامه این مقاله ابتدا باید کلاس positioned را به <p> دوم در HTML اضافه کنیم:
1<p class="positioned"> ... </p>
اکنون قاعده زیر را به انتهای CSS خود اضافه کنید:
1.positioned {
2 position: static;
3 background: yellow;
4}
اگر فایل HTML را اینک ذخیره کرده و صفحه را رفرش کنید، هیچ تفاوتی نخواهید دید به جز این که رنگ پسزمینه پاراگراف دوم تغییر یافته است. همچنان که پیشتر گفتیم موقعیتیابی استاتیک همان رفتار پیشفرض عناصر است.
موقعیتیابی نسبی
«موقعیتیابی نسبی» (Relative Positioning) نخستین نوع از موقعیتیابی است که بررسی میکنیم. این نوع کاملاً مشابه موقعیتیابی استاتیک است، به جز این که عنصر موقعیتیابیشده جایگاه خود را در گردش لیآوت نرمال میگیرد و میتوانید موقعیت نهایی را تغییر دهید. مثلاً میتوانید آن را روی عناصر دیگر صفحه قرار دهید. در ادامه اعلان position را در کد خود به صورت زیر تغییر میدهیم:
1position: relative;
اینک اگر صفحه را ذخیره و رفرش کنید، هیچ تغییری در نتیجه مشاهده نمیکنید. بنابراین تأثیر تغییر موقعیت عنصر در چه بوده است؟ برای ایجاد تغییر واقعی باید از مشخصههای top، bottom، left و right به ترتیب که در بخش بعدی توضیح خواهیم داد، استفاده کنید.
مشخصههای top ،bottom ،left و right
چهار مشخصه top ،bottom ،left و right همراه با position برای تعیین مکان دقیق قرارگیری عنصر استفاده میشوند. برای امتحان کردن این مقادیر اعلان زیر را به قاعده .positioned در CSS خود اضافه کنید:
1top: 30px;
2left: 30px;
توجه کنید که مقادیر این مشخصهها میتوانند هر واحد معقولی مانند پیکسل، میلیمتر، rems، درصد و غیره را بگیرند. اگر اکنون فایل را ذخیره و صفحه را رفرش کنید نتیجهای مانند زیر میبینید:
چنان که میبینید پاراگراف دوم به سمت راست و پایین جابجا شده است. توجه کنید که اگر چه ما مشخصههای بالا و چپ را تغییر دادیم، اما طرز کار موقعیتیابی نسبی این گونه است. در واقع این طور به نظر میرسد که از جهت تعیینشده، نیرویی به عنصر مورد نظر وارد میشود و آن را در جهت عکس حرکت میدهد. بنابراین برای نمونه اگر مقدار top: 30px; تعیین شود، نیروی از سمت بالا به باکس وارد میشود و آن را به میزان 30 پیکسل به سمت پایین میراند.
موقعیتیابی مطلق
«موقعیتیابی مطلق» (Absolute positioning) نتایج بسیار متفاوتی ایجاد میکند. در این بخش اعلان موقعیت را در کد خود به صورت زیر تغییر میدهیم:
1position: absolute;
اگر فایل را ذخیره و صفحه را رفرش کنید، چیزی مانند زیر میبینید:
قبل از هر چیز توجه کنید که فاصلهای که عنصر موقعیتیابیشده در گردش سند باید در آنجا قرار داشت، دیگر وجود ندارد. عنصر اول و سوم به هم نزدیکتر شدهاند. به این ترتیب متوجه میشویم که عنصر با موقعیتیابی مطلق دیگر در گردش لیآوت نرمال سند قرار ندارد، بلکه در لایه خاص خود قرار میگیرد که از همه لایههای دیگر جدا است. این رویه بسیار مفیدی است، چون میتوانیم قابلیتهای UI را که با موقعیت عناصر روی صفحه تداخل ندارند از هم جدا کنیم. برای نمونه باکسهای اطلاعات پاپآپ و منوهای کنترل یا پنلهای جمعشدنی و همچنین مواردی که میتوانند هر جای صفحه کشیده و رها شوند از این نوع موقعیتیابی بهره میبرند.
نکته دوم که باید توجه کنیم این است که موقعیت عنصر تغییر یافته است. دلیل این امر آن است که مشخصههای top ،bottom ،left و right در موقعیتیابی مطلق به طرز متفاوتی عمل میکنند. در این زمان به جای تعیین جهت حرکت عنصر، مسافت عنصر از اضلاع عنصر محتوی خود را مشخص میکنند. بنابراین در این مورد بیان کردهایم که عنصر با موقعیتیابی مطلق باید در فاصله 30 پیکسل از بخش فوقانی عنصر حاوی خود و در فاصله 30 پیکسل از سمت چپ عنصر حاوی خود قرار گیرد.
چارچوبهای موقعیتیابی
در بخش قبل از «عنصر حاوی» صحبت کردیم. اینک عنصر حاوی عنصر با موقعیتیابی مطلق ما در مثال قبلی کدام است؟ این موضوع به میزان زیادی به مشخصه position اجداد عنصر موقعیتیابیشده بستگی دارد.
اگر هیچ یک از عناصر اجداد عنصر حاضر دارای مشخصهای نباشد که موقعیت آن به صورت صریح تعیین شده باشد، در این صورت به صورت پیشفرض همه عناصر دارای موقعیت استاتیک خواهند بود. نتیجه این وضعیت آن است که عنصر با موقعیتیابی مطلق در «بلوک شامل اولیه» (initial containing block) قرار میگیرد. بلوک شامل اولیه همان ابعاد ویوپورت را دارد و همان بلوکی است که عنصر <html> در آن قرار میگیرد. به بیان ساده، عنصر با موقعیتیابی مطلق خارج از عنصر <html> قرار میگیرد و به صورت نسبی با ویوپورت اولیه موقعیتیابی میشود.
عنصر موقعیتیابیشده درون <body> در سورس HTML قرار میگیرد، اما در لیآوت نهایی 30 پیکسل از لبههای بالا و چپ صفحه فاصله میگیرد. ما میتوانیم «چارچوب موقعیتیابی» یک عنصر را تغییر دهیم. این کار از طریق تعیین موقعیتیابی روی اجداد عنصر صورت میگیرد. برای نمایش این موضوع اعلان زیر را به قاعده body اضافه کنید:
1position: relative;
نتیجه کد فوق به صورت زیر است:
عنصر موقعیتیابیشده اکنون در نسبت با عنصر <body> موقعیتیابی میشود.
معرفی z-index
موقعیتیابی مطلق که در بخش قبل معرفی کردیم، به تنهایی روش مفید و مناسبی محسوب میشود، اما نکته دیگری نیز وجود دارد که هنوز بررسی نکردهایم. زمانی که عناصر روی هم قرار میگیرند، کدام عامل تعیین میکند برخی عناصر روی دیگری قرار گیرند؟ در مثال قبلی که دیدیم، تنها یک عنصر در چارچوب موقعیتیابی قرار داشت و روی بقیهی عناصر قرار میگرفت، زیرا عناصر موقعیتیابیشده نسبت به عناصر بدون موقعیتیابی تقدم بالاتری دارند. اما اگر بیش از یک عنصر موقعیتیابیشده وجود داشته باشد چطور؟
با افزودن CSS زیر میتوانید کاری کنید که پاراگراف اول نیز دارای موقعیتیابی مطلق باشد.
1p:nth-of-type(1) {
2 position: absolute;
3 background: lime;
4 top: 10px;
5 right: 30px;
6}
در این زمان میبینید که پاراگراف اول به رنگ لیمویی درمیآید و از گردش نرمال سند خارج میشود و کمی بالاتر از جایی که در ابتدا بود، قرار میگیرد. این عنصر همچنین زیر پاراگراف اصلی positioned. که روی هم قرار گرفتهاند، قرار میگیرد. دلیل این امر آن است که پاراگراف positioned. دومین پاراگراف از نظر ترتیب کد است و عناصر موقعیتیابیشده بعدی از نظر ترتیب سورس کد، روی عناصر قبلی موقعیتیابیشده قرار میگیرند.
البته امکان تغییر روش قرارگیری عناصر همپوشان وجود دارد. این کار با استفاده از مشخصه z-index صورت میگیرد. این مشخصه مرجعی برای محور ارتفاع (z) محسوب میشود. در بخشهای قبلی این سری مقالات آموزشی اشاره کردیم که صفحههای وب دارای محور افقی (x) و محور عمودی (y) هستند و از آنها برای موقعیتیابی چیزهایی مانند تصاویر پسزمینه و آفستهای سایههای زیرین استفاده میکنند. مقدار (0,0) به معنی گوشه چپ و بالای صفحه (یا عنصر) است و محورهای X و Y به سمت راست و پایین امتداد مییابند.
صفحههای وب دارای یک محور دیگر به نام محور z نیز هستند. این خط خیالی از سطح صفحه به سمت بیرون و در امتداد کاربر بازدیدکننده کشیده شده است. مقادیر z-index موقعیت عناصر را روی این محور تعیین میکنند. مقادیر مثبت بالاتر قرار میگیرند و مقادیر کمتر در ردههای پایینتر واقع میشوند. به صورت پیشفرض عناصر موقعیتیابیشده همگی دارای یک z-index به مقدار auto هستند که عملاً به معنی مقدار 0 است.
برای تغییر ترتیب قرارگیری عناصر همپوشان روی هم، اعلان زیر را به قاعده p:nth-of-type(1) خود اضافه کنید:
1z-index: 1;
اینک باید نتیجهای مانند زیر ببینید که پاراگراف به رنگ لیمویی به بالا آمده است:
توجه کنید که z-index مقادیر اندیس بدون واحد میپذیرد. شما نمیتوانید تعیین کنید که میخواهید یک عنصر 23 پیکسل از مبدأ محور Z فاصله داشته باشد. طرز کار این محور چنین نیست. این محور مقادیر بدون واحد میگیرد و مقادیر بیشتر موجب میشوند عنصر در سطح بالاتری قرار گیرد و مقادیر کمتر موجب قرار گیری در سطوح پایینتر میشوند. از این رو استفاده از دو مقدار 2 و 3 همان تأثیری را دارد که مقادیر 300 و 40000 دارند.
موقعیتیابی ثابت
در این بخش به بررسی «موقعیتیابی ثابت» (Fixed Positioning) میپردازیم. این نوع از موقعیتیابی به همان طریق موقعیتیابی مطلق کار میکند. تنها تفاوت کلیدی آن در این است که در موقعیتیابی مطلق یک عنصر در رابطه با نزدیکترین والد خود قرار میگرفت، اما در موقعیتیابی ثابت، عنصر در یک موقعیت ثابت در رابطه با خود ویوپورت قرار میگیرد. این بدان معنی است که میتوانید آیتمهای مفید UI مانند منوهای ناوبری بسازید که در موقعیت ثابتی قرار دارند.
در این بخش با ارائه یک مثال جامع منظور خود را تبیین میکنیم. قبل از هر چیز باید قواعد p:nth-of-type(1) و.positioned را از CSS حذف کنید. سپس قاعده body را تغییر داده و اعلان ;position: relative را حذف کنید و یک ارتفاع ثابت به آن بدهید:
1body {
2 width: 500px;
3 height: 1400px;
4 margin: 0 auto;
5}
اکنون باید مقدار موقعیت عنصر <h1> را به صورت ;position: fixed تعیین کنیم تا در بالاترین نقطه ویوپورت قرار گیرد. قاعده زیر را به CSS اضافه کنید:
1h1 {
2 position: fixed;
3 top: 0;
4 width: 500px;
5 margin-top: 0;
6 background: white;
7 padding: 10px;
8}
اعلان ;top: 0 برای این که این عنصر به بخش فوقانی صفحه بچسبد ضروری است. عرض عنوان را برابر با عرض ستون محتوا قرار میدهیم و یک پسزمینه سفید و مقداری padding و margin به آن دادهایم تا محتوا در زیر آن دیده نشود.
اینک اگر فایل را ذخیره و صفحه را رفرش کنید یک جلوه کوچک جالب میبینید که موجب شده عنوان صفحه به صورت ثابت درآید و محتوا در زمان اسکرول شدن پیدا و نهان میشود. اما این وضعیت را میتوان بیش از این بهبود بخشید. در این زمان بخشی از محتوا زیر عنوان دیده میشوند. دلیل این امر آن است که عنوان موقعیتیابیشده دیگر در گردش نرمال سند قرار ندارد، بنابراین بقیه محتوا به سمت و پایین و بالا حرکت میکنند. ما باید آن را کمی به سمت پایین حرکت دهیم. این کار با تعیین مقداری برای حاشیه فوقانی پاراگراف اول انجام میدهیم:
1p:nth-of-type(1) {
2 margin-top: 60px;
3}
اینک باید با نتیجهای مانند زیر مواجه شوید:
موقعیتیابی چسبان
یک نوع دیگر از موقعیتیابی نیز وجود دارد که «موقعیتیابی چسبان» (position: sticky) نام دارد و جدیدتر از موارد دیگر است. این نوع موقعیتیابی در عمل ترکیبی از موقعیتیابی نسبی و ثابت است. این موقعیتیابی موجب میشود که عنصر مورد نظر تا یک حد آستانه مانند یک عنصر با موقعیتیابی نسبی عمل کند و پس از آن از نوع موقعیتیابی ثابت استفاده میکند. از این نوع موقعیتیابی میتوان برای مثال برای یک نوار ناوبری استفاده کرد که تا حد مشخصی همراه با اسکرول شدن صفحه با آن همراهی میکند، اما پس از آن در بالای صفحه قرار میگیرد.
1.positioned {
2 position: sticky;
3 top: 30px;
4 left: 30px;
5}
یکی از کاربردهای رایج و جالب موقعیتیابی position: sticky ایجاد یک صفحه اندیس اسکرولشونده است که عناوین مختلف در زمان رسیدن به ابتدای صفحه به آن میچسبند. فایل HTML چنین صفحهای به صورت زیر است:
1<h1>Sticky positioning</h1>
2
3<dl>
4 <dt>A</dt>
5 <dd>Apple</dd>
6 <dd>Ant</dd>
7 <dd>Altimeter</dd>
8 <dd>Airplane</dd>
9 <dt>B</dt>
10 <dd>Bird</dd>
11 <dd>Buzzard</dd>
12 <dd>Bee</dd>
13 <dd>Banana</dd>
14 <dd>Beanstalk</dd>
15 <dt>C</dt>
16 <dd>Calculator</dd>
17 <dd>Cane</dd>
18 <dd>Camera</dd>
19 <dd>Camel</dd>
20 <dt>D</dt>
21 <dd>Duck</dd>
22 <dd>Dime</dd>
23 <dd>Dipstick</dd>
24 <dd>Drone</dd>
25 <dt>E</dt>
26 <dd>Egg</dd>
27 <dd>Elephant</dd>
28 <dd>Egret</dd>
29</dl>
CSS نیز میتواند مانند زیر باشد. در گردش نرمال، عناصر <dt> به همراه محتوا اسکرول میشوند. زمانی که position: sticky را به عنصر <dt> اضافه کنیم، همراه با مقدار top با مقدار 0 موجب میشود که عناوین در زمان رسیدن به ابتدای صفحه در مرورگرهایی که از این قابلیت پشتیبانی میکنند به آنجا بچسبند. همه هدرهای بعدی در زمانی که به جای هدر قبلی برسند، جایگزین آن میشوند.
1dt {
2 background-color: black;
3 color: white;
4 padding: 10px;
5 position: sticky;
6 top: 0;
7 left: 0;
8 margin: 1em 0;
9}
سخن پایانی
امیدواریم از مطالعه این مقاله لذت برده باشید و کار کردن با مقادیر مختلف موقعیتیابی در CSS موجب افزایش دانش شما شده باشد. با این که موقعیتیابی چیزی نیست که در همه لیآوتها به استفاده از آن نیاز داشته باشیم، اما چنان که در طول این راهنما دیدید، کارکردهای مفید زیادی دارد.
برای مطالعه بخش بعدی این سری مقالات روی لینک زیر کلیک کنید:
سلام وقت بخیر. من یک المان رو با fixed شبیه به sticky کردم. چون sticky نبود داخل انتخاب های position . حالا اتفاقی که میوفته اینکه میره زیره فوتر سایت. چه پارامتریش رو تغییر بدم ک اسکرول از یجایی به بعد دیگه این المان رو با خودش نیاره؟ مرسی
از z index استفاده کن