tazzz.ru · frontend-agent · замер на бою 09.09.2026 · правки внесены и проверены 09.09.2026

Аудит позиционирования tazzz.ru

Вопрос был: «нужно полностью перейти к относительному позиционированию — это ведь исправит проблему?» Нет. Ни одно из найденных наложений не вызвано position:absolute. Все три — переполнение обычного потока (шапка шире колонки) и один плавающий элемент, под который не зарезервировано место. Сплошная замена на relative их не тронет, зато сломает модалки, выпадающие меню, бейджи на фото и липкую шапку.

Правки внесены точечно, четырьмя файлами, и перепроверены тем же инструментом: на 144 замерах (10 маршрутов × 14 ширин окна) не осталось ни переполнения шапки, ни наездов на неё, ни горизонтальной прокрутки. Что именно изменилось — в разделе «После правок».

119
употреблений absolute / fixed / sticky проверено в коде боевого фронта и админки
0
absolute-элементов без позиционированного родителя — самая частая причина «улетевших» блоков здесь отсутствует
3 → 0
наложения найдено на бою и исправлено; проверено повторным прогоном на сборке с правками

Где ломается: по ширине окна

Ширина в CSS-пикселях. Масштаб Windows 125 % превращает ноутбук 1366 px в окно 1093 px, а монитор 1920 px — в 1536 px; при 150 % это 911 и 1280 px. Именно поэтому жалоба звучит как «зависит от разрешения экрана».

Чат: шапка наезжает на панель «Из базы»/chat, панель открыта по умолчанию на десктопе
768 – 1616
Шапка шире окна на любой страницекнопка профиля обрезана, на /analytics — горизонтальная прокрутка
768 – 976
Лендинг: рейл разделов на карточках/, fixed right-5, показывается с 1024 px
1024 – 1207
Мобильная раскладкашапка без меню, нижняя навигация — вне этого аудита
< 768
768md
9111366 @150 %
1024lg
10931366 @125 %
12801920 @150 %
1366
15361920 @125 %
1920монитор

Границы измерены Playwright/Chromium на бою (гость) и с подменой API для закрытых страниц (логин «carletoajdavisrnc253» в шапке). Верхняя граница чата и шапки зависит от длины логина: цифры даны для этого логина, для гостя с надписью «Профиль» они на 95 px ниже.

Находки

Критично

1. В чате шапка сайта живёт внутри средней колонки и не помещается в неё

pages/ChatPage.tsx:59–140 · components/layout/TopBar.tsx:109–127 · components/search/InventoryDrawer.tsx:131–135 · store/chatStore.ts:179

Страница чата — это flex-ряд: слева история диалогов w-64 (256 px), справа панель «Из базы» шириной 384 px, и TopBar смонтирован внутри средней колонки. Панель открыта по умолчанию на любом экране от 768 px (defaultFeedOpen()), поэтому средней колонке достаётся «ширина окна минус 640 px».

Шапка же — сетка grid-cols-[1fr_auto_1fr], у которой средняя дорожка (шесть пунктов меню с подписями) имеет минимальную ширину контента 636 px, а вся шапка с логотипом и аккаунтом — 977 px. Сетка не умеет сжиматься ниже минимума контента, она переполняет контейнер вправо. У шапки z-30, у панели z-index нет — поэтому пункты меню рисуются поверх заголовка панели. Это и есть «блок справа залез на верхний бар».

Чат при ширине 911 px: пункты меню шапки поверх панели «Из базы»
911 × 683 (ноутбук 1366 при масштабе 150 %). Средняя колонка 271 px, шапка 977 px: «История», «Радар», «Сообщения» лежат на заголовке панели «Из базы», кнопка «Аналитика» и аккаунт уехали за край окна.
Чат при ширине 1366 px
1366 × 768 — самое частое разрешение ноутбуков без масштабирования. Колонка 726 px: шапке нужно 977 px, «Аналитика» обрезана краем панели, а аватар с логином нарисованы поверх заголовка «Из базы» и его счётчика.
ОкноКолонка чатаНужно шапкеНе хватаетЧто видно
800160977817документ 1233 px — горизонтальная прокрутка; меню и аккаунт целиком на панели и за окном
911271977706«История», «Радар», «Сообщения» на заголовке панели; «Аналитика» и аккаунт за окном
1024384977593«Радар», «Сообщения», «Аналитика» и аккаунт поверх панели; документ 1233 px
1093453977524«Сообщения», «Аналитика» и аккаунт поверх панели; документ 1233 px
1280640977337«Сообщения», «Аналитика» и аккаунт поверх панели
1366726977251«Аналитика» обрезана, аватар с логином поверх заголовка «Из базы»
153689697781логин заезжает на панель на 81 px
19201280977—помещается

Сделано

ChatPage.tsx обёрнут в flex h-[100svh] flex-col: шапка стоит первой строкой на всю ширину окна, под ней flex min-h-0 flex-1 с прежним рядом «история · чат · панель». Шапке теперь достаётся ширина окна, а не остаток. Кнопка-бургер из слота left работает как раньше, мобильная раскладка не изменилась.

Замер после правки: на всех восьми ширинах от 800 до 1920 px переполнение шапки равно нулю (было от 81 до 817 px).

Средне

2. Шапка шире окна при 768–976 px на всех страницах

components/layout/TopBar.tsx:114 (grid-cols-[1fr_auto_1fr]) · :145 (подписи с sm:) · :170 (логин без truncate)

Тот же механизм без чужих колонок: с 768 px в шапке появляется полное меню, но минимальная ширина её содержимого — 882 px для гостя и 977 px для этого логина. На лендинге корень overflow-x-hidden просто отрезает кнопку профиля; на /analytics, /search, /account и остальных страницах документ становится шире окна (замер: scrollWidth 882 при окне 768) и появляется горизонтальная прокрутка.

Логин в шапке не ограничен по ширине, поэтому граница плавает от пользователя к пользователю — ещё одна причина, почему проблема «то есть, то нет».

Лендинг при 800 px: кнопка профиля обрезана
800 × 600, гость: от кнопки «Профиль» осталась половина иконки.
Поиск при 911 px: логин обрезан
911 × 683, залогинен: логин «carletoajdavisrnc253» уходит за край, страница получает горизонтальную прокрутку.

Сделано

Подписи пунктов меню переведены на hidden lg:inline: между 768 и 1023 px меню иконочное (≈ 280 px вместо 636), название пункта переехало в title, так что при наведении оно видно. Логин ограничен max-w-[8rem] truncate — длинное имя больше не раздувает шапку и обрезается многоточием.

Замер после правки: на 768 и 800 px переполнение ушло (было 114 и 82 px у гостя, 177 px под логином), горизонтальной прокрутки на закрытых страницах нет.

Средне

3. Рейл разделов лендинга лежит на карточках при 1024–1207 px

components/landing/SectionRail.tsx:54 (fixed right-5 … hidden lg:flex) · SectionChips.tsx:49 (lg:hidden) · LandingView.tsx:76–77

Единственный случай, где виноват именно плавающий элемент — и то не потому, что он fixed, а потому, что под него не зарезервировано место. Рейл прижат к правому краю окна (right-5, ширина 32 px), а контент лендинга тянется до max-w-6xl (1152 px) с отступом 24 px. Пока окно уже 1208 px, правый край карточек заходит под овалы рейла; при наведении к ним ещё и выезжает подпись шириной до 330 px.

Лендинг при 1093 px: рейл разделов на карточке «страны импорта»
1093 × 614 (ноутбук 1366 при 125 %): активный красный овал рейла сидит на правой границе карточки «4 страны импорта», серые овалы — на карточках ниже.

Сделано

Рейл показывается с xl: (1280 px), лента чипов SectionChips живёт до xl:hidden. Замер после правки: на 768–1207 px рейла нет, вместо него чипы; на 1280 px левый край рейла — 1228 px, правый край карточек — 1192 px, то есть между ними 36 px зазора.

Низко

4. Панель «Из базы» открыта по умолчанию даже там, где чату остаётся меньше половины окна

store/chatStore.ts:179 (defaultFeedOpen: min-width 768px)

После исправления пункта 1 шапка с панелью не конфликтует, но при 1024 px чату оставалось бы 384 px — ширина телефона. Порог автораскрытия поднят до 1280 px: колонка панели по-прежнему существует с 768 px, просто закрытой, и открывается язычком.

Осталось на ваше решение. Открыть панель язычком можно и на 800 px — тогда чату достаётся 160 px, и читать его нельзя. Это поведение было и раньше; чтобы убрать и его, панель на 768–1279 px должна открываться поверх страницы (как на телефоне), а не раздвигать колонки. Это уже правка самой панели, я её не делал.

После правок

Изменены четыре файла. Прогон повторён на сборке с правками: те же маршруты, те же ширины окна, тот же инструмент. Проверка типов проходит.

ФайлЧто изменено
pages/ChatPage.tsxШапка вынесена из средней колонки в отдельную строку над всеми тремя колонками.
components/layout/TopBar.tsxПодписи пунктов меню с lg: вместо sm:, название пункта в title, логин ограничен 8rem с многоточием.
components/landing/SectionRail.tsx
components/landing/SectionChips.tsx
Рейл разделов показывается с 1280 px, лента чипов — до 1280 px.
store/chatStore.tsПанель «Из базы» раскрывается сама с 1280 px вместо 768 px.
Чат при 1366 px после правок: шапка во всю ширину, ничего не пересекается
Чат, 1366 × 768 — после. Шапка занимает всю ширину окна над тремя колонками, аватар с логином больше не лежит на заголовке «Из базы». Сравните со снимком в находке 1.
Лендинг при 1093 px после правок: рейла разделов нет, карточки чистые
Лендинг, 1093 × 614 — после. Овалов рейла на карточках нет: на этой ширине работает лента чипов под шапкой.
МаршрутОкноБылоСтало
/chat8008170
/chat9117060
/chat10245930
/chat10935240
/chat12803370
/chat13662510
/account8001770
/analytics8001770
/history8001770
/messages8001770
/radar8001770
/search8001770
/search/results8001770
/ (гость)7681140
/analytics (гость)7681140
/ (гость)800820
/analytics (гость)800820
/chat1536810
/account911660
/analytics911660
/history911660
/messages911660
/radar911660
/search911660
/search/results911660

Переполнение шапки в пикселях: ширина её содержимого минус ширина коробки, в которую она поставлена. Ноль означает, что содержимое помещается. Строки, где до правок переполнения не было, опущены.

Опись позиционирования: что оставить, что трогать

Просмотрены все 119 употреблений в frontend-agent/src и frontend-admin/src (то, что nginx на бою отдаёт с / и /admin/; frontend/ и frontend-v2/ на бой не попадают). У каждого absolute проверен ближайший позиционированный предок — он есть везде. Ниже группы по роли; «оставить» означает, что в обычном потоке эту вещь выразить нельзя.

РольШтукПримерыВердикт
Модалки и оверлеи: fixed inset-0 + карточка по центру, кнопки закрытия29CarModal:1135, CarModalHost:62/75, OrderModal:124, Sheet:147, CrossCountry*Modal, ComparePicker:110, AccountPage:667/889, CarrierTurnkeyBlock:53, dialog.tsx:18/39/45, кнопки закрытия AccountPage:675/897, OrderModal:135, Sheet:224, toast:71, CarModal:1170/1175, ApiDocsPage:1248/1338, admin ItemDrawer:45, admin ui:119оставить
Бейджи, кнопки и подложки на фото внутри relative-карточки37AgentCarCard:208–260, LandingCarCard:67–135, Gallery:124–150, AccountPage:251–428, UserPage:351, SimilarCard:28, ComparePicker:92, CarGrid:103, AlertCard:124, AnalyticsPage:300–304, CarRibbon:221, ListingMetricsPanel:333, bits:103, CompareTable:101оставить
Выпадающие меню и подсказки под полем/кнопкой10TopBar:173, AgentCarCard:347/352, SuggestInput:214, searchable-select:272, PlatformSelector:183, HomePage:315, SectionRail:67, admin Bell:45/46оставить
Иконка внутри поля ввода, галочка в select6SuggestInput:197, ConversationSidebar:40/55, UserPage:277, select:110, searchable-select:327, CrossCountryPickerModal:303оставить
Липкие панели: шапка, лента чипов, композер чата, шапки таблиц17TopBar:109, SectionChips:49, ChatPage:165, CompareTable:123, SearchFilters:446, ApiDocsPage:395/562, CarrierLayout:79, admin Layout:78, admin thead ×7, admin ui:127оставить
Плавающие элементы у края окна7SectionRail:54 · InventoryDrawer:144/168 · BottomTabBar:85 · toast.tsx:17 · CarrierLayout:106/113 · admin Layout:92/99SectionRail — исправить, остальные оставить
Всплывающие подсказки аналитики порталом в body по координатам курсора2bits.tsx:164, :223 (left зажат в 96…100vw−96)оставить
Декор: свечение, шиммер, фон-«сияние», кольцо у язычка, зона касания 44 px, бейджи непрочитанного10Composer:50/108, LandingView:286, index.css:60 (body::before), :205, :244 (.tap-44), :325 (.feed-glow), TopBar:140, BottomTabBar:117, admin Bell:38оставить
Блокировка прокрутки фона под модалкой (body{position:fixed})1lib/useBodyScrollLock.ts:25оставить
Не CSS: item_type: 'fixed', «sticky»-перевозчик в сторах51CarrierConfigurationDetailPage, api/carrier.ts, carrierOffersStore, marketCountryложные срабатывания grep

Отдельно проверено: в TopBar комментарий про backdrop-filter верен — он делает шапку containing block для fixed-потомков, поэтому оверлей меню аккаунта закрывается по клику снаружи через слушатель на document, а не через fixed inset-0. То же учтено в Sheet и CarrierTurnkeyBlock. Это правильные решения, менять их не нужно.

Матрица замеров

Для каждой пары «страница × окно»: ширина содержимого шапки против доступной ей ширины. Красным — переполнение (то, что видно как обрезанную кнопку, прокрутку или наезд). Закрытые страницы сняты с подменой API: данные пустые, геометрия оболочки честная.

Окно/ (гость)/analytics (гость)/chat/search/search/results/radar/history/account/messages/analytics
768882/768882/768————————
800882/800882/800977/160977/800977/800977/800977/800977/800977/800977/800
853882/853882/853————————
911✓✓977/271977/911977/911977/911977/911977/911977/911977/911
960✓✓————————
1000✓✓————————
1024рейл✓977/384✓✓✓✓✓✓✓
1093рейл✓977/453✓✓✓✓✓✓✓
1152рейл✓————————
1280✓✓977/640✓✓✓✓✓✓✓
1366✓✓977/726✓✓✓✓✓—✓
1440✓✓————————
1536✓✓977/896—✓✓—✓✓✓
1920✓✓✓✓✓✓✓✓✓✓

Что осталось за кадром

Что дальше