Fix categories dock glass effect on production.

Portal the dock to body and move backdrop-filter off transformed/overflow-clipped ancestors so Chromium can render the glossy blur.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-09-23 15:53:42 +03:30
co-authored by Cursor
parent 36a3eef6fb
commit 99fa25e7f8
2 changed files with 40 additions and 19 deletions
+33 -17
View File
@@ -1,31 +1,47 @@
.categories-dock { .categories-dock {
position: fixed; position: fixed;
bottom: 18px; bottom: 18px;
left: 50%; left: 0;
transform: translateX(-50%); right: 0;
z-index: 80; z-index: 80;
width: min(var(--max-container), calc(100vw - 48px)); width: min(var(--max-container), calc(100vw - 48px));
margin-inline: auto;
padding: 14px 24px; padding: 14px 24px;
border-radius: 28px; border-radius: 28px;
border: 1px solid rgba(255, 255, 255, 0.7); background: transparent;
background: border: none;
linear-gradient( box-shadow: none;
165deg,
rgba(255, 255, 255, 0.72) 0%,
rgba(255, 247, 241, 0.55) 45%,
rgba(255, 255, 255, 0.4) 100%
);
backdrop-filter: blur(18px) saturate(160%);
-webkit-backdrop-filter: blur(18px) saturate(160%);
box-shadow:
0 10px 36px rgba(143, 65, 12, 0.14),
0 2px 8px rgba(0, 0, 0, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.85),
inset 0 -1px 0 rgba(143, 65, 12, 0.04);
pointer-events: auto; pointer-events: auto;
} }
/* Glass layer without transform — backdrop-filter breaks when combined
with transform / overflow-hidden ancestors in Chromium. */
.categories-dock__glass {
position: absolute;
inset: 0;
z-index: 0;
border-radius: inherit;
border: 1px solid rgba(255, 255, 255, 0.72);
background:
linear-gradient(
165deg,
rgba(255, 255, 255, 0.58) 0%,
rgba(255, 247, 241, 0.42) 45%,
rgba(255, 255, 255, 0.28) 100%
);
backdrop-filter: blur(20px) saturate(170%);
-webkit-backdrop-filter: blur(20px) saturate(170%);
box-shadow:
0 10px 36px rgba(143, 65, 12, 0.14),
0 2px 8px rgba(0, 0, 0, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.9),
inset 0 -1px 0 rgba(143, 65, 12, 0.05);
pointer-events: none;
}
.categories-dock__list { .categories-dock__list {
position: relative;
z-index: 1;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
+7 -2
View File
@@ -1,9 +1,12 @@
import { createPortal } from 'react-dom'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import './CategoriesDock.css' import './CategoriesDock.css'
/** /**
* Fixed glossy dock — images and labels are hardcoded. * Fixed glossy dock — images and labels are hardcoded.
* Slugs match production API categories on shirinibalout.com. * Slugs match production API categories on shirinibalout.com.
* Portaled to document.body so backdrop-filter is not killed by
* overflow-x: hidden / transform on .app ancestors.
*/ */
const DOCK_CATEGORIES = [ const DOCK_CATEGORIES = [
{ {
@@ -45,8 +48,9 @@ const DOCK_CATEGORIES = [
] as const ] as const
export default function CategoriesDock() { export default function CategoriesDock() {
return ( return createPortal(
<nav className="categories-dock" aria-label="دسته‌بندی محصولات"> <nav className="categories-dock" aria-label="دسته‌بندی محصولات">
<div className="categories-dock__glass" aria-hidden="true" />
<ul className="categories-dock__list"> <ul className="categories-dock__list">
{DOCK_CATEGORIES.map((category) => ( {DOCK_CATEGORIES.map((category) => (
<li key={category.slug} className="categories-dock__item"> <li key={category.slug} className="categories-dock__item">
@@ -65,6 +69,7 @@ export default function CategoriesDock() {
</li> </li>
))} ))}
</ul> </ul>
</nav> </nav>,
document.body,
) )
} }