added blur on topBar

This commit is contained in:
SlimusMinus
2026-09-09 23:42:03 +03:00
parent 800cb8233a
commit 4021840429
6 changed files with 847 additions and 642 deletions

View File

@@ -1,3 +1,17 @@
/* ─────────────────────────────────────────────────────────────────────
СТЕКЛЯННАЯ ШАПКА + ЗАТУХАНИЕ ЛЕНТЫ (Telegram Web style)
─────────────────────────────────────────────────────────────────────
Регистрация кастомного свойства: именно благодаря @property смена
--feed-fade-height анимируется transition'ом. В браузерах без поддержки
@property значение просто меняется мгновенно (graceful degradation).
*/
@property --feed-fade-height {
syntax: '<length>';
inherits: false;
initial-value: 48px;
}
/* ── App Shell (Instagram-style) ── */
.f-app {
display: flex; height: 100vh; height: 100dvh;
@@ -19,17 +33,46 @@
}
/* ── Topbar (telegram-style; mobile only; desktop uses the nav sidebar) ──
Фон отсутствует полностью: стеклянными выглядят только сами кнопки. */
«Стекло»: полупрозрачный фон темы + мягкий blur по содержимому под шапкой.
blur/saturate явно умеренные — сильно агрессивное размытие даёт
пересвеченное «стекло» (blur 12px + saturate ~135%). */
.f-topbar {
position: sticky;
top: 0;
z-index: 100;
z-index: 10;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 8px 12px;
padding-top: calc(8px + env(safe-area-inset-top));
/* Без backdrop-filter: blur имеет жёсткую границу по кромке прямоугольника,
которую маской не убрать. Плавность даёт только сквозной альфа-градиент,
сходящийся к 0 уже к низу бара. */
background: linear-gradient(
to bottom,
rgba(var(--bg-rgb), 0.14) 0%,
rgba(var(--bg-rgb), 0.07) 55%,
rgba(var(--bg-rgb), 0.05) 100%
);
transition: transform 0.25s ease, background-color 0.25s ease;
}
/* Продолжение того же сквозного градиента ниже бара: цвет уходит в 0,
резкой границы нет, «плашки» не видно вообще. */
.f-topbar::after {
content: "";
position: absolute;
left: 0;
right: 0;
top: 100%;
height: 64px;
pointer-events: none;
background: linear-gradient(
to bottom,
rgba(var(--bg-rgb), 0.05) 0%,
rgba(var(--bg-rgb), 0) 100%
);
}
/* Кнопка-логотип по центру: wordmark «Находка» в округлой стеклянной капсуле */
@@ -206,18 +249,22 @@
.f-topbar-dropdown-wrap {
position: relative;
}
/* В ленте шапка липнет к верху скроллера: контент прокручивается под ней
и «замыливается» через backdrop-filter на .f-topbar */
.f-feed > .f-topbar-dropdown-wrap {
position: sticky;
top: 0;
z-index: 100;
margin: -20px -16px 0;
.f-topbar-dropdown-wrap .f-topbar.f-topbar-hidden {
/* Плавное скрытие шапки при скролле вниз (translateY вверх, за кромку .f-feed).
Висим на самом .f-topbar, а НЕ на обёртке: transform на обёртке создал бы
containing block для position:fixed оверлея дропдауна и сломал бы клик вне. */
transform: translateY(-100%);
}
@media (max-width: 900px) {
.f-feed > .f-topbar-dropdown-wrap {
margin: -10px -10px 0;
}
/* В ленте шапка лежит ПОВЕРХ маскированного скролл-контейнера (.f-feed-scroll):
по z-index она выше «слоя затухания», но ниже, чем сам контент не бывает
никогда — жёстко прижата к верху .f-feed. */
.f-feed > .f-topbar-dropdown-wrap {
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 10;
margin: 0;
}
.f-topbar-dropdown-overlay {
@@ -577,14 +624,45 @@
/* ── Feed Wrap + Scroll ── */
.f-wrap { display: flex; flex: 1; overflow: hidden; min-height: 0; }
/* Внешний контейнер ленты: не скроллится, лишь позиционирует слои.
Сверху — стеклянная шапка (абсолютный слой), под ней — маскированный
скролл-список; такой порядок даёт нужную иерархию z-index. */
.f-feed {
flex: 1; overflow-y: scroll; overflow-x: hidden; overscroll-behavior: contain; min-height: 0;
padding: 20px 16px; display: flex; flex-direction: column; gap: 16px;
width: 100%; max-width: 660px; margin: 0 auto;
position: relative;
overflow: hidden;
flex: 1;
min-height: 0;
width: 100%;
max-width: 660px;
margin: 0 auto;
}
.f-feed::-webkit-scrollbar { width: 4px; }
.f-feed::-webkit-scrollbar-track { background: transparent; }
.f-feed::-webkit-scrollbar-thumb { background: var(--muted2); border-radius: 2px; }
/* ── Слой затухания ленты ──
mask-image на самом контейнере списка (НЕ blur, НЕ opacity карточек):
верхние элементы, доезжающие до кромки под FeedTopBar, «растворяются».
Маска якорена к border-box скролл-контейнера, т.е. НЕ уезжает вместе
с карточками — зона затухания всегда под шапкой. Высота зоны задаётся
--feed-fade-height (управляется из React/ResizeObserver) и через
@property + transition анимируется при изменении.
padding-top синхронизирован с этой же переменной, чтобы первая карточка
в состоянии покоя не проваливалась под шапку. */
.f-feed-scroll {
position: absolute;
inset: 0;
overflow-y: scroll;
overflow-x: hidden;
overscroll-behavior: contain;
display: flex;
flex-direction: column;
gap: 16px;
padding: calc(var(--feed-fade-height, 48px) + 20px) 16px 20px;
-webkit-mask-image: linear-gradient(to bottom, transparent 0, black var(--feed-fade-height, 48px));
mask-image: linear-gradient(to bottom, transparent 0, black var(--feed-fade-height, 48px));
transition: --feed-fade-height 0.2s ease;
}
.f-feed-scroll::-webkit-scrollbar { width: 4px; }
.f-feed-scroll::-webkit-scrollbar-track { background: transparent; }
.f-feed-scroll::-webkit-scrollbar-thumb { background: var(--muted2); border-radius: 2px; }
@media (min-width: 900px) {
.f-main-feed .f-topbar {
@@ -611,8 +689,8 @@
bottom: calc(84px + env(safe-area-inset-bottom));
}
.f-feed {
padding: 10px;
.f-feed-scroll {
padding: calc(var(--feed-fade-height, 48px) + 10px) 10px calc(150px + env(safe-area-inset-bottom));
gap: 12px;
}
@@ -645,11 +723,6 @@
margin-top: 4px; border-radius: 999px;
}
.f-topbar-dropdown-item { padding: 7px 13px; font-size: 0.8rem; }
/* Нижняя панель fixed — освобождаем место в конце ленты */
.f-feed {
padding-bottom: calc(150px + env(safe-area-inset-bottom));
}
}
@media (max-width: 600px) {