آیا تا به حال z-index: 99999 را روی یک عنصر در CSS خود تنظیم کرده اید و در بالای عناصر دیگر قرار نمی گیرد؟ یک مقدار بزرگ باید به راحتی آن عنصر را به صورت بصری بر روی هر چیز دیگری قرار دهد، با این فرض که همه عناصر مختلف در مقدار کمتری تنظیم شده اند یا اصلاً تنظیم نشده اند. یک صفحه وب معمولاً در یک فضای دو بعدی نمایش داده می شود. با این حال، با اعمال ویژگی های خاص CSS، یک صفحه فرضی محور z برای انتقال عمق معرفی می شود. این صفحه عمود بر صفحه است و کاربر از روی آن ترتیب عناصر را بر روی دیگری درک می کند. ایده پشت محور z خیالی، درک کاربر از عناصر پشتهای، این است که ویژگیهای CSS که آن را ایجاد میکنند، ترکیب میشوند تا چیزی را که ما آن را زمینه انباشتگی مینامیم، تشکیل دهند. ما قصد داریم در مورد نحوه "انباشته شدن" عناصر در یک صفحه وب، مواردی که ترتیب انباشتگی را کنترل می کند و رویکردهای عملی برای "بازکردن" عناصر در صورت نیاز صحبت کنیم. درباره انباشتن زمینه ها صفحه وب خود را به عنوان یک میز تحریر تصور کنید. همانطور که عناصر HTML را اضافه می کنید، تکه های کاغذ را یکی پس از دیگری روی میز می گذارید. آخرین تکه کاغذی که قرار داده شده معادل آخرین عنصر HTML اضافه شده است و روی تمام کاغذهای دیگر قرار می گیرد. این جریان عادی سند است، حتی برای عناصر تو در تو. میز خود نمایانگر زمینه انباشته ریشه است که توسط عنصر تشکیل شده است که شامل تمام پوشه های دیگر است. اکنون، ویژگی های خاص CSS وارد عمل می شوند. ویژگی هایی مانند موقعیت (با z-index)، opacity، transform و contain مانند یک پوشه عمل می کنند. این پوشه یک عنصر و همه فرزندان آن را می گیرد، آنها را از پشته اصلی استخراج می کند، و آنها را در یک زیر پشته جداگانه گروه بندی می کند و چیزی را ایجاد می کند که ما آن را زمینه انباشتگی می نامیم. برای عناصر موقعیتیافته، این زمانی اتفاق میافتد که یک مقدار z-index غیر از خودکار را اعلام کنیم. برای ویژگی هایی مانند کدورت، تبدیل، و فیلتر، پس از اعمال مقادیر خاص، زمینه انباشتگی به طور خودکار ایجاد می شود.
سعی کنید این را بفهمید: هنگامی که یک تکه کاغذ (به عنوان مثال، عنصر فرزند) در داخل یک پوشه قرار می گیرد (به عنوان مثال، زمینه انباشته شدن والدین)، هرگز نمی تواند از آن پوشه خارج شود یا بین کاغذهای یک پوشه دیگر قرار گیرد. z-index آن اکنون فقط در داخل پوشه خودش مربوط است.
در تصویر زیر، کاغذ B اکنون در زمینه انباشته شدن پوشه B قرار دارد و فقط با سایر کاغذهای موجود در پوشه قابل سفارش است.
تصور کنید، اگر بخواهید، دو پوشه روی میز خود دارید:
.folder-a { z-index: 1; } .folder-b { z-index: 2; }
بیایید نشانه گذاری را کمی به روز کنیم. داخل پوشه A یک صفحه خاص است، z-index: 9999. داخل پوشه B یک صفحه ساده است، z-index: 5.
.special-page { z-index: 9999; } .plain-page { z-index: 5; }
کدام صفحه بالای صفحه است؟ این صفحه .plain در پوشه B است. مرورگر کاغذهای فرزند را نادیده می گیرد و ابتدا دو پوشه را روی هم می چیند. پوشه B را می بیند (z-index: 2) و آن را در بالای پوشه A قرار می دهد (z-index: 1) زیرا می دانیم که دو بزرگتر از یک است. در همین حال، صفحه ویژهای که روی z-index: 9999 تنظیم شده است، در انتهای پشته قرار دارد، حتی اگر z-index آن روی بالاترین مقدار ممکن تنظیم شده باشد. زمینههای انباشته نیز میتوانند تودرتو شوند (پوشهها در داخل پوشهها) و یک «درخت خانواده» ایجاد میکنند. همین اصل صادق است: یک کودک هرگز نمی تواند از پوشه والدین خود فرار کند. اکنون که متوجه شدید که چگونه زمینههای انباشته مانند پوشههایی که لایهها را گروهبندی و مرتب میکنند، رفتار میکنند، ارزش این را دارد که بپرسید: چرا ویژگیهای خاصی - مانند تبدیل و کدورت - زمینههای انباشته جدیدی ایجاد میکنند؟ نکته اینجاست: این ویژگی ها به دلیل ظاهرشان زمینه های انباشته ایجاد نمی کنند. آنها این کار را به دلیل نحوه عملکرد مرورگر در زیر کاپوت انجام می دهند. وقتی تبدیل، کدورت، فیلتر یا پرسپکتیو را اعمال میکنید، به مرورگر میگویید: «سلام، این عنصر ممکن است حرکت کند، بچرخد یا محو شود، پس آماده باشید!»
هنگامی که از این ویژگی ها استفاده می کنید، مرورگر یک زمینه انباشته جدید برای مدیریت کارآمدتر رندر ایجاد می کند. این به مرورگر اجازه می دهد تا انیمیشن ها، تبدیل ها و جلوه های بصری را به طور مستقل مدیریت کند و نیاز به محاسبه مجدد نحوه تعامل این عناصر با بقیه صفحه را کاهش می دهد. به این فکر کنید که مرورگر میگوید: «من این پوشه را جداگانه مدیریت میکنم تا مجبور نباشم هر بار که چیزی در داخل آن تغییر میکند کل میز را تغییر دهم.» اما وجود داردیک عارضه جانبی هنگامی که مرورگر یک عنصر را به لایه خود برد، باید همه چیز را در آن "مسطح" کند و یک زمینه انباشته جدید ایجاد کند. این مانند برداشتن یک پوشه از روی میز است تا آن را به طور جداگانه مدیریت کنید. همه چیز در داخل آن پوشه گروه بندی می شود و مرورگر اکنون با آن به عنوان یک واحد در هنگام تصمیم گیری در مورد اینکه چه چیزی در بالای پوشه قرار می گیرد، رفتار می کند. بنابراین، اگرچه به نظر میرسد که ویژگیهای تبدیل و کدورت روی روشی که عناصر بهصورت بصری روی هم قرار میگیرند، تأثیر نمیگذارند، تأثیری دارند، و این برای بهینهسازی عملکرد است. چندین ویژگی دیگر CSS نیز می توانند به دلایل مشابه زمینه های انباشته ایجاد کنند. اگر میخواهید عمیقتر شوید، MDN فهرست کاملی را ارائه میکند. تعداد کمی وجود دارد، که فقط نشان می دهد که چقدر آسان است که به طور ناخواسته یک زمینه انباشته بدون دانستن آن ایجاد کنید. مشکل "باز کردن انباشته". مشکلات انباشته شدن می تواند به دلایل زیادی ایجاد شود، اما برخی از آنها شایع تر از دیگران هستند. مولفههای مدال یک الگوی کلاسیک هستند، زیرا نیاز دارند که مولفه را روی لایه بالایی بالاتر از همه عناصر دیگر "باز" کنید، سپس وقتی "بسته شد" آن را از لایه بالایی جدا کنید. من کاملاً مطمئن هستم که همه ما در موقعیتی قرار گرفته ایم که یک مودال را باز می کنیم و به هر دلیلی ظاهر نمی شود. این به این معنا نیست که به درستی باز نشده است، بلکه در لایه پایینتری از زمینه انباشتگی خارج از دید است. این شما را به تعجب وا می دارد که "چطور؟" از زمانی که تنظیم کردید:
.پوشش { موقعیت: ثابت؛ /* زمینه انباشتگی را ایجاد می کند */ z-index: 1; /* عنصر را روی یک لایه بالاتر از هر چیز دیگری قرار می دهد */ ورودی: 0; عرض: 100%؛ ارتفاع: 100vh; سرریز: پنهان; پس زمینه رنگ: #00000080; }
این درست به نظر می رسد، اما اگر عنصر والد حاوی تریگر مودال یک عنصر فرزند در عنصر والد دیگری باشد که روی z-index: 1 نیز تنظیم شده است، از نظر فنی مودال را در زیرلایه ای قرار می دهد که توسط پوشه اصلی مبهم است. بیایید به آن سناریوی خاص و چند دام رایج دیگر در زمینه انباشتگی نگاه کنیم. من فکر می کنم شما نه تنها خواهید دید که ایجاد سهواً زمینه های انباشته چقدر آسان است، بلکه نحوه مدیریت نادرست آنها را نیز خواهید دید. همچنین نحوه بازگشت شما به حالت مدیریت شده بستگی به شرایط دارد. سناریو 1: مدال به دام افتاده
میتوانید فوراً مدال خود را در یک لایه سطح پایین به دام افتاده ببینید و والد را شناسایی کنید. برنامه های افزودنی مرورگر توسعه دهندگان هوشمند افزونه هایی برای کمک ساخته اند. ابزارهایی مانند این برنامه افزودنی Chrome "CSS Stacking Context Inspector" یک برگه z-index اضافی به DevTools شما اضافه می کنند تا اطلاعاتی را درباره عناصری که یک زمینه انباشتگی ایجاد می کنند به شما نشان دهد.
برنامه های افزودنی IDE حتی میتوانید مشکلات را در حین توسعه با افزونهای مانند این برای VS Code تشخیص دهید، که مشکلات احتمالی زمینه انباشتگی را مستقیماً در ویرایشگر شما برجسته میکند.
برداشتن و بازیابی کنترل بعد از اینکه علت اصلی را شناسایی کردیم، گام بعدی مقابله با آن است. چندین روش وجود دارد که می توانید برای مقابله با این مشکل استفاده کنید، و من آنها را به ترتیب فهرست می کنم. شما می توانید هر کسی را در هر سطحی انتخاب کنید. هیچ کس نمی تواند شکایت کند یا مانع دیگری شود. تغییر ساختار HTML این راه حل بهینه در نظر گرفته می شود. برای اینکه شما با یک مشکل زمینه انباشتگی مواجه شوید، باید برخی از عناصر را در موقعیت های خنده دار در HTML خود قرار داده باشید. تغییر ساختار صفحه به شما کمک می کند DOM را تغییر شکل دهید و مشکل زمینه انباشتگی را از بین ببرید. عنصر مشکل ساز را پیدا کنید و آن را از عنصر تله در نشانه گذاری HTML حذف کنید. به عنوان مثال، ما میتوانیم اولین سناریو، "The Trapped Modal" را با خارج کردن .modal-container از هدر و قرار دادن آن در عنصر
به تنهایی حل کنیم.این محتوا دارای z-index 2 است و همچنان حالت مدال را پوشش نمیدهد.سرصفحه
محتوای اصلی
هنگامی که روی دکمه "Open Modal" کلیک می کنید، مدال در مقابل هر چیز دیگری همانطور که قرار است باشد قرار می گیرد. به سناریوی قلم 1 مراجعه کنید: مدال به دام افتاده (راه حل) [چنگال شده] توسط Shoyombo Gabriel Ayomide. تنظیم کنیدانباشتن زمینه والدین در CSS اگر عنصر عنصری باشد که نمیتوانید بدون شکستن طرح حرکت کنید، چه؟ بهتر است به این موضوع بپردازیم: والدین زمینه را تعیین می کنند. ویژگی CSS (یا خصوصیات) را که مسئول ایجاد زمینه است پیدا کنید و آن را حذف کنید. اگر هدفی دارد و نمیتوان آن را حذف کرد، برای بلند کردن کل ظرف، مقدار z-index بالاتری نسبت به عناصر برادرش به والدین بدهید. با مقدار z-index بالاتر، ظرف والد به سمت بالا حرکت میکند و فرزندان آن نزدیکتر به کاربر ظاهر میشوند. بر اساس آنچه در سناریوی "The Submerged Dropdown" یاد گرفتیم، نمیتوانیم کشویی را از نوار ناوبری خارج کنیم. منطقی نخواهد بود با این حال، میتوانیم مقدار z-index ظرف .navbar را بیشتر از مقدار z-index عنصر .content افزایش دهیم. .navbar { پس زمینه: #333; /* z-index: 1; */ z-index: 3; موقعیت: نسبی; }
با این تغییر، اکنون منوی کشویی بدون هیچ مشکلی در جلوی محتوا ظاهر می شود.
سناریو 2 قلم را ببینید: کشویی غوطه ور (راه حل) [فورک شده] توسط شویمبو گابریل آیومید.
در صورت استفاده از یک چارچوب، پورتال ها را امتحان کنید
در فریمورکهایی مانند React یا Vue، Portal ویژگیای است که به شما امکان میدهد یک مؤلفه را خارج از سلسله مراتب والد معمولی آن در DOM ارائه دهید. پورتال ها مانند یک دستگاه انتقال از راه دور برای قطعات شما هستند. آنها به شما امکان می دهند HTML یک مؤلفه را در هر نقطه از سند (معمولاً مستقیماً در document.body) ارائه دهید و در عین حال آن را به طور منطقی به والد اصلی خود برای موارد، حالت و رویدادها متصل نگه دارید. این برای فرار از تله های زمینه انباشته عالی است زیرا خروجی رندر شده به معنای واقعی کلمه خارج از ظرف اصلی مشکل ساز ظاهر می شود.
ReactDOM.createPortal(
این تضمین میکند که محتوای کرکرهای شما پشت والد خود پنهان نمیشود، حتی اگر والد سرریز داشته باشد: پنهان یا z-index کمتر. در سناریوی "The Clipped Tooltip" که قبلا به آن نگاه کردیم، من از یک پورتال برای نجات راهنمای ابزار از سرریز استفاده کردم: کلیپ پنهان با قرار دادن آن در بدنه سند و قرار دادن آن در بالای ماشه در ظرف. سناریو 3 قلم را ببینید: نکته ابزار بریده شده (راه حل) [چنگال شده] توسط Shoyombo Gabriel Ayomide. معرفی زمینه انباشته شدن بدون عوارض جانبی تمام رویکردهایی که در بخش قبل توضیح داده شد با هدف "باز کردن انباشته" عناصر از زمینه های انباشته مشکل ساز هستند، اما شرایطی وجود دارد که شما واقعاً نیاز دارید یا می خواهید یک زمینه انباشته ایجاد کنید. ایجاد یک زمینه انباشته جدید آسان است، اما همه رویکردها با یک اثر جانبی همراه هستند. یعنی به جز استفاده از ایزوله: ایزوله. هنگامی که به یک عنصر اعمال می شود، زمینه انباشته فرزندان آن عنصر نسبت به هر کودک و در آن زمینه تعیین می شود، نه اینکه تحت تأثیر عناصر خارج از آن قرار گیرد. یک مثال کلاسیک اختصاص دادن یک مقدار منفی به آن عنصر است، مانند z-index: -1. تصور کنید که یک جزء .card دارید. میخواهید یک شکل تزئینی اضافه کنید که در پشت متن کارت، اما بالای پسزمینه کارت قرار گیرد. بدون یک زمینه انباشته روی کارت، z-index: -1 شکل را به پایین زمینه انباشتگی ریشه (کل صفحه) می فرستد. این باعث می شود آن را در پشت پس زمینه سفید کارت. به Pen Negative z-index (مشکل) [فشار شده] توسط Shoyombo Gabriel Ayomide مراجعه کنید. برای حل این مشکل، انزوا را اعلام می کنیم: isolate در .card والد: به Pen Negative z-index (راه حل) [فورک شده] توسط Shoyombo Gabriel Ayomide مراجعه کنید. اکنون، عنصر .card خود به یک زمینه انباشته تبدیل می شود. وقتی عنصر فرزند آن - شکل تزئینی ایجاد شده بر روی عنصر :before شبه - دارای z-index: -1 باشد، به انتهای بافت انباشته والد می رود. همانطور که در نظر گرفته شده است کاملاً در پشت متن و بالای پس زمینه کارت قرار می گیرد. نتیجه گیری به یاد داشته باشید: دفعه بعد که z-index شما خارج از کنترل به نظر می رسد، یک زمینه انباشته به دام افتاده است. مراجع
زمینه انباشته (MDN) Z-index و زمینه های انباشته (web.dev) ناتالی پینا: «نحوه ایجاد یک زمینه Stacking جدید با ویژگی Isolation در CSS» "What The Heck، z-index?"، جاش کومئو
مطالعه بیشتر در SmashingMag
"مدیریت CSS Z-Index در پروژه های بزرگ"، استیون فریسون «هدرهای چسبنده و عناصر تمام قد: ترکیبی دشوار»، فیلیپ براونن «مدیریت Z-Index در یک برنامه وب مبتنی بر مؤلفه»، پاول پومرانتسف "ویژگی Z-Index CSS: نگاهی جامع"، لوئیس لازاریس