Вкладки товару
У файлі про вкладки лежать три різні фігури: липка полиця .pdp-tabs (два кольорові екрани), рядок чипів .ptabs на головній (чотири екрани) і двоколонкова сітка сторінки товару .pdp (три екрани). Вирішувач знайшов тут 30 мертвих оголошень - третій показник шару зі 193. Три з них це top, і жодне з трьох ніколи не діє.
Полиця складає рівно одне - ціну: price.css дає .told, .tnew і .uiv-cur, discount.css - .tcut і .ttier. Усередині кореня немає жодного класу з двома власниками, а таких імен у шарі 126.
| Файл | Класів | Які саме |
|---|---|---|
price.css | 1 | .uiv-cur |
discount.css | 1 | .ttier |
Розмітка тут - не переписана від руки. Її знято з design/product.html у цій же сесії, обробники зняті, посилання підняті на рівень. Корінь тут fixed або sticky і в продукті видимий, тож open йому не додавали. Сцена потрібна тільки щоб він лишався всередині свого демо.
Показано в рамці шириною 1180, і ширина названа не для краси: це ширина, на якій цей організм у продукті стоїть. Медіа-умова читає в'юпорт, а не контейнер, тож жодне правило самого стенда цього не вирішує - тільки справжній в'юпорт, а він є лише в рамки.
.pdp-tabs - sticky, z-index 25, горизонтальне прокручування зі схованою смугою (scrollbar-width:none плюс ::-webkit-scrollbar). Заміряно 358x55 при 390 і 1032x59 при 1280, усередині 13 елементів.pdp-tabs::before - fixed на всю ширину вікна, top: var(--shelf-top, 0px), height: var(--shelf-h, 0px), z-index:-1, opacity:0. Обидві змінні пише JavaScript: у знятій розмітці видно --shelf-top:112px і --shelf-h:55px.pdp-tabs a.on - --text-body і --fw-black, під словом ::after на 2.5px у --bg-action, підтягнутий по 12px з боків - рівно на падінг посилання.tprice - inline-grid на дві колонки: стара ціна й чип знижки в перший ряд, нова на весь другий. :not(:has(.told)) піднімає нову в перший ряд, коли старої немає.ptabs - зовсім інша фігура: flex із переносом і проміжком 8, над сіткою товарів на головній. Від .pdp-tabs її відрізняє одна літера в імені.pdp - одна колонка до 859, далі права колонка 420px у структурі, 540px у кольорі й 580px від 1180. Три числа на дві межіtop оголошено тричі, і не діє жодного разу
У файлі три різні top для полиці: 103px у колірному блоці, 87px у структурному від 860 і 79px у колірному від 860. Вирішувач по кожному з трьох каже одне: beaten by INLINE. uivPdpTabs() у design/_nav.js щоразу пише tabs.style.top з живого нижнього краю хедера, а інлайн б'є будь-яке правило таблиці. У знятій розмітці це 112px при 1280.Мало того, 87px мертвий і без JavaScript: у тій самій умові
@media (min-width: 860px) нижче у файлі стоїть 79px, і він виграє. Тобто запасних значень насправді два, а не три, і обидва розходяться з тим, що робить продукт.І саме число варто дочитати до кінця. 112 при 1280 - це висота хедера. 113 при 390 - це 40px верхньої смуги стенда (
--shell-top у design/_stand.css нижче 1076) плюс 73 хедера. Поза стендом там було б 73. Тобто запасне число не просто розходиться з продуктом - воно розходиться з числом, у якому сидить стенд..ptabs - це не ця смуга. Спільне коріння в імені, і на цьому подібність кінчається: .pdp-tabs липне, скролиться вбік і від 960 вирощує ціну й кнопку покупки, а .ptabs - три оголошення, flex із gap: var(--space-8) і flex-wrap: wrap, і стоїть на чотирьох головних, де тримає чіпи .ptab над полицею товарів. Спільного коду нуль. Те, що вони в одному файлі, - питання етапу 09, а не факт про компонент.
design/index.html. Самі чіпи малює chip.css; .ptabs - це рядок під ними і перенос, коли вони не влазять.pdp - взагалі не смуга, а розкладка сторінки товару: grid в одну колонку, від 960 - minmax(0, 1fr) плюс рейка 420, далі 540 і 580. І живе вона в цьому файлі не випадково: смуга від 960 показує ціну й кнопку саме тому, що на цій ширині рейка покупки від'їхала вбік і перестала бути перед очима. Це один механізм, записаний двома класами, тож у рамці вище вони тепер стоять разом - смуга, а під нею розкладка з рейкою праворуч, точно в тому порядку, в якому вони сусідять на design/product.html.
Першу спробу цієї рамки гейт відхилив, і причина була вигадана структура
.pdp-tabs вклали всередину .pdp - здавалось природним, а в продукті вони сусіди. Ціна вигадки заміряна одразу: accept дав over=185 на 390, бо до 960 .pdp - це голий 1fr, тобто підлога за min-content, а смуга всередині неї несе overflow-x: auto й нерозривні вкладки, і колонка розсунулась на їхню повну ширину. Свій overflow смуга тримає лише доти, доки її не поклали в колонку, яка про нього не знає..pdp можна тільки в рамці: minmax і межа 960 читають в'юпорт, а не колонку стенда| Стан | Що робить | Чому так |
|---|---|---|
| спокій | фон знято, нижня рамка прозора, посилання --text-secondary | поки полиця в потоці сторінки, вона просто рядок посилань і нічого не перекриває |
наведення :hover | посилання йде в --text-body; кнопка .tbuy бере opacity:.93 | єдиний псевдоклас файлу |
активний розділ .on | --text-body, --fw-black і помаранчева риска 2.5px під словом | фон не змінюється: полиця тонка, і заливка на ній читалась би як друга панель |
приклеєно .stuck | фон-псевдоелемент виходить в opacity:1 з тінню --elevation-2; від 860 з'являються ціна й кнопка. body.pdp-stuck знімає тінь із хедера | дві приклеєні смуги одна під одною дали б подвійну лінію, тож нижня бере тінь, а верхня її віддає. Класи ставить uivPdpTabs() |
| до 859 | ціна й кнопка не показуються ніколи | на телефоні їх несе окрема нижня смуга buy-bar.css, і дублювати дію в двох приклеєних смугах не можна |
У файлі 2 медіа-умови, і кожна з них - межа, якої стандартні ширини перепису (360 / 390 / 720 / 1280) не бачать зсередини смуги. Заміряти їх треба власними ширинами, по одній з кожного боку.
@media (min-width: 860px)@media (min-width:860px)
Сторінка звіряє себе з файлом: 5 власних класів і 3 стани.
.stuck і .pdp-stuck стоять у станах, а не в класах: обидва дописує скрол - tabs.classList.toggle('stuck', stuck) на самій смузі й document.body.classList.toggle('pdp-stuck', stuck) на <body> сторінки товару, щоб решта макета знала, що смуга прилипла. Другий узагалі не належить компонентові: намалювати його тут означало б надіти клас товарної сторінки на стенд.
ПОВЕДІНКА НА ШИРИНІ - етап 10, крок 4
Від якого порогу:--bp-shell-wide. Що саме міняється: сторінка товару стає двоколонковою. Було ще й 1180, поза реєстром, і воно робило рівно одне - розширювало праву колонку з 540 до 580. 40px це РОЗМІР, тож він тепер пандус між тими самими двома значеннями. Зміряно на product: 248 + 540 на 860 і 312 + 580 на 1180, до і після. Ліва колонка й далі читає minmax(0,1fr), тобто бере те, що лишилось.Робота: ВІДПОВІДЬ. Рухається: прозорість полиці вкладок на скролі. Тривалість --dur-fast (150ms), крива --ease-standard. Значення читаються через var(): підміна токена в браузері веде за собою кожне з них. При prefers-reduced-motion рух зникає, а стан лишається.
Рух живе на ::before, а не на самому елементі - перекличка спершу назвала компонент нерухомим саме тому, що читала господаря, а не псевдоелемент.
Прочитані з pdp-tabs.css: 9 семантичних ролей і 18 примітивів.
| Семантичні ролі (9) | Примітиви (18) |
|---|---|
--bg-action --bg-inverse --bg-page --elevation-2 --line-hair --text-body --text-onaction --text-oninverse --text-secondary | --dur-fast --ease-standard --fs-12 --fs-14 --fs-16 --fs-20 --fw-black --fw-bold --fw-semibold --lh-flat --radius-4 --radius-8 --space-12 --space-16 --space-2 --space-24 --space-40 --space-8 |
По всіх 21 селекторі: 30 оголошень збігаються з елементами й ніде не виграють, ще 5 не збіглися ні з чим. Тридцять розкладаються на три купки. Перша - три top, розібрані вище: їх б'є інлайн. Друга, найбільша - 17 оголошень .pdp-tabs .tbuy зі структурного блоку, які б'є той самий селектор у колірному блоці нижче: це навмисний розділ етапу 08.
Третя купка - права колонка, і вона про незаміряну смугу
.pdp{ grid-template-columns } мертве двічі: і 420px зі структури, і 540px із кольору. 420 не виграє ніде взагалі - його б'є 540 у тій самій медіа-умові в цьому ж файлі. А 540 не виграв на жодній заміряній ширині, бо єдина смуга, де він міг би виграти, це 860-1179, і в неї не заходить жодна ширина перепису: 720 нижче, 1280 вище. Редакція правої колонки на 540px не малювалась ніколи ні на чому.П'ять незбіглих - це стани:
.pdp-tabs.stuck .tprice, .pdp-tabs.stuck .tbuy, body.pdp-stuck .wfh.uiv-scrolled (їх ставить прокрутка) і .tprice:not(:has(.told)) - на обох заміряних екранах стара ціна є завжди, тож ціна без знижки на полиці не малювалась.Чого бракує
topтричі й жодного разу. Рішення про значення, вголос: або зняти запасні числа й лишити рахунок за JavaScript, або вирахувати їх з висоти хедера - пам'ятаючи, що заміряні 112 і 113 містять смугу стенда, а продуктове число це 73- Смуга 860-1179 незаміряна. Права колонка 540px не намалювалась на жодній ширині перепису; поки її не заміряють, це намір, а не значення
- Три фігури в одному файлі.
.ptabs- це чипи головної,.pdp- сітка всієї сторінки товару. Ні те, ні те не вкладки - Корінь має двох власників.
.pdp-tabsописує ще йprice.css(.pdp-tabs:has(.told) .tnew), хоч усередині кореня неоднозначних імен немає - Полиця є на 2 з 40 кольорових екранів. На
product-oos,product-loadingіproduct-errorїї немає, і чи має вона там бути - ніде не сказано
Не домальовано наперед і не замовчано: етап 09 стартує з цього списку, зведеного в design/kit/docs/architecture.md.