ترازِ نمایش

هر کامپوننتِ شناورِ دیگ قبلاً یک عدد دستی داشت: z-50 روی popover، همان z-50 روی dialog، و کسی مطمئن نبود این اتفاقی است یا قرارداد. الان سه توکن‌اند، نه یک طیف.

چرا فقط سه لایه، نه یک عدد جدا برای هر کامپوننت

سایه چهار پله دارد، ولی اینجا عمداً «popover» و «modal» عددِ جدا نمی‌گیرند. دلیلش یک باگِ واقعی است: اگر Select عددی کوچک‌تر از Dialog داشته باشد، وقتی همان Select از داخل یک Dialog باز شود دقیقاً پشتِ همان Dialog قایم می‌شود، چون z-index یک استکینگ‌کانتکست تازه می‌سازد و از آن به بعد دیگر ترتیبِ DOM تصمیم نمی‌گیرد، عدد تصمیم می‌گیرد.

راه‌حلِ درست این نیست که عدد Select را دستی بالاتر ببریم. راه‌حل این است که هر چیزی که ممکن است از دلِ چیز دیگری باز شود — popover، dropdown، dialog، sheet، tooltip — در یک لایهٔ مشترک بماند و وقتی z-index مساوی است، ترتیبِ DOM (کدام portal دیرتر مونت شده) برنده را مشخص کند. توست تنها موردی است که باید همیشه بالای همه بماند، حتی بالای یک modal باز، پس تنها همان یک لایهٔ جداگانه و بزرگ‌تر می‌گیرد.

z-sticky10هدر چسبانِ جدول، پنل چسبانِ صفحه — بالای محتوا، زیر همه‌چیزِ شناور
z-overlay50هر چیز شناور: backdrop، dialog، sheet، drawer، popover، dropdown-menu، select، combobox، context-menu، menubar، tooltip، hover-card
z-toast100بالاترین لایه؛ باید حتی روی یک modal باز هم دیده شود

چیزهایی که اینجا توکن نگرفتند

یک z-10 محلی مثل حلقهٔ فوکوسِ یک اینپوت داخل InputGroup، یا جابه‌جاییِ Badge روی گوشهٔ Avatar، دربارهٔ رقابت با لایه‌های صفحه چیزی نمی‌گوید؛ فقط این المان را از خواهر و برادرِ بلافصلِ خودش بالاتر می‌برد. اسم‌گذاری این‌ها به‌عنوان لایهٔ سراسری باعث می‌شود توسعه‌دهنده فکر کند این عدد با toast یا dialog رقابت می‌کند، در حالی که اصلاً در همان استکینگ‌کانتکست نیست. این‌ها همچنان از عددِ خامِ Tailwind استفاده می‌کنند.

استفاده

برخلاف رنگ و سایه، یوتیلیتیِ z در Tailwind از فضای نامِ توکن گسترش پیدا نمی‌کند، پس کلاسِ خام z-overlay هیچ CSSای تولید نمی‌کند. متغیر را با سینتکسِ ولیوی دلخواه صدا بزنید:

Dialog.tsx
<div className="fixed z-(--z-overlay) ...">…</div>
app/globals.css
z-index: var(--z-toast);