دو مفهوم Stacking context و Layers در فرآیند تبدیل کدهای ما به صفحات وب در مرورگر معنا پیدا میکنند. این دو مفهوم خیلی شبیه هم هستند و حتی بعضی جاها اشتباها به جای هم به کار میرن اما تفاوت دارند. دونستن این تفاوت بهمون کمک میکنه که CSS ای بنویسیم که به سایت با کیفیتتری منتج بشه!
از اونجایی که گفتم فرآیند تبدیل کد ما به صفحات وب، لازمه تا یک بار این فرآیند رو مرور کنیم و اختصارا بگیم که این دو مفهوم در کدوم لایه از این فرآیند خودشون رو نشون میدن.
وقتی یه صفحه وب رو باز میکنید، مرورگر چند مرحله اصلی رو طی میکنه تا کدهای شما رو به یه صفحه قابل مشاهده تبدیل کنه:

وقتی مرورگر کدهای HTML شما رو میخونه، یه ساختار درختی به نام DOM میسازه. این درخت شامل تمام المانهای HTML صفحه شما میشه، از <html> تا آخرین <div> یا <span>. هر المان یه node در این درخت محسوب میشه.
همزمان با ساخت DOM، مرورگر کدهای CSS رو هم پردازش میکنه و یه ساختار درختی دیگه به نام CSSDOM میسازه. این درخت شامل تمام استایلها و قوانین CSS میشه که مشخص میکنه هر المان چجوری باید نمایش داده بشه.
بعد از ساخت DOM و CSSDOM، مرورگر این دو درخت رو با هم ترکیب میکنه و یه درخت رندر ایجاد میکنه. این درخت فقط شامل المانهایی میشه که قابل نمایش هستند (مثلا المانهای با display: none در این درخت وجود ندارند).
در این مرحله، مرورگر موقعیت و اندازه دقیق هر المان رو در صفحه محاسبه میکنه. این فرآیند به عنوان reflow یا layout شناخته میشه. مرورگر از اطلاعات درخت رندر استفاده میکنه تا بفهمه هر المان کجا باید قرار بگیره و چقدر فضا اشغال کنه.
بعد از اینکه موقعیت و اندازه المانها مشخص شد، مرورگر شروع میکنه به رنگآمیزی یا paint کردن المانها. در این مرحله، رنگها، تصاویر، متنها و سایر ویژگیهای بصری روی صفحه کشیده میشن.
در مرحله آخر، مرورگر لایههای مختلف رو با هم ترکیب میکنه تا صفحه نهایی رو نمایش بده.
توصیه میکنم یه بار به این مقاله در وبسایت کروم مراجعه کنید. چون داخلش این فرآیند رو به شکل تصویری خیلی خوب نشون داده.
از بین مراحل فوق، همگی به جز Compostion کاملا در CPU انجام می شوند.
امور مربوط به ایجاد Stacking Context در بخش Paint رخ میدهد. (جلوتر میرسیم)
امور مربوط به Layers (جلوتر میرسیم که چی هستن) در بخش Composition رخ می دهد. (عمدتا در GPU)
زمانبر ترین بخش این فرآیندها، بخش Layout یا Reflow است، چون باید x,y یک المان یا مختصاتش رو CPU دربیاره و برای این فرآیند باید تمام المانهای توی صفحه رو درنظر بگیره.
ذکر این نکته هم لازمه که، چنانچه سیستمی GPU نداشته باشه (که دیگه اینروزا خیلی بعیده) قضیه hand-off میشه به همون CPU مون!
بنابراین اگر حرکاتی(!) بزنیم که Reflow رخ نده، میتونیم انتظار سرعت و عملکرد بهتری در وبسایتمون داشته باشیم. منظورمون از حرکات هم صرفا تغییر css مونه.
البته Reflow لازم و ضروریه اما یه وقتهایی واسه یه چیز بیخودی و دائما در حال انجام (مثل انیمیشنها) ما اشتباها موجبات Reflow رو فراهم میکنیم (در حالیکه میتونیم نکنیم) و اینجوری سایتمون کند میشه و بعضا هنگ میکنه.
اگر بخوایم براش یه لیست درست کنیم، قطعا به خاطر نمیشه سپرد و اصلا کار جالبی هم نیست!
فقط کافیه این rule of thumb رو بخاطر بسپارید:
هر تغییر CSS ای که ابعاد و موقعیت x,y یک المان و همسایههاش رو عوض نکنه، موجب reflow نمیشه.
خب دیگه خودتون می تونید یه لیست درست کنید، کارهایی مثل تغییر color و background و opacity تنها نمونههایی از این لیست هستند.
یه انیمیشن ساده رو با دو روش زیر انجام بدیم یکی با مارجین یکی با ترنسفورم. اولی یه nightmare برای مرورگره و دومی یه چیزه خیلی سریع و مناسب.
روش اول: استفاده از margin (دردسرساز!)
<div class="container"> <div class="box bad-animation">Animation with margin</div> </div>
.box { width: 100px; height: 100px; background: blue; margin-top: 10px; } .bad-animation:hover { margin-top: 110px; /* This cause reflow! */ transition: margin-top 0.3s ease; }
روش دوم: استفاده از transform (بهینه!)
<div class="container"> <div class="box good-animation">Animation with transform</div> </div>
.box { width: 100px; height: 100px; background: green; margin-top: 10px; } .good-animation:hover { transform: translateY(100px); /* This isn't cause reflow! */ transition: transform 0.3s ease; }
توضیح:
در روش اول، با تغییر margin-top، مرورگر مجبور هست تمام المانهای بعدی رو مجددا محاسبه کنه (reflow)
در روش دوم، transform فقط المان رو در Stacking context جداگانهای حرکت میده و نیازی به محاسبه مجدد موقعیت سایر المانها نداره
فرض کنید یه فایل HTML مانند فایل زیر دارید. تمامی المنتها در این فایل، در normal flow زیست می کنند.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Simple HTML Page</title> </head> <body> <h1>Hello, World!</h1> <p>This is a simple HTML page with no styles or JavaScript.</p> </body> </html>
مفهوم normal flow در مرورگر: یعنی المان های از نوع block در زیر هم به صورت عمودی قرار می گیرند و المان های از نوع inline به صورت افقی در کنار هم. تصویر زیر:
تمام المنتهایی که در HTML داریم مثل
div,p,a,article, و غیره همگی به طور پیشفرض براساس normal flow توسط مرورگر چیده میشوند، مگر اینکه با Stacking Context آنها رو از normal flow خارج کنیم!
اگر با واژه stack آشنا نیستید باید بگم، stack مشابه طبقات یک کیک است که روی هم قرار میگیرند و وقتی میخواهیم کیک بخوریم قاعدتا اون طبقه بالایی رو اول برمیداریم. به عبارت دیگر آخرین (روترین) لایه روی کیک، اولین لایهای است که باید برداریم. (لطفا تصورش کنید!)
حالا Stacking Context در مرورگر طبق تعریف سایت MDN میشود:
اگر ساختار چینش المان ها در صفحه HTML را در یک صفحه سه بعدی در نظر بگیریم، به محور Z و نحوه قرارگیری المان ها در آن stacking context می گویند.
هر کدام از element های زیر میتوانند منجر به ایجاد stacking context جدید شوند:
المنت (<html>)
المنتی با مقدار position برابر absolute یا relative و مقدار z-index غیر از auto
المنتی با مقدار position برابر fixed یا sticky
المنتی با مقدار container-type برابر size یا inline-size
المنتی که یک flex item است با مقدار z-index غیر از auto
المنتی که یک grid item است با مقدار z-index غیر از auto
المنتی با مقدار opacity کمتر از 1
المنتی با مقدار mix-blend-mode غیر از normal
المنتی با هر یک از خواص زیر با مقداری غیر از none:
transform (مثالی که بالاتر زده بودیم مثلا همین رو فقط داشت)
scale
rotate
translate
filter
backdrop-filter
perspective
clip-path
mask / mask-image / mask-border
مشاهده کامل مقاله در
https://farshidev.ir/Post/layers-and-stacking-context
موفق باشید.