You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _documentation/600-Frontend/200-Styling.md
+32Lines changed: 32 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -227,6 +227,37 @@ Do not use `:global()` in Svelte components for rules that apply across componen
227
227
228
228
---
229
229
230
+
## Z-Index and Stacking
231
+
232
+
**Avoid ad-hoc `z-index`.** In a component ecosystem where you cannot predict how components nest into each other, hand-rolled stacking values are brittle — they break down as soon as two popovers or tooltips are open at the same time, or a modal must open from inside a tooltip while the popover behind it stays visible. A global token ladder (`--z-popover: 600`, `--z-modal: 800`, …) looks tidy until components combine in ways the ladder didn't anticipate, at which point every fix requires raising numbers and introducing exceptions.
233
+
234
+
**The real fix for overlay components is portals.** Components like `Dialog`, `BottomSheet`, and `Popover` teleport their DOM to a root-level container (typically `<body>`), placing the rendered node completely outside any ancestor stacking context that would otherwise trap it. This is why simply moving a component tag to the end of the Svelte template is often enough — the teleported node lands at the end of the portal target, not because of local sibling order, but because it escapes the subtree entirely.
235
+
236
+
```svelte
237
+
<!-- ✗ Don't roll your own overlay with position: fixed + z-index -->
<!-- ✓ Use a component that portals its DOM — stacking context is no longer your problem -->
241
+
<Dialog bind:open={dialogOpen} />
242
+
```
243
+
244
+
Note that portaled components may carry a `z-index` value internally — that is the library's concern, not yours. What you must avoid is adding `z-index` in your own component code to patch a stacking problem.
245
+
246
+
**DOM ordering is a secondary technique**, valid only when elements share the same stacking context and no ancestor breaks it. Many CSS properties create a new stacking context (`transform`, `opacity < 1`, `filter`, `isolation: isolate`, positioned `z-index`) — once a new stacking context exists, later siblings outside it cannot paint over elements inside it regardless of order. Do not rely on DOM ordering alone for overlay elements.
247
+
248
+
Only introduce `z-index` as a genuine last resort, and only with a component-local token so the value is visible and scoped:
249
+
250
+
```css
251
+
.my-component {
252
+
--my-component-z: 1; /* document why 1 and what it sits above */
253
+
z-index: var(--my-component-z);
254
+
}
255
+
```
256
+
257
+
Never use bare numeric `z-index` values or a global `--z-*` token ladder.
258
+
259
+
---
260
+
230
261
## Rules
231
262
232
263
-**No `!important`** — ever. Cascade layers make it unnecessary.
@@ -235,4 +266,5 @@ Do not use `:global()` in Svelte components for rules that apply across componen
235
266
-**States reassign component-local tokens**, not global ones. Because the browser re-evaluates every property referencing the token automatically, one reassignment line replaces what would otherwise be repeated property declarations in every state rule.
236
267
-**No utility-class spam** — if a pattern repeats across 3+ components, extract a shared Svelte primitive, not a utility class.
237
268
-**Dark mode is free** — do not add `[data-theme="dark"]` rules inside component styles. The token layer handles it globally.
269
+
-**No ad-hoc `z-index`** — use portaled overlay components instead of rolling `position: fixed` + `z-index`. DOM ordering is only a secondary aid within a shared stacking context. See [Z-Index and Stacking](#z-index-and-stacking) for the full rationale and the allowed exception form.
238
270
-**Do not add new rules to `public/css/`** — those files belong to the legacy layer and are being phased out. New styles must use the token system described above.
0 commit comments